HOWTO · Matplotlib

在 Matplotlib 中新增子圖

本教程介紹如何使用 `Figure.add_subplot()` 向現有 Matplotlib 圖形新增並定位子圖,以及如何使用 `matplotlib.pyplot.subplots()` 建立包含子圖的新圖形。

本頁內容

若要在既有的 Matplotlib 圖形中新增子圖,請呼叫 Figure.add_subplot(),並傳入格線的列數、欄數和子圖從 1 開始計算的位置。回傳的 Axes 物件可用來繪圖及設定標籤。若要同時建立新圖形及其座標軸,請使用 matplotlib.pyplot.subplots()。

執行以下範例。不可變的程式碼區塊中,圖表標籤維持英文。

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(1, 1, 1)
ax.plot([1, 2, 3, 4], [2, 5, 3, 7], marker="o")
ax.set(title="Measurements", xlabel="Sample", ylabel="Value")
print(f"axes={len(fig.axes)}")
plt.show()
axes=1

圖形包含座標軸,而座標軸則包含繪製的線條及其標籤。如果執行指令碼的環境沒有圖形顯示裝置,可以將 plt.show() 換成 fig.savefig("plot.png"),改為儲存圖形。

使用 Figure.add_subplot() 在圖形中新增子圖

呼叫 fig.add_subplot(nrows, ncols, index) 會將圖形劃分為格線,並在 index 指定的位置放置一個子圖。列由上往下計算,欄由左往右計算;左上角儲存格的位置是 1。若格線有兩列兩欄,位置 1 和 2 在上列,位置 3 和 4 在下列。這裡的位置代表格線中的儲存格,而不是列數。

對於 1×1 格線,fig.add_subplot(1, 1, 1) 和它的緊湊寫法 fig.add_subplot(111) 都會選取相同的儲存格。三位數的緊湊寫法會以個位數編碼列數、欄數和位置,因此只有在這三個值都介於 1 到 9 之間時才能使用。如果任一值大於 9,請以三個獨立引數呼叫 fig.add_subplot(nrows, ncols, index)。當格線或位置不易一眼看懂時,三引數寫法也更清楚。

不規則版面可以讓不同座標軸使用不同的格線規格。在下方範例中,第一個座標軸橫跨兩欄格線的完整高度;另外兩個則分別占據右上和右下的儲存格。每次呼叫都會回傳該位置的 Axes,因此請保留回傳的物件,並在這些物件上呼叫繪圖方法。

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8, 5))
left = fig.add_subplot(2, 2, (1, 3))
top_right = fig.add_subplot(2, 2, 2)
bottom_right = fig.add_subplot(2, 2, 4)

left.plot([1, 2, 3], [2, 4, 3])
left.set_title("Full-height axes")
top_right.plot([1, 2, 3], [1, 3, 2])
top_right.set_title("Top right")
bottom_right.plot([1, 2, 3], [3, 2, 4])
bottom_right.set_title("Bottom right")

fig.tight_layout()
plt.show()

元組 (1, 3) 會選取第一欄中的一段格線儲存格。使用 tight_layout() 可減少標題與座標軸裝飾之間的重疊;視圖形尺寸和標籤而定,可能也需要調整圖形大小或間距。每個座標軸彼此獨立,因此可以分別設定標題、標籤、刻度和繪圖資料。

使用 matplotlib.pyplot.subplots() 建立含有子圖的圖形

使用 matplotlib.pyplot.subplots() 一次建立新的 Figure 和一組格線排列的 Axes。它會回傳一組成對的值:圖形,以及座標軸物件或座標軸陣列。子圖數量多於一個時,squeeze=True(預設值)會回傳維度符合格線配置的 NumPy 陣列。若配置為 2×1,可用 axes[0] 和 axes[1] 存取上方及下方的座標軸。只有一個子圖時,回傳的是單一 Axes,而不是陣列;若需要固定為二維的陣列,請設定 squeeze=False。

當格線配置已知,而且需要立即取得圖形與座標軸時,這個函式很實用。不同於 Figure.add_subplot(),它會建立新圖形,而不是在既有圖形中新增座標軸。請透過各自的座標軸繪製不同資料序列,並使用 tight_layout() 為標籤留出空間。

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
fig, axes = plt.subplots(2, 1, figsize=(6, 5))

axes[0].plot(x, [value ** 2 for value in x], marker="o")
axes[0].set(title="Squared values", xlabel="x", ylabel="x squared")

axes[1].plot(x, [4 * value + 1 for value in x], marker="s")
axes[1].set(title="Linear values", xlabel="x", ylabel="4x + 1")

fig.tight_layout()
plt.show()

結果是一個包含兩個垂直堆疊座標軸的圖形:上方顯示平方值,下方顯示線性值。需要設定整個圖形的標題、儲存完整結果或調整版面時,請保留 fig 中的圖形物件;子圖專屬的格式設定和繪圖則使用 axes 中的各個項目。