HOWTO · Seaborn

如何建立 Seaborn 折線圖

本教學示範如何使用 Seaborn 模組在 Python 中建立折線圖。學習如何使用可自訂的折線圖、信賴區間和多條線進行比較分析,從而有效地視覺化資料。無論是初學者還是希望提高資料視覺化技能的經驗豐富的使用者,都非常適合。

本頁內容

Seaborn 折線圖將 x 變數和 y 變數的值對應到由一條線連接的點。它常用於時間序列,但 x 可以是任何有序或連續變數。seaborn.lineplot() 函數還可以彙總重複的觀測,並為不同類別繪製單獨的線,因此有助於探索測量值如何變化並比較不同組別。

Seaborn 入門

Seaborn 是一個建立在 Matplotlib 之上的統計繪圖庫。下面的範例使用 pandas DataFrame,這是一種將命名欄放在一起的便捷方式。如果你的 Python 環境中還沒有 Seaborn 及其相依性,請先安裝它們;然後匯入 Seaborn 和 Matplotlib。繪圖範例中不需要單獨的安裝命令。

本教學中的範例已使用 Python 3.12 上的 Seaborn 0.13.2、Matplotlib 3.11.2 和 pandas 3.1.0 執行並驗證,下面的每個圖都是這些範例實際產生的輸出。

建立基本折線圖

將 DataFrame 傳遞給 data,並為 x 和 y 指定欄名。下面的範例使用固定值,因此繪製的點是可重現的。呼叫 plt.show() 會在互動式環境中開啟圖形;在筆記本中,圖形通常顯示為儲存格的結果。

執行此範例:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "day": [1, 2, 3, 4, 5],
    "visitors": [12, 15, 13, 18, 21],
})

sns.lineplot(data=data, x="day", y="visitors")
plt.xlabel("Day")
plt.ylabel("Visitors")
plt.title("Visitors by day")
plt.tight_layout()
plt.show()

第 1 天到第 5 天訪客人數的 Seaborn 折線圖,從 12 上升到 21,第 3 天回落到 13。

橫軸使用 day,縱軸使用 visitors。將這些名稱和值替換為你自己表格中的欄。如果多列共享同一個 x 值,Seaborn 可能會彙總該位置的 y 觀測值並顯示不確定性帶;接下來的幾個部分將解釋如何解讀這些特徵。

自訂折線圖

外觀設定可幫助讀者區分一個系列或追蹤其值。例如,color 設定線條顏色,marker 在每個觀測處放置一個符號,linestyle 更改線條的描邊樣式。這些是視覺上的選擇;它們不會建立分組,也不會改變哪些列屬於資料。請選擇在圖形將被閱讀的尺寸下仍易於區分的顏色和標記。

在包含匯入和 data 定義的腳本中使用與上面相同的確定性表格。這個完整變體用虛線強調各點:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "day": [1, 2, 3, 4, 5],
    "visitors": [12, 15, 13, 18, 21],
})

sns.lineplot(data=data, x="day", y="visitors", color="darkorange", marker="o", linestyle="--")
plt.xlabel("Day")
plt.ylabel("Visitors")
plt.title("Visitors by day")
plt.tight_layout()
plt.show()

同一張訪客折線圖改用深橙色虛線,並在每個觀測處加上圓形標記。

如需不同的外觀,可更改這些參數,或使用 Matplotlib 方法設定標籤和標題。保持 x 和 y 的對應明確,以便後來的讀者能知道每個點代表什麼。

新增信賴區間

線條周圍的不確定性帶彙總了估計周圍的變異或不確定性。其含義取決於資料和估計量:當多個觀測對某個 x 位置有貢獻時,中心線可能會對它們進行彙總,而帶則傳達了該彙總周圍的不確定性。它不僅僅是標準差的另一個名稱。標準差描述觀測之間的離散程度;信賴區間描述的是一個估計量的不確定性。

下面的範例為每一天提供三個觀測值。程式碼首先印出每個組的平均值,這樣你就可以將繪製的線與簡單的數字進行核對:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "day": [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
    "visitors": [10, 12, 14, 14, 16, 18, 13, 15, 17, 19, 21, 23],
})

print(data.groupby("day")["visitors"].mean())

sns.lineplot(data=data, x="day", y="visitors", marker="o")
plt.xlabel("Day")
plt.ylabel("Visitors")
plt.title("Mean visitors by day with 95% confidence band")
plt.tight_layout()
plt.show()

輸出:

day
1    12.0
2    16.0
3    15.0
4    21.0
Name: visitors, dtype: float64

每天的平均訪客人數以一條穿過組平均值 12、16、15 和 21 的線表示,周圍有陰影的 95% 信賴帶。

中心線穿過印出的平均值(12、16、15 和 21):當存在重複觀測時,lineplot() 預設使用平均值彙總每個 x 組。陰影帶是該平均值的 95% 信賴區間,透過拔靴法(bootstrapping)計算。某個組的分布越分散,帶就越寬;它並不能說明單個觀測值落在何處。

