# 【Python 筆記】Matplotlib Pyplot 套件應用(上)
[TOC]
感謝您點進本篇文章,我是 LukeTseng,該系列主要以筆記加上口語白話形式學習 Python,若文章某處有誤敬請告知,非常感謝。
## Matplotlib 是啥?
Matplotlib 是 Python 中最熱門的 2D 繪圖函式庫,是由 John D. Hunter 這個人開發的。然後這個人他原本其實是一個美國的生物神經學家,後來為了可視化癲癇患者的腦電圖數據,因而製作了這個 Matplotlib 出來。
Matplotlib 這個名稱其實是 MATLAB + Plot + Library 的簡稱,因為它使用類似 MATLAB 的語法和樣式來繪圖。
這個套件可以繪製各種圖表,有折線圖、直方圖、圓餅圖、散點圖、長條圖等等,還能跟其他 Python 資料處理函式庫如 NumPy、Pandas 有很高的兼容性,可以互相搭配使用。
總之這就是一個數據分析可視化的繪圖函式庫,正因為他熱門,正是因為它非常強大,所以才要學這東西。
## 安裝 Matplotlib
使用以下指令安裝,如果已在 colab 或是 Anaconda 環境下就不用再安裝了,因為就有內建這東西。(本篇筆記使用 colab 進行學習)
```bash
pip install matplotlib
```
## 引入模組
使用 Matplotlib 時,最常用的是它的 pyplot 模組,通常會將其命名為 plt。而本篇筆記主題是 pyplot,後續也只會學習 pyplot。
```python
import matplotlib.pyplot as plt
```
## plot() 基本繪圖
先介紹以下兩個函式:
- `plot()`:用於繪製線圖和散佈圖。
- `show()`:顯示圖表。
`plot()` 語法:
```
plt.plot([x座標資料,] y座標資料 [, 參數1, 參數2, …])
```
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y)
plt.show()
```
Output:

接下來介紹 fmt 格式字串,這是在 `plot()` 中的其中一個參數。具體形式為 `fmt = '[color][marker][line]'`。
如以下片段程式碼:
```python=
# 藍色圓點實線
plt.plot(x, y, 'bo-')
# 綠色三角形虛線
plt.plot(x, y, 'g^--')
# 紅色加號點線
plt.plot(x, y, 'r+:')
```
這邊設定成藍色圓點實線用在上個範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, 'bo-')
plt.show()
```
Output:

綠色三角形虛線(虛線是兩個 dash `--`):

紅色加號點線(點線的符號是 `:`):

也可以設定成紅色加號點畫線(點畫線是 `-.`):

### linewidth or lw
`linewidth` 或 `lw`,用於設定線條寬度,預設的話是 1.0,要設定在 `plot()` 的話可寫 `plot(x, y, linewidth=5.0)`。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, 'bo-', lw=5.0)
plt.show()
```
Output:

### color
`color` 參數可調整顏色,不一定要透過 fmt 的方式更改。
使用方法如 `plot(x, y, color='b')`,b 是 blue。
顏色表如下:
| 顏色 | 值 |
| -------- | -------- |
| 藍色 | b, blue |
| 紅色 | r, red |
| 綠色 | g, green |
| 黃色 | y, yellow |
| 青色 | c, cyan |
| 洋紅 | m, magenta |
| 黑色 | k, black |
| 白色 | w, white |
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 5.0, color = 'k')
plt.show()
```
Output:

### linestyle or ls
`linestyle` 或是 `ls` 參數在先前介紹 fmt 有稍微講過一些,使用方式跟前面一樣,如 `plot(x, y, linestyle = "-")` 表示實線。
以下是 linestyle 的表格:
| linestyle | description |
| -------- | -------- |
| `"-"` | 實線 |
| `"--"` | 虛線 |
| `"-."` | 虛點線 |
| `":"` | 點線 |
### marker
marker 使用方式也跟前面的都差不多,如:`plot(x, y, marker = '.')` 表示上面的資料點以「點」的方式呈現。
符號表:
| Symbols | Description |
| -------- | -------- |
| `"."` | 點 |
| `"o"` | 圓 |
| `"*"` | 星 |
| `"v"`、`"^"` | 正 / 倒三角形 |
| `"<"`、`">"` | 左 / 右三角形 |
| `"s"` | 矩形 |
| `"p"` | 五角形 |
| `"h"`、`"H"` | 六邊形 |
| `"d"`、`"D"` | 鑽形小 / 大 |
| `"+"` | 十字 |
| `"x"` | 交叉 |
| `"_"` | 橫線 |
| `"1"`、`"2"`、`"3"`、`"4"`、`"5"` | 下左右人字形 |
註:由於 markdown 語法,單獨講直線的表示方法:`"|"`
以 `"*"` 為範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*")
plt.show()
```
Output:

### markersize or ms
`markersize` or `ms` 參數代表 marker 的 size 大小,使用方式如:`plot(x, y, ms=12)`。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*", markersize=12)
plt.show()
```
Output:

