返回文章列表

Pandas 與 Matplotlib 資料視覺化深度解析

本文探討如何運用 Pandas 和 Matplotlib 進行資料視覺化,涵蓋區域圖、直方圖、KDE、散點圖等多種圖表型別,並搭配實務案例講解自定義顏色、標籤、網格線、子圖等技巧,同時也介紹了 Matplotlib 的進階用法,例如 GridSpec 和複合圖表繪製,以及如何使用散點圖和散點矩陣探索資料間的關

資料科學 Python

Pandas 和 Matplotlib 是 Python 資料科學領域中常用的兩個套件,它們能有效地協助我們進行資料視覺化。本文除了基本圖表型別如區域圖、條狀圖外,也探討直方圖和 KDE 的應用,並以實際案例說明如何調整引數、自定義樣式以及處理 DataFrame 中的多列資料。此外,更進一步介紹如何使用 Matplotlib 建立更複雜的視覺化,例如複合圖表和 GridSpec 的應用,讓讀者能更精細地控制圖表佈局。最後,本文也講解了散點圖和散點矩陣的應用,幫助讀者理解變數之間的關係和資料分佈。

使用 Pandas 和 Matplotlib 的視覺化技術

在現代資料分析中,視覺化是一項不可或缺的工具。Pandas 和 Matplotlib 提供了強大的功能,讓我們能夠輕鬆地建立各種圖表,從而更好地理解資料。以下將探討如何使用 Pandas 和 Matplotlib 進行視覺化,並涵蓋一些實務中的應用案例。

區域圖(Area Chart)

區域圖是一種常見的視覺化方式,適用於顯示隨時間變化的資料。當使用 pd.DataFrame 時,預設情況下會堆積疊列。

df.plot(kind="area")

若要取消堆積疊,可以使用 stacked=False 並新增 alpha 引數來調整透明度:

df.plot(kind="area", stacked=False, alpha=0.5)

內容解密:

  • kind="area":指定圖表型別為區域圖。
  • stacked=False:取消堆積疊模式。
  • alpha=0.5:調整圖表的透明度,值範圍在 0 到 1 之間,0 表示完全透明,1 表示完全不透明。

自定義標題與標籤

在建立圖表時,我們可以透過引數來自定義標題、標籤及顏色等。例如,新增標題:

ser.plot(kind="bar", title="每日書籍銷售量")

內容解密:

  • kind="bar":指定圖表型別為條形圖。
  • title="每日書籍銷售量":設定圖表的標題。

自定義顏色

我們可以使用 color引數來改變線條、條形和標記的顏色。顏色可以透過 RGB 十六進位制碼或 Matplotlib 的命名顏色來指定:

ser.plot(kind="bar", title="每日書籍銷售量", color="seagreen")

內容解密:

  • color="seagreen":設定圖表中的顏色為海綠色。

DataFrame 中的自定義顏色

當處理 pd.DataFrame 時,我們可以透過傳遞一個字典來控制哪些列使用哪些顏色:

df.plot(
    kind="bar",
    title="書籍指標",
    color={
        "book_sales": "slateblue",
        "book_returns": "#7D5260"
    }
)

內容解密:

  • color:字典中鍵為列名,值為對應的顏色。這樣可以為不同的列設定不同的顏色。

調整網格線

我們可以透過 grid引數來控制是否顯示網格線:

ser.plot(kind="bar", title="每日書籍銷售量", color="teal", grid=False)

內容解密:

  • grid=False:隱藏網格線。

自定義軸標籤

我們可以使用 xlabelylabel引數來控制 x 軸和 y 軸的標籤:

ser.plot(
    kind="bar",
    title="每日書籍銷售量",
    color="darkgoldenrod",
    grid=False,
    xlabel="日期編號",
    ylabel="書籍銷售量"
)

內容解密:

  • xlabel="日期編號":設定 x 軸的標籤。
  • ylabel="書籍銷售量":設定 y 軸的標籤。

建立子圖

當處理 pd.DataFrame 時,Pandas 預設會將每個列的資料放在同一個圖表中。但我們可以透過設定 subplots=True 來生成單獨的子圖:

df.plot(
    kind="bar",
    title="書籍績效",
    grid=False,
    subplots=True,
)

內容解密:

  • subplots=True:生成單獨的子圖。

調整傳說

當生成單獨的子圖時,傳說可能會變得多餘。我們可以透過設定 legend=False 來關閉傳說:

df.plot(
    kind="bar",
    title="書籍績效",
    grid=False,
    subplots=True,
    legend=False,
)

內容解密:

  • legend=False:關閉傳說。

分享 Y 軸

