HOWTO · Matplotlib

Matplotlib 中的疊加圖

本文介紹如何在 Matplotlib 中疊加繪圖,並提供實用範例和清晰的解說。了解組合不同類型視覺化圖表(包括折線圖和長條圖)的最佳方法,提升資料呈現的敘事效果。探索如何建立能夠有效傳達洞見和對比關係的分層圖形。

本頁內容

在 Matplotlib 中疊加圖表時,將每組資料繪製在同一個 Axes 物件上,便能在同一座標系統中比較相關數值。若資料需要不同的尺度,或分開呈現更容易閱讀,請使用個別子圖;每個子圖都有自己的 Axes。

方法 1:基本折線圖疊加

在同一個座標軸上多次呼叫 plot()。以下範例會比較相同 x 位置上的正弦與餘弦值。每次呼叫都會新增一條線,並將標籤加入同一個圖例。範例圖表的標題、座標軸標籤與圖例項目均維持英文,例如 “Sine” 和 “Cosine”,並未顯示為繁體中文。

請在有 Matplotlib 顯示環境中執行此範例;它會開啟圖表,並將 line-overlay.png 儲存至目前目錄。在無頭環境中,仍可查看儲存的 PNG 檔案。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), label="Sine", color="blue")
ax.plot(x, np.cos(x), label="Cosine", color="red")
ax.set(title="Sine and cosine", xlabel="x", ylabel="Value")
ax.legend()
fig.savefig("line-overlay.png", dpi=150, bbox_inches="tight")
plt.show()
plt.close(fig)

Matplotlib 中的疊加圖

兩條線共用相同的 x 軸與 y 軸尺度,因此圖表便於比較各 x 位置的數值。如果資料序列的單位不同,或數值範圍差異很大,共用 y 軸可能造成誤解;此時可改用個別子圖,或使用標示清楚的次要座標軸。

方法 2:疊加長條圖與折線圖

若長條圖與折線圖代表相同類別,而且數值具有合理的可比性,就能在同一個座標軸上呈現。使用數值形式的類別位置,讓標記落在長條中央。適度設定長條透明度,有助於讓折線保持清晰可見。

執行此範例後會開啟圖表,並將 bar-line-overlay.png 儲存至目前目錄。

import matplotlib.pyplot as plt

categories = ["A", "B", "C", "D"]
positions = range(len(categories))
bar_values = [3, 7, 2, 5]
line_values = [4, 6, 3, 4]

fig, ax = plt.subplots()
ax.bar(positions, bar_values, width=0.65, alpha=0.55, label="Bar values")
ax.plot(positions, line_values, color="darkorange", marker="o", label="Line values")
ax.set_xticks(list(positions), categories)
ax.set(xlabel="Category", ylabel="Value", title="Bar and line overlay")
ax.legend()
fig.savefig("bar-line-overlay.png", dpi=150, bbox_inches="tight")
plt.show()
plt.close(fig)

疊加長條圖和折線圖

此範例使用單一 y 軸,因為兩組資料的尺度相近。如果其中一組資料代表不同的量或單位,請清楚說明,並使用個別座標軸或子圖,避免讓讀者誤以為兩者的高度可以直接比較。

控制哪個繪圖元素顯示在前方:zorder

Matplotlib 會依照 zorder 的順序繪製圖形元素:數值較大的元素會顯示在數值較小的元素前方。若要讓折線顯示在長條上方,請明確設定 zorder。執行此範例後會開啟圖表,並將 zorder-overlay.png 儲存至目前目錄。

import matplotlib.pyplot as plt

positions = [0, 1, 2]
fig, ax = plt.subplots()
ax.bar(positions, [3, 5, 4], alpha=0.6, zorder=1)
ax.plot(positions, [4, 3, 5], color="darkorange", marker="o", zorder=2)
fig.savefig("zorder-overlay.png", dpi=150, bbox_inches="tight")
plt.show()
plt.close(fig)

較高的 zorder 只會控制繪製順序,不會改變數值尺度或資料值。它適合用來讓標記或格線清楚可見,但無法解決需要不同尺度的資料彼此重疊問題。

方法 3:使用子圖整理多個圖表

plt.subplots() 會建立彼此獨立的座標軸。如下例所示,你可以在一個子圖中疊加相關資料序列,並在另一個子圖中呈現不同資料。這種方式能整理各自獨立的比較,不會暗示所有資料都共用同一個尺度。

執行此範例後會開啟圖表,並將 subplot-overlay.png 儲存至目前目錄:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
fig, axes = plt.subplots(2, 1, figsize=(8, 6))
axes[0].plot(x, np.sin(x), label="Sine")
axes[0].plot(x, np.cos(x), label="Cosine")
axes[0].set_ylabel("Value")
axes[0].legend()
tangent = np.tan(x)
tangent[np.abs(tangent) > 5] = np.nan
axes[1].plot(x, tangent, color="green", label="Tangent")
axes[1].set_ylim(-5, 5)
axes[1].set_xlabel("x")
axes[1].set_ylabel("Value")
axes[1].legend()
fig.tight_layout()
fig.savefig("subplot-overlay.png", dpi=150, bbox_inches="tight")
plt.show()
plt.close(fig)

第一個座標軸包含兩條疊加的折線;第二個座標軸則呈現落在圖示 y 軸範圍內的正切函數線段。繪圖前會遮罩絕對值大於 5 的數值,因此 Matplotlib 不會在正切函數的垂直漸近線處畫出跨越的線段。tight_layout() 會調整間距,降低標籤互相重疊的機會。資料集很多時,只有在子圖有助於區分比較時才增加子圖;比起少數聚焦的圖表,過度密集的疊圖可能更難解讀。

結論

在 Matplotlib 中,對同一個 Axes 呼叫繪圖方法即可疊加圖表。請使用圖例、清楚的標籤與相容的尺度;若繪製順序很重要,也可設定 zorder。若資料應分開呈現,請使用個別子圖,並控制疊加的資料序列數量,讓圖表容易閱讀。

常見問題

  1. 為什麼要在 Matplotlib 中疊加圖表?
    疊圖能在同一個畫面呈現相關資料集;當它們使用有意義且可比較的尺度時,更容易比較趨勢與數值。

  2. 可以組合不同類型的圖表嗎?
    可以。例如,當類別與數值適合清楚比較時,可在同一個座標軸上繪製長條圖與折線圖。

  3. 如何自訂疊加圖表?
    在繪圖呼叫中設定顏色、標記、線條樣式、透明度、標籤與 zorder。圖例和座標軸標籤應清楚指出各資料序列代表的內容。

  4. 可以疊加多少個圖表?
    沒有固定上限,但過多折線或標記會讓圖表顯得雜亂。當標籤或比較內容變得難以理解時,請將資料分到不同子圖。

  5. 如何將疊加圖儲存為圖片?
    關閉圖表前呼叫 fig.savefig("overlay.png", dpi=150, bbox_inches="tight")。這會將目前的圖表儲存為 PNG 檔;需要其他格式時,可改用支援的副檔名。