跳轉至

建立 2026-10-13 更新 2026-10-13

分布與統計圖

分布圖回答「資料集中在哪裡、散得多開、有沒有離群值」。Plotly Express 提供直方圖(px.histogram)、箱形圖(px.box)、小提琴圖(px.violin)、條帶圖(px.strip)、經驗累積分布圖(px.ecdf)與二維密度圖(px.density_heatmap、px.density_contour),另外散佈圖的 trendline 參數可以直接加上迴歸或平滑趨勢線。

直方圖 px.histogram

直方圖把數值切成區間(bin),計算每個區間的筆數。

import plotly.express as px

df = px.data.tips()
fig = px.histogram(df, x="total_bill", color="sex", marginal="box",
                   nbins=30, opacity=0.75)
fig.show()
參數 說明
nbins 區間數量
histnorm 正規化:"percent"、"probability"、"density"、"probability density"
histfunc 有 y 時的彙總函式:"count"(預設)、"sum"、"avg"、"min"、"max"
barmode 多組時:"relative"(堆疊,預設)、"overlay"(重疊,搭配 opacity)、"group"
cumulative=True 累積直方圖
marginal 在上方加 "box"、"violin"、"rug" 小圖
text_auto=True 在長條上顯示數值

histogram 也是「自動加總的長條圖」

x 是類別欄位時,px.histogram 會計算每個類別的筆數;再加上 y 與 histfunc="sum" 就是「先 groupby 再加總」的長條圖。這是畫類別統計最省事的寫法:

px.histogram(df, x="day", y="tip", histfunc="avg", color="time", barmode="group")

箱形圖 px.box

箱形圖(box plot)用五個數字摘要分布:最小值、第一四分位數(Q1)、中位數、第三四分位數(Q3)、最大值;超出 1.5 倍四分位距(IQR)的點畫成離群值。

import plotly.express as px

df = px.data.tips()
fig = px.box(df, x="day", y="total_bill", color="smoker", points="all",
             category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]})
fig.show()
參數 說明
points 顯示原始資料點:"outliers"(預設)、"all"、"suspectedoutliers"、False
notched=True 在中位數處加凹口,方便比較兩組中位數是否明顯不同
boxmode 多組時 "group"(並排,預設)或 "overlay"

小提琴圖 px.violin

小提琴圖用核密度估計(KDE)畫出分布形狀,比箱形圖更能看出「雙峰」等細節。

px.violin(df, y="tip", x="smoker", color="sex", box=True, points="all")

box=True 在小提琴內部加一個小箱形圖;violinmode="overlay" 讓不同顏色的小提琴重疊比較。

條帶圖 px.strip

條帶圖(strip plot)把每一筆資料都畫成點,並在橫向加入隨機抖動避免重疊。資料量小(數百筆以內)時,比箱形圖更誠實。

px.strip(df, x="total_bill", y="day", color="sex", orientation="h")

經驗累積分布圖 px.ecdf

ECDF(Empirical Cumulative Distribution Function)的每個點表示「小於等於這個值的資料佔多少比例」。不需要選區間數,適合比較多組分布。

px.ecdf(df, x="total_bill", color="sex", markers=True)

ecdfnorm=None 改顯示累積筆數;ecdfmode="reversed" 改成「大於等於」。

二維密度圖

資料點太多、散佈圖重疊嚴重時,改用二維直方圖:

px.density_heatmap(df, x="total_bill", y="tip", nbinsx=20, nbinsy=20,
                   marginal_x="histogram", marginal_y="histogram", text_auto=True)

px.density_contour(df, x="total_bill", y="tip", color="sex")  # 等高線版本

density_heatmap 也能用 z 加上 histfunc="avg" 計算每一格的平均值,相當於一張彙總熱圖。

趨勢線

px.scatter 的 trendline 參數直接加上趨勢線,不需要自己算迴歸:

import plotly.express as px

df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip", color="time", trendline="ols")
fig.show()
trendline 值 說明 需要套件
"ols" 普通最小平方法線性迴歸 statsmodels
"lowess" 局部加權平滑曲線 statsmodels
"rolling" 移動平均,搭配 trendline_options=dict(window=5) pandas
"ewm" 指數加權移動平均,搭配 trendline_options=dict(halflife=2) pandas
"expanding" 累積平均 pandas

trendline_scope="overall" 畫一條涵蓋所有資料的趨勢線(預設每個顏色一條)。取得迴歸係數與 R²:

results = px.get_trendline_results(fig)
print(results.px_fit_results.iloc[0].summary())

該選哪一種?

情境 建議
一個變數的分布形狀 histogram,或不想選區間時用 ecdf
多組分布比較中位數與離群值 box
多組分布比較形狀 violin
資料不多,想看每一筆 strip
兩個變數、點非常多 density_heatmap/density_contour
兩個變數的線性關係 scatter + trendline="ols"

推薦影音

Box & Violin Plots - Python Plotly(Charming Data)

簡述:先講解如何閱讀箱形圖與小提琴圖,再用 Plotly Express 畫出、調整樣式並加入動畫,資料是美國蜂群數量。對應本頁「箱形圖」與「小提琴圖」兩節。

相關頁面