預設情況下,x 軸標籤是分享的,但 y 軸範圍可能不同。如果我們希望 y 軸也分享,可以新增 sharey=True

df.plot(
    kind="bar",
    title="書籍績效",
    grid=False,
    subplots=True,
    legend=False,
    sharey=True,
)

內容解密:

  • sharey=True:使所有子圖分享 y 軸範圍。

控制視覺化列

當使用 pd.DataFrame.plot 時,我們可以透過 y引數來控制哪些列應該被視覺化:

df.plot(
    kind="barh",
    y=["book_returns"],
    title="書籍退貨量",
    legend=False,
    grid=False,
    color="seagreen"
)

內容解密:

  • y=["book_returns"]:僅視覺化 “book_returns” 列。
  • kind="barh":指定水平條形圖。

散佈分佈視覺化

除了基本的條形圖和區域圖外,直方圖(Histogram)和核密度估計(KDE)也是常用於分析資料分佈的工具。以下將介紹如何使用 Pandas 和 Matplotlib 建立這些視覺化。

生成直方圖

首先,我們生成一個包含隨機正態分佈資料的 Pandas Series:

import numpy as np
import pandas as pd

np.random.seed(42)
ser = pd.Series(
    np.random.default_rng().normal(size=10_000),
    dtype=pd.Float64Dtype()
)

然後,我們可以使用直方圖來視覺化這些資料:

ser.plot(kind="hist")

調整直方圖桶(bins)

直方圖會將資料分成若干個桶(bins),並根據桶中的資料數量繪製柱狀。我們可以透過 bins引數來控制桶的數量:

ser.plot(kind="hist", bins=2)   # 較少桶數會使正態分佈不易觀察到
ser.plot(kind="hist", bins=100) # 較多桶數會更清晰地展示正態分佈

DataFrame 中的直方圖

當處理 DataFrame 時,我們可能會遇到不同列之間桶重疊的問題。這時我們可以透過增加透明度或生成子圖來解決這個問題:

np.random.seed(42)
df = pd.DataFrame({
    "normal": np.random.default_rng().normal(size=10_000),
    "triangular": np.random.default_rng().triangular(-2, 0, 2, size=10_000),
})
df = df.convert_dtypes(dtype_backend="numpy_nullable")

df.plot(kind="hist")             # 預設情況下桶可能重疊
df.plot(kind="hist", alpha=0.5) # 增加透明度以減少重疊影響
df.plot(kind="hist", subplots=True) # 生成子圖以避免桶重疊
df.plot(kind="hist", alpha=0.5, bins=100) # 增加桶數以更清晰地展示分佈差異

自定義視覺化組態

雖然 Pandas 提供了許多選項來控制視覺化效果,但有時候它可能無法完全滿足需求。這時我們可以使用 Matplotlib 的高階功能進行更精細的調整。

Kernel Density Estimate(KDE)圖

KDE 是一種更強大的工具,用於展示資料分佈。它不僅僅展示資料落入每個桶中的次數,還展示了資料點之間的密度分佈:

ser.plot(kind='kde')

這樣我們就能夠更清晰地看到資料分佈的一些特徵,例如正態性、偏斜度等。

此篇文章以深度探討瞭如何使用 Pandas 和 Matplotlib 建立和自定義各種視覺化工具,從而更好地理解和分析資料。透過實務案例和程式碼範例,玄貓希望能夠幫助讀者在實際工作中靈活運用這些技術。

資料視覺化的進階技巧

在資料分析中,視覺化是展示資料的重要方式,而直方圖(Histogram)是最常見的工具之一。然而,直方圖的分箱策略會對資料的解讀產生影響,這確實是一個缺點。這時候,我們可以使用核密度估計(Kernel Density Estimate,KDE)圖來避免這個問題。KDE 圖不需要手動選擇分箱策略,只需安裝 SciPy 函式庫即可使用。

使用 KDE 圖進行資料視覺化

首先,我們需要安裝 SciPy 函式庫:

python -m pip install scipy

安裝完成後,我們可以將 kind 引數設定為 "kde" 來繪製 KDE 圖:

ser.plot(kind="kde")

在一個 pd.DataFrame 中使用 KDE 圖,可以清楚地看到兩個不同的分佈:

df.plot(kind="kde")

Matplotlib 的進階自定義

對於簡單的圖表,pandas 提供的預設佈局可能已經足夠。然而,當我們需要更複雜的自定義時,Matplotlib 會是更好的選擇。在 Matplotlib 中,「figure」指的是繪圖區域,「axes」或「subplot」則是 figure 中的繪圖區域。注意不要將「axes」與「axis」(X軸或Y軸)混淆。

複合圖表的繪製