### label
label 為設定圖例名稱的參數,這個參數要搭配 `plt.legend()` 才有效。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*", markersize=12, label="DataLINE")
plt.legend()
plt.show()
```
Output:

可看到左上角多了一個圖例。
## 設定圖表標題
使用以下三個函式:
- `plt.title()`:設定圖表標題。
- `plt.xlabel()`:設定 X 軸標題。
- `plt.ylabel()`:設定 Y 軸標題。
`plt.title()` 語法:
```python
plt.title(label, fontsize=None, fontdict=None, loc=None, pad=None, **kwargs)
```
* `label`:字串,圖表的標題內容。
* `fontsize`:字體大小。
* `fontdict`:字典,設定字體屬性(如字型大小、顏色、粗細等)。
* `loc`:標題位置 (`'center'`、`'left'`、`'right'`),預設居中。
* `pad`:標題與圖表頂部之間的間距。
* `**kwargs`:額外參數,設定標題的其他樣式(可參照 Text 物件屬性)。
而之後的 `plt.xlabel()`、`plt.ylabel()` 語法都跟上面這個相同。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*", markersize=12, label="DataLINE")
plt.title("Chart")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend()
plt.show()
```
Output:

可看到多了 `Chart`、`X`、`Y` 這些標題。
## 設定 x、y 軸的資料範圍
透過以下兩個函數可以手動設定 x、y 座標軸上的資料範圍:
- `plt.xlim()`:設定 x 軸的範圍。
- `plt.ylim()`:設定 y 軸的範圍。
`plt.xlim()` 語法:
- 格式 1:`plt.xlim(xmin, xmax)`。
- 格式 2:`plt.xlim(xmin=最小, xmax=最大)`。
取得目前範圍:`x_min, x_max = plt.xlim()`。
`plt.ylim()` 與 `plt.xlim()` 相同。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*", markersize=12, label="DataLINE")
plt.title("Chart")
plt.xlabel("X")
plt.ylabel("Y")
plt.xlim(0, 30)
plt.ylim(0, 30)
plt.legend()
plt.show()
```
Output:

可以看到圖被放的很小,因為 x、y 軸的資料範圍被放大了。
## 為圖表設定格線
使用函式 `plt.grid(boolean_value)`,`boolean_value` 可為 `True` 或 `False`。
也可為格線進一步設定 `linestyle`、`linewidth`、`alpha` 等參數,其中 `alpha` 是透明度。
範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
plt.plot(x, y, lw = 0.5, color = 'k', marker = "*", markersize=12, label="DataLINE")
plt.title("Chart")
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True, linestyle="-", linewidth=2.0, alpha=0.5)
plt.legend()
plt.show()
```
Output:

其中 `alpha` 的參數值為 `0` ~ `1.0`。
## 同時繪製兩條或多條以上的線
只要再多寫幾個 `plt.plot()` 即可。
以下範例為兩條實線的範例:
```python=
import matplotlib.pyplot as plt
import numpy as np
x1 = np.array([1, 2, 3, 4, 5])
y1 = np.array([1, 2, 3, 4, 5])
plt.plot(x1, y1, lw = 0.5, color = 'k', marker = "*", markersize=5, label="D1")
x2 = np.array([1, 3, 5, 7, 9])
y2 = np.array([2, 4, 6, 8, 10])
plt.plot(x2, y2, lw = 0.5, color = 'r', marker = "o", markersize=5, label="D2")
plt.title("Chart")
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True, linestyle="-", linewidth=2.0, alpha=0.5)
plt.legend()
plt.show()
```
Output:

而其實兩組資料可以寫在同一個函式當中,只是其函式的參數順序要注意:
```python
plt.plot(x1, y1, style1..., x2, y2, style2...)
```
以下範例將上一個範例寫在同一個函式當中:
```python=
import matplotlib.pyplot as plt
import numpy as np
x1 = np.array([1, 2, 3, 4, 5])
y1 = np.array([1, 2, 3, 4, 5])
x2 = np.array([1, 3, 5, 7, 9])
y2 = np.array([2, 4, 6, 8, 10])
plt.plot(x1, y1, 'k*-', x2, y2, 'ro-')
plt.title("Chart")
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True, linestyle="-", linewidth=2.0, alpha=0.5)
plt.show()
```
Output:

這個寫法的缺點是沒有辦法單獨為某一條線段新增圖例。
## 自訂 x、y 軸刻度
`plt.xticks()` 和 `plt.yticks()` 用來自訂軸刻度,而清楚一點的說法是說去設定或取得座標軸上的刻度位置與標題。像是可以讓 x 軸顯示月份、y 軸標記實際名稱,而非數字。
而兩者詳細語法如下(以 `plt.xticks()` 舉例):
```python
plt.xticks(ticks=None, labels=None, **kwargs)
```
* ticks:一組刻度位置(數字列表或 numpy 陣列),指定在哪些值上顯示刻度。
* labels(可選):每個 ticks 位置的顯示文字(如:月份、人名等),型別為字串串列。
* kwargs:額外文字屬性(如字型大小、顏色、旋轉角度等)。
若不回傳參數,則會回傳目前刻度位置以及 Text 物件列表:
```python
locs, labels = plt.xticks()
```
範例:
```python=
import matplotlib.pyplot as plt
x = range(1, 13)
y = [i for i in x]
plt.plot(x, y)
plt.xticks([1, 3, 6, 9, 12]) # x軸只顯示這些位置刻度
plt.yticks([2, 4, 6, 8, 10, 12]) # y軸刻度同理
plt.show()
```
Output:

自訂刻度範例:
```python=
import matplotlib.pyplot as plt
import calendar
x = range(1, 13)
y = [i for i in x]
plt.plot(x, y)
plt.xticks(x, calendar.month_name[1:13], color='blue', rotation=45) # x軸每個月名稱
plt.yticks(y, ['A','B','C','D','E','F','G','H','I','J','K','L'], color='red')
plt.show()
```

隱藏刻度範例:
```python=
import matplotlib.pyplot as plt
import calendar
x = range(1, 13)
y = [i for i in x]
plt.plot(x, y)
plt.xticks([]) # 隱藏 x 軸所有刻度
plt.yticks([]) # 隱藏 y 軸所有刻度
plt.show()
```
Output:

### 全面自訂座標軸刻度線
`plt.tick_params()` 函式可同時做到 `plt.xticks()`、`plt.yticks()` 這兩個可做到的事情,另外參數也蠻多的,請見以下語法說明:
```python=
plt.tick_params(axis='both', which='major', direction='out', length=6,
width=1, color='black', labelsize=None, labelcolor=None,
colors=None, pad=None, labelrotation=None,...)
```
* `axis`:控制哪個軸 (`'x'`、`'y'`、`'both'`)。
* `which`:主刻度線 (`'major'`)、副刻度線 (`'minor'`) 或同時 (`'both'`)。
* `direction`:刻度線方向 (`'in'` 內側、`'out'` 外側、`'inout' `雙向)。
* `length`:刻度線長度(點,pt,預設 6)。
* `width`:刻度線寬度(點,預設 1)。
* `color`:僅刻度線顏色。
* `colors`:刻度線和刻度標籤文字顏色都一起改。
* `labelsize`:刻度標籤的字型大小。
* `labelcolor`:刻度標籤文字顏色。
* `pad`:刻度標籤與刻度線之間距離(點)。
* `labelrotation`:旋轉標籤,例如 45。
* `bottom/top/left/right`:是否顯示各側刻度線(布林值)。
* `labelbottom/labeltop/labelleft/labelright`:是否顯示各邊刻度標籤(布林值)。
不過這樣看有些複雜,所以來做一些範例。
統一設計 x 軸主刻度:
```python=
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
plt.plot(x)
plt.tick_params(axis='x', which='major', length=10, width=3, color='blue', labelsize=14, labelrotation=30)
plt.show()
```
Output:

可以看到刻度線顏色換成藍色,並且所有的標籤(0、1、2、3、4)都旋轉了 30 度。
同時設計 x, y 軸標籤顏色:
```python=
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
plt.plot(x)
plt.tick_params(axis='both', length=8, colors='red', labelsize=12)
plt.show()
```
Output:

刻度線方向向內:
```python=
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
plt.plot(x)
plt.tick_params(direction='in')
plt.show()
```
Output:

隱藏底部標籤跟刻度:
```python=
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
plt.plot(x)
plt.tick_params(bottom=False, labelbottom=False)
plt.show()
```
Output:

## 總結
### 基礎繪圖函式
| 函式 | 功能 | 範例或說明 |
| ------------ | ------------------------------------ | ------------------ |
| `plt.plot()` | 繪製線圖或散點圖 | `plt.plot(x, y)` |
| `plt.show()` | 顯示圖表 | `plt.show()` |
| `fmt` 格式字串 | `'[color][marker][line]'` 控制顏色、標記、線型 | 例:`'bo-'` → 藍色圓點實線 |
### 線條與點樣式控制
| 參數 | 功能 | 範例 |
| ------------------- | ------------------------------------ | ---------------------------- |
| `linewidth` / `lw` | 線條寬度 | `plt.plot(x, y, lw=3)` |
| `color` | 線條顏色(b, r, g, y, c, m, k, w) | `plt.plot(x, y, color='r')` |
| `linestyle` / `ls` | 線型(`"-"`, `"--"`, `"-. "`, `":"`) | `plt.plot(x, y, ls='--')` |
| `marker` | 標記符號(如 `"o"`, `"*"`, `"x"`, `"^"` 等) | `plt.plot(x, y, marker='*')` |
| `markersize` / `ms` | 標記大小 | `plt.plot(x, y, ms=10)` |
### 圖例與標題
| 函式 | 功能 | 範例 |
| -------------- | ----------------- | -------------------- |
| `plt.legend()` | 顯示圖例(需搭配 `label`) | `plt.legend()` |
| `plt.title()` | 設定圖表標題 | `plt.title("Chart")` |
| `plt.xlabel()` | 設定 X 軸標題 | `plt.xlabel("X")` |
| `plt.ylabel()` | 設定 Y 軸標題 | `plt.ylabel("Y")` |
### 座標軸控制
| 函式 | 功能 | 範例 |
| ------------ | -------- | ------------------------------------------------------- |
| `plt.xlim()` | 設定 X 軸範圍 | `plt.xlim(0, 30)` |
| `plt.ylim()` | 設定 Y 軸範圍 | `plt.ylim(0, 30)` |
| `plt.grid()` | 顯示格線 | `plt.grid(True, linestyle='-', linewidth=2, alpha=0.5)` |
### 繪製多條線
方式一:多次呼叫 `plt.plot()`。
```python=
plt.plot(x1, y1, 'k*-', label='D1')
plt.plot(x2, y2, 'ro-', label='D2')
```
方式二:在同一函式中一次繪製多條線。
```python
plt.plot(x1, y1, 'k*-', x2, y2, 'ro-')
```
### 座標軸刻度設定
| 函式 | 功能 | 範例 |
| -------------- | -------------------------------- | ------------------------------------------ |
| `plt.xticks()` | 設定 X 軸刻度位置與文字 | `plt.xticks([1,3,6], ['Jan','Mar','Jun'])` |
| `plt.yticks()` | 設定 Y 軸刻度 | `plt.yticks([0,2,4,6])` |
| 隱藏刻度 | `plt.xticks([]), plt.yticks([])` | |
### 全面刻度設定
`plt.tick_params()`:
| 主要參數 | 功能 |
| ----------------------- | --------------------------------- |
| `axis` | 控制軸(`'x'`, `'y'`, `'both'`) |
| `which` | 主或副刻度(`'major'`, `'minor'`) |
| `direction` | 刻度線方向(`'in'`, `'out'`, `'inout'`) |
| `length`, `width` | 刻度線長寬 |
| `color`, `colors` | 刻度線或標籤顏色 |
| `labelsize` | 標籤字體大小 |
| `labelrotation` | 標籤旋轉角度 |
| `bottom/top/left/right` | 控制是否顯示該邊刻度線 |
| `labelbottom/...` | 控制是否顯示標籤 |
範例:`plt.tick_params(axis='x', length=10, width=3, color='blue', labelrotation=30)`
## 參考資料
[Matplotlib — Visualization with Python](https://matplotlib.org/)
[matplotlib 函式庫 - matplotlib 教學 ( Python ) | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/example/matplotlib.html)
[Matplotlib Tutorial - GeeksforGeeks](https://www.geeksforgeeks.org/python/matplotlib-tutorial/)