分布與統計圖
分布圖回答「資料集中在哪裡、散得多開、有沒有離群值」。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.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)畫出分布形狀,比箱形圖更能看出「雙峰」等細節。
box=True 在小提琴內部加一個小箱形圖;violinmode="overlay" 讓不同顏色的小提琴重疊比較。
條帶圖 px.strip
條帶圖(strip plot)把每一筆資料都畫成點,並在橫向加入隨機抖動避免重疊。資料量小(數百筆以內)時,比箱形圖更誠實。
經驗累積分布圖 px.ecdf
ECDF(Empirical Cumulative Distribution Function)的每個點表示「小於等於這個值的資料佔多少比例」。不需要選區間數,適合比較多組分布。
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²:
該選哪一種?
| 情境 | 建議 |
|---|---|
| 一個變數的分布形狀 | histogram,或不想選區間時用 ecdf |
| 多組分布比較中位數與離群值 | box |
| 多組分布比較形狀 | violin |
| 資料不多,想看每一筆 | strip |
| 兩個變數、點非常多 | density_heatmap/density_contour |
| 兩個變數的線性關係 | scatter + trendline="ols" |
推薦影音
Box & Violin Plots - Python Plotly(Charming Data)
簡述:先講解如何閱讀箱形圖與小提琴圖,再用 Plotly Express 畫出、調整樣式並加入動畫,資料是美國蜂群數量。對應本頁「箱形圖」與「小提琴圖」兩節。