我們以書本銷售資料為例,繪製三種不同型別的折線圖、條形圖和餅狀圖。首先,我們設定繪圖區域:

fig, axes = plt.subplots(nrows=1, ncols=3)

這樣會傳回一個包含 figure 和 axes 序列的二元組。接下來,我們將資料繪製到這些 axes 上:

ser.plot(ax=axes[0])
ser.plot(kind="bar", ax=axes[1])
ser.plot(kind="pie", ax=axes[2])

這樣生成的結果可能會顯得很不美觀,因為 Matplotlib 預設會給出等大小的 axes,導致折線圖和條形圖過高狹長,餅狀圖上下留白過多。

使用 GridSpec 進行更精細的控制

我們可以使用 Matplotlib 的 GridSpec 來建立一個 2x2 的網格,將折線圖和條形圖放在第一行,餅狀圖佔據整個第二行:

from matplotlib.gridspec import GridSpec

fig = plt.figure()
gs = GridSpec(2, 2, figure=fig)
ax0 = fig.add_subplot(gs[0, 0])
ax1 = fig.add_subplot(gs[0, 1])
ax2 = fig.add_subplot(gs[1, :])
ser.plot(ax=ax0)
ser.plot(kind="bar", ax=ax1)
ser.plot(kind="pie", ax=ax2)

這樣看起來會好一些,但還有一些標籤重疊問題。我們可以進一步修改每個 axes 的標籤旋轉、移除標籤、改變標題等:

fig.suptitle("Book Sales Visualized in Different Ways")
gs = GridSpec(2, 2, figure=fig, hspace=.5)
ax0 = fig.add_subplot(gs[0, 0])
ax1 = fig.add_subplot(gs[0, 1])
ax2 = fig.add_subplot(gs[1, :])

ax0 = ser.plot(ax=ax0)
ax0.set_title("Line chart")
ax1 = ser.plot(kind="bar", ax=ax1)
ax1.set_title("Bar chart")
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=45)

# 則餅狀圖移除標籤並新增自定義圖例
ax2 = ser.plot(kind="pie", ax=ax2, labels=None)
ax2.legend(
    ser.index,
    bbox_to_anchor=(1, -0.2, 0.5, 1),
    prop={"size": 6},
)
ax2.set_title("Pie Chart")
ax2.set_ylabel(None)

探索散點圖

散點圖是最強大的視覺化工具之一,能夠在有限空間內展示兩個變數之間的關係、測量單個資料點的規模,甚至檢視這些關係和規模在不同類別中的變化。

散點圖的建立

散點圖至少需要兩個變數來衡量其之間的關係,因此只能使用 pd.DataFrame 建立。以下是一個包含四個列的範例 pd.DataFrame

df = pd.DataFrame({
    "var_a": [1, 2, 3, 4, 5],
    "var_b": [1, 2, 4, 8, 16],
    "var_c": [500, 200, 600, 100, 400],
    "var_d": ["blue", "orange", "gray", "blue", "gray"],
})
df = df.convert_dtypes(dtype_backend="numpy_nullable")
df

此表格中包含了三個連續變數和一個顏色列用於分類別不同資料點。

散點圖邏輯及應用

散點圖能夠同時展示多種資料特徵。例如:var_avar_b 是連續變數之間的關係;而顏色列 var_d 用來區分不同類別。這樣的一張散點圖能夠幫助我們快速理解資料之間的關係以及不同類別中的差異。

玄貓強調,雖然 Matplotlib 提供了非常靈活且強大的自定義功能,但對於一些使用者來說可能過於複雜。幸運的是,像 seaborn 操作簡單且美觀的高層次繪製包正好滿足了這類別使用者需求。

資料視覺化與散點圖深度分析

在進行資料分析時,視覺化是非常重要的一環。它不僅能夠幫助我們理解資料的內在關係,還能讓我們更直觀地發現潛在的模式和異常值。本文將探討如何利用Python中的Pandas和Matplotlib進行資料視覺化,特別是散點圖的應用。

散點圖基本概念

散點圖(Scatter Plot)是一種用來顯示兩個變數之間關係的圖表。透過將資料點繪製在二維平面上,我們可以直觀地觀察到這兩個變數之間的相關性。在Pandas中,我們可以使用plot方法來繪製散點圖。

以下是一個簡單的散點圖範例:

import pandas as pd
import matplotlib.pyplot as plt

# 假設我們有一個DataFrame df
data = {
    'var_a': [1, 2, 3, 4, 5],
    'var_b': [5, 4, 3, 2, 1],
    'var_c': [200, 300, 400, 500, 600],
    'var_d': ['A', 'B', 'C', 'D', 'E']
}
df = pd.DataFrame(data)