在解讀一條帶之前,請檢查每個 x 值是否有重複的觀測,以及這些觀測代表什麼。例如,來自同一受試者的重複測量並不一定代表獨立樣本。當每個 x 值只有一個觀測時,就不存在可據以同樣方式推斷變異的位置內重複。合適的解讀還取決於所使用的 Seaborn 版本和繪圖選項。這裡的範例使用 errorbar 參數,該參數自 Seaborn 0.12 起可用;在 Seaborn 0.13.2 中,預設值為 errorbar=("ci", 95),而 errorbar="sd" 則會改為繪製一條在平均值兩側各跨一個標準差的帶。當你需要控制估計量或區間方法時,請查閱已安裝版本的說明文件。如果該帶對你的資料沒有意義,請相應設定圖形,或將其省略,並說明該線是如何計算的。

當帶沒有意義時,可使用 errorbar=None 將其關閉。彙總仍會發生——線仍會連接各組的平均值——但不會繪製任何帶:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "day": [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
    "visitors": [10, 12, 14, 14, 16, 18, 13, 15, 17, 19, 21, 23],
})

sns.lineplot(data=data, x="day", y="visitors", marker="o", errorbar=None)
plt.xlabel("Day")
plt.ylabel("Visitors")
plt.title("Mean visitors by day without uncertainty band")
plt.tight_layout()
plt.show()

將 errorbar 設為 None 後繪製的每天平均訪客人數,該線連接相同的組平均值,但沒有不確定性帶。

這兩個圖繪製的是相同的平均值;區別僅在於帶。請根據不確定性彙總是否有助於讀者來在兩者之間選擇,而不是看哪個圖看起來更乾淨。

繪製多條線

對於基於類別的比較,請包含一個類別欄並將其對應到 hue。Seaborn 會為每個類別繪製一條單獨的彩色線並加入圖例。當線條樣式可提供額外的視覺區分時,將 style 對應到相同或另一個類別欄。僅當各列共享相同的 x 和 y 度量時才使用類別;保持各組別之間的標籤和單位一致。

以下是一個使用固定觀測值的完整分組資料範例:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.DataFrame({
    "week": [1, 2, 3, 1, 2, 3],
    "orders": [8, 11, 14, 6, 9, 10],
    "store": ["North", "North", "North", "South", "South", "South"],
})

sns.lineplot(data=data, x="week", y="orders", hue="store", style="store", markers=True, dashes=True)
plt.xlabel("Week")
plt.ylabel("Orders")
plt.title("Orders by store")
plt.tight_layout()
plt.show()

一張圖中的兩條折線:North 商店的每週訂單從 8 上升到 14,位於從 6 上升到 10 的 South 商店之上,兩者以顏色、標記和線型區分。

當資料改為每個系列有單獨的數值欄時,將其重塑為一張長表,其中包含一個值欄和一個系列名稱欄,然後將系列名稱對應到 hue。或者,將每個 y 欄繪製在共享的 Matplotlib 座標軸上,並在加入圖例前為每條線指定一個標籤。無論哪種方法,圖例都應標識每條線並與其資料相符。不要使用類別樣式來掩蓋不同的單位或尺度;當直接比較會產生誤導時,請考慮使用單獨的座標軸或單獨的圖形。

修復拼寫錯誤的欄名

傳遞給 x 和 y 的名稱必須與 data 中的欄名完全一致。如果名稱拼寫錯誤,lineplot() 會在繪製任何內容之前引發錯誤。此呼叫要求一個名為 visitor 的欄,但 DataFrame 中只有 visitors:

import pandas as pd
import seaborn as sns

data = pd.DataFrame({
    "day": [1, 2, 3, 4, 5],
    "visitors": [12, 15, 13, 18, 21],
})

sns.lineplot(data=data, x="day", y="visitor")

輸出:

ValueError: Could not interpret value `visitor` for `y`. An entry with this name does not appear in `data`.

該訊息指明了參數(y)、失敗的值(visitor)和原因,因此這個錯誤很容易修復:將名稱與實際欄進行比較——印出 data.columns 即可列出它們——然後更正拼寫。對於 x 或拼寫錯誤的 hue 或 style 欄,也會出現同樣的錯誤。

結論

使用 seaborn.lineplot() 沿 x 值連接 y 的測量值,然後選擇外觀設定或類別對應,使圖形易於閱讀。在解讀不確定性帶之前,請檢查重複觀測是如何彙總的,並為每個被比較的系列明確加上標籤。

常見問題

  1. Seaborn 為 Matplotlib 增加了什麼? Seaborn 提供了用於統計圖形的高階介面,並與 Matplotlib 協同工作,以顯示圖形和進一步格式化。
  2. 我可以傳遞 pandas DataFrame 嗎? 可以。將 data 設定為 DataFrame 並將欄名傳遞給 x 和 y。
  3. 如何更改線條外觀? 使用 color、marker 和 linestyle 等選項;這些選項更改外觀,而 hue 將類別對應到單獨的線。
  4. 陰影帶是什麼意思? 它表示與所繪製估計相關的不確定性彙總。其解讀取決於重複觀測、估計量和所選的區間方法;它並不自動就是標準差。
  5. 如何比較多條線? 將類別欄對應到 hue,或者在共享座標軸上繪製單獨標記的系列。確保圖例準確命名每條線。
  6. 如何移除陰影帶? 傳遞 errorbar=None。該線仍會使用平均值彙總重複觀測;只是省略了不確定性帶。