df.plot(
    kind="scatter",
    x="var_a",
    y="var_b",
    s="var_c",
    c="var_d"
)
plt.show()

內容解密:

這段程式碼展示瞭如何使用Pandas來繪製一個基本的散點圖。kind="scatter"指定了圖表型別為散點圖,xy分別指定了X軸和Y軸的變數,s指定了每個資料點的大小,c指定了每個資料點的顏色。這樣我們可以根據不同的變數來控制資料點的顯示效果。

探索實際資料集

為了更深入地瞭解散點圖的應用,我們將使用美國能源部發布的年度報告資料集。這個資料集包含了1985年至2025年的車輛燃油經濟性測試結果。我們將從中選取幾個關鍵欄位進行分析。

df = pd.read_csv(
    "data/vehicles.csv.zip",
    dtype_backend="numpy_nullable",
    usecols=["city08", "highway08", "VClass", "fuelCost08", "year"]
)
df.head()

內容解密:

這段程式碼展示瞭如何從CSV檔案中讀取特定欄位的資料。dtype_backend="numpy_nullable"用於處理缺失值,usecols則指定了我們需要的欄位。這樣我們可以只讀取對我們有用的部分,提高處理效率。

資料過濾與分類別

由於這個資料集包含多種車輛型別,我們將過濾出2015年以後的轎車(Car)進行分析。

car_classes = (
    "Subcompact Cars",
    "Compact Cars",
    "Midsize Cars",
    "Large Cars",
    "Two Seaters"
)

mask = (df["year"] >= 2015) & df["VClass"].isin(car_classes)
df = df[mask]
df.head()

內容解密:

這段程式碼展示瞭如何過濾資料。首先,我們定義了一個包含所需車輛型別的列表。然後使用布林索引過濾出符合條件的行。這樣我們就得到了一個只包含2015年以後轎車的DataFrame。

基本散點圖

接下來,我們將繪製市區和高速公路每加侖行駛里程(MPG)之間的關係。

df.plot(
    kind="scatter",
    x="city08",
    y="highway08"
)
plt.show()

內容解密:

這段程式碼展示瞭如何繪製市區和高速公路MPG之間的關係。從圖表中可以看出,這兩者之間存在一個強烈的線性趨勢,即市區和高速公路MPG之間有一定的正相關性。

分類別顏色與尺寸

為了進一步探索資料,我們可以根據車輛型別分配顏色並根據燃油成本調整資料點大小。

classes_ser = pd.Series(car_classes, dtype=pd.StringDtype())
cat = pd.CategoricalDtype(classes_ser)
df["VClass"] = df["VClass"].astype(cat)

df.plot(
    kind="scatter",
    x="city08",
    y="highway08",
    c="VClass",
    colormap="Dark2"
)
plt.show()

內容解密:

這段程式碼展示瞭如何根據車輛型別分配顏色。首先,我們將車輛型別轉換為分型別(Categorical),然後使用colormap引數來分配顏色。這樣我們可以更直觀地看到不同車輛型別在市區和高速公路MPG之間的分佈情況。

調整尺寸與透明度

由於燃油成本數值較大,直接使用可能會導致資料點過大。因此,我們需要對燃油成本進行縮放並新增透明度。

df.assign(
    scaled_fuel_cost=lambda x: x["fuelCost08"] / 25,
).plot(
    kind="scatter",
    x="city08",
    y="highway08",
    c="VClass",
    colormap="Dark2",
    s="scaled_fuel_cost",
    alpha=0.4
)
plt.show()

內容解密:

這段程式碼展示瞭如何調整資料點大小和透明度。首先,我們將燃油成本縮小25倍並新增到DataFrame中。然後在繪製散點圖時使用縮小後的燃油成本作為尺寸並設定透明度為0.4。這樣可以使圖表更加清晰易讀。

散點矩陣

除了基本散點圖外,散點矩陣(Scatter Matrix)也是一種強大的視覺化工具。它可以生成所有連續變數之間的雙變數關係。

from pandas.plotting import scatter_matrix
scatter_matrix(df)
plt.show()

內容解密:

這段程式碼展示瞭如何繪製散點矩陣。透過sctter_matrix函式,我們可以快速生成所有連續變數之間的雙變數關係圖表。這樣可以幫助我們更全面地理解資料中的各種關係。

內容解密:

此圖示展示了城市裡程、高速里程、燃料成本及車輛型別之間的一些邏輯關係。 玄貓建議:對於現代技術專家而言,不僅要擁有堅實的技術知識基礎,還要具備靈活運用各種工具進行深入分析及驗證假設能力。 玄貓提醒:現代資料科學家必須不斷學習及更新技術知識來保持競爭力且技術堆積疊為成功關鍵。