基礎已經雙重審閱,尚未人工抽查

分布圖:為什麼不要用長條圖加誤差線

mean 加一根誤差線的長條圖把樣本數、分布形狀、離群值全部藏起來,而那根誤差線可能是 SD、SE 或 95% CI 中的任何一種,長度差好幾倍。盒鬚圖、小提琴圖與 raincloud 各補上什麼,以及期刊為什麼開始要求畫出每一個資料點。

這一頁在解決什麼問題

論文與投影片上最常見的連續變項畫法是這樣的:每組一根長條,長條高度是平均數,頂上長出一根短短的誤差線。 這種圖有個綽號叫 dynamite plot(炸藥棒圖),因為它長得像插著引線的炸藥。

它的問題不是不好看,是每組只畫了兩個數字:一個柱高、一根鬍鬚長度。 你手上原本有幾十幾百個觀測值,畫完之後讀者拿到兩個摘要量,而且看不出來這兩個數字是從幾個人身上算來的。

本頁把同一份資料畫成四種圖,然後具體算出前一種畫法藏掉了什麼。 資料是 MASS::birthwt:189 位產婦,結果變項是新生兒出生體重(公克), 分組變項與 t 檢定與變異數分析那一頁的 ANOVA 例子完全相同, 所以兩頁講的是同一份資料的同一組分層。

同一份資料,四種畫法

四格圖,同一份出生體重資料依三個族群分組。A 為平均數長條圖加標準誤誤差線,圖上以文字列出這一格看不到的東西;B 為盒鬚圖,顯示中位數、四分位數與被標記的離群點;C 為小提琴圖,顯示完整的密度形狀;D 為 raincloud,左側是每一個觀測值的抖動散點、中間是窄箱、右側是半個密度曲線,並在各組底下標出樣本數。
同一份資料的四種畫法。A 的縱軸從 0 起(長條圖必須如此),另外三格的縱軸落在資料真正的範圍上,所以 A 把 709 到 4990 公克這段真實跨距壓成了柱頂的一小截。產圖腳本 figures/scripts/B1-05-distribution-plots.R

四種畫法看得到與看不到的東西:

畫法讀者拿得到讀者拿不到
長條圖 + 誤差線平均數、一根長度未定義的鬍鬚樣本數、離散程度、形狀、離群值、個別觀測值
盒鬚圖中位數、四分位距、鬍鬚範圍、被標記的離群點樣本數、雙峰、箱內部的密度分布
小提琴圖完整的密度形狀、雙峰、長尾樣本數、個別觀測值(密度是估計出來的,不是資料本身)
raincloud密度形狀、四分位數、每一個觀測值、樣本數沒有——它的成本是版面,不是資訊

注意 A 那一格的縱軸:長條圖的柱長要能被比較,起點就必須是 0, 於是整段資料被擠在圖的上緣。另外三種圖不受這個限制,縱軸可以貼著資料走,所以同樣的紙面上解析度高得多。

dynamite 在這份資料上藏了什麼

前一節的表格是原則。原則說服不了人,所以這一節把數字算出來。

一、三組的人數差了好幾倍,而長條圖上完全看不到

組別n平均數(g)SD(g)SE(g)中位數(g)四分位距(g)
白人963102.7727.974.330621066.2
黑人262719.7638.7125.32849686.5
其他672805.3722.288.22835961

最大組與最小組的人數比是 3.69,而三組的 SD 幾乎一樣 (最大與最小只差 1.14 倍)。可是三根 SE 誤差線的長度差了 1.69 倍。原因是 SE 等於 SD 除以 n 的平方根,所以誤差線的長度主要在講樣本數,不在講離散程度

這件事在這份資料上有一個極乾淨的例子:黑人組的 SD 是三組裡最小的 (638.7 g),可是它的 SE 誤差線是三組裡最長的(125.3 g), 因為那一組只有 26 個人。

二、平均數差得看起來很多,個別的嬰兒重疊得很厲害

兩組比較平均數差(g)隨機各抽一人,前者較重的機率前者落在後者四分位距內的比例兩組數值範圍的交集(g)
白人 vs 黑人3830.65430.2%1135 到 3860
白人 vs 其他297.40.60642.7%1021 到 4054
黑人 vs 其他-85.60.45953.8%1135 到 3860

第一列是最有代表性的:白人組與 黑人組的平均數差 383 公克, 在長條圖上是肉眼可見的兩根不同高度的柱子。但如果從兩組各隨機抽一個嬰兒, 白人組那個比較重的機率只有 0.654——比丟硬幣好一些,遠不到「兩組不一樣」的程度。 而且有 30.2% 的 白人組嬰兒的體重,落在 黑人組的四分位距裡面。

「隨機各抽一人,前者較重的機率」這個量(機率優越性,probability of superiority)之所以好用, 是因為它跟原始單位無關,而且每個讀者都懂 0.5 是什麼意思。它不是檢定,也不取代 ANOVA 與事後比較那一頁在做的推論—— 它回答的是另一個問題:這個組間差距,放到一個病人身上,有多大

三、形狀:這份資料其實相當乾淨,說實話比較有用

教科書講到這裡通常會說「而且長條圖藏住了偏態、雙峰與離群值」。在這份資料上,這句話大部分不成立, 照實報出來比硬套原則有用:

組別偏度1.5 IQR 規則下的離群值個數密度局部極大值(預設頻寬)密度局部極大值(頻寬放寬一半)
白人-0.13031
黑人-0.31131
其他-0.42121

三組的偏度絕對值最大只有 0.42,屬於接近對稱; 全部 189 個嬰兒裡,被 1.5 IQR 規則標成離群值的只有 2 個。 至於雙峰:在 density() 的預設頻寬下,最多的一組有 3 個局部極大值, 看起來像有第二個群;但把頻寬放寬一半之後,三組全部只剩 1 個。 多出來的那幾個峰是平滑參數的產物,不是次族群的證據。

所以在這份資料上,dynamite plot 的傷害來自人數差距重疊,不是來自被藏起來的偏態或雙峰。 形狀真的不同時會發生什麼,第五節用刻意構造的資料補上。

三種誤差線,外觀一樣,長度差好幾倍

上面一直說「那根誤差線」,因為在圖上根本看不出它是什麼。同一組資料可以畫出三種誤差線:

  • SD(標準差) 描述的是個體之間有多分散。它不隨樣本數縮小——多收一百個人,SD 大致不變。
  • SE(標準誤) 描述的是平均數這個估計有多精確。它等於 SD 除以 n 的平方根,所以人越多它越短。
  • 95% CI 是 SE 乘上一個 t 分位數,大約兩倍的 SE。它回答的是「平均數合理落在哪個範圍」。
同一組出生體重資料的三種誤差線並排。左側三根是平均數正負一個標準差,中間三根是平均數正負一個標準誤,右側三根是平均數的 95% 信賴區間;每根誤差線上方標出它的半長度(公克),標準差的棒子明顯比標準誤的棒子長好幾倍。
三組完全相同,三個平均數完全相同,只有誤差線的定義換了。每根棒子上方的數字是它的半長度(公克)。這三種畫法在圖上長得一模一樣,只有圖說能區分。產圖腳本 figures/scripts/B1-05-distribution-plots.R
組別SD 半長(g)SE 半長(g)95% CI 半長(g)SD 是 SE 的幾倍CI 是 SE 的幾倍
白人727.974.3147.59.81.99
黑人638.7125.32585.12.06
其他722.288.2176.28.192

在 白人組,SD 的棒子是 SE 棒子的 9.8 倍長。 換句話說,同一份資料、同一個平均數,作者選 SE 或選 SD,讀者看到的圖差了將近一個數量級。 而 SE 是三者中最短的,所以選 SE 會讓組間看起來最分開——這也是它最常被選的原因之一。

還有一個相關的誤讀:誤差線有沒有重疊,不能當成檢定的替代品。 兩組的 95% CI 稍微重疊時, 兩組平均數差的檢定仍然可能達到統計顯著;反過來,兩組的 SE 棒子沒有重疊,也不代表達到顯著。 要判斷組間差距,看的是差距本身的信賴區間,不是兩個各自的區間有沒有碰到。 這一點在 t 檢定與變異數分析那一頁講得更完整。

同一張長條圖,三份完全不同的資料

前面第三節已經照實說了:birthwt 的三組分布相當對稱、離群值很少。 那形狀真的不同的時候會怎樣?下面三份資料是刻意構造的,不是任何研究的結果: 三份都是 40 個觀測值,平均數都是 3000,標準差都是 700, 所以 SE 都是 110.7,95% CI 半長都是 223.9。它們的長條圖是同一張圖畫三次

上排是三個構造樣本的平均數長條圖加標準誤誤差線,三根長條與三根誤差線完全一樣長。下排三格是同樣三份資料的 raincloud:第一格是對稱單峰、第二格明顯分成上下兩群、第三格絕大多數集中在低處而有四個點遠遠落在上方。
假設性資料,不是任何研究的結果。三份樣本的樣本數、平均數與標準差刻意設成完全相同,所以上排的長條圖三根一樣;下排顯示它們其實是三種完全不同的東西。虛線是共同的平均數。產圖腳本 figures/scripts/B1-05-distribution-plots.R
構造樣本平均數SDSE中位數偏度離群值個數密度峰數
樣本一:對稱單峰3000700110.73000001
樣本二:兩個群3000700110.73000002
樣本三:四個極端值3000700110.72831.81.9543

前四欄一模一樣,後四欄完全不同。樣本二分成兩群,平均數落在兩群之間沒有人的地方—— 一個沒有任何觀測值靠近的位置,卻是柱子的高度。樣本三的偏度是 1.95, 4 個極端值把平均數從中位數 2831.8 拉到了 3000。

動手跑一次

library(MASS)
data(birthwt, package = "MASS")
bw <- birthwt
bw$race_f <- factor(bw$race, levels = 1:3, labels = c("White", "Black", "Other"))
sp <- split(bw$bwt, bw$race_f)

# 1. 長條圖加 SE。放在這裡是為了對照,不是建議。
m  <- sapply(sp, mean)
se <- sapply(sp, function(x) sd(x) / sqrt(length(x)))
mids <- barplot(m, ylim = c(0, 3600), ylab = "Birth weight (g)")
arrows(mids, m, mids, m + se, angle = 90, code = 2, length = 0.05)

# 2. 盒鬚圖。一行。
boxplot(bwt ~ race_f, data = bw, ylab = "Birth weight (g)")

# 3. 小提琴圖:density() + polygon(),不需要額外套件。
violin <- function(x, at, width = 0.35, col = "#dfe6ee") {
  d <- density(x, adjust = 1.2)
  k <- d$x >= min(x) & d$x <= max(x)      # 不要畫到資料範圍以外
  dy <- d$y[k] / max(d$y) * width
  polygon(c(at + dy, rev(at - dy)), c(d$x[k], rev(d$x[k])), col = col)
}
plot(NA, xlim = c(0.5, 3.5), ylim = range(bw$bwt), xaxt = "n",
     xlab = "", ylab = "Birth weight (g)")
axis(1, at = 1:3, labels = levels(bw$race_f))
for (i in 1:3) violin(sp[[i]], i)

# 4. raincloud:半個小提琴 + 窄箱 + 每一個觀測值。
plot(NA, xlim = c(0.5, 3.5), ylim = range(bw$bwt), xaxt = "n",
     xlab = "", ylab = "Birth weight (g)")
axis(1, at = 1:3, labels = levels(bw$race_f))
set.seed(1)                               # 固定 seed,否則每次重畫點位都不同
for (i in 1:3) {
  x <- sp[[i]]
  d <- density(x, adjust = 1.2)
  k <- d$x >= min(x) & d$x <= max(x)
  dy <- d$y[k] / max(d$y) * 0.34
  polygon(c(rep(i, sum(k)), rev(i + dy)), c(d$x[k], rev(d$x[k])),
          col = "#dfe6ee", border = "#4d6a8c")
  boxplot(x, at = i - 0.02, add = TRUE, boxwex = 0.09,
          axes = FALSE, outline = FALSE)
  points(jitter(rep(i - 0.22, length(x)), amount = 0.09), x,
         pch = 16, cex = 0.6, col = adjustcolor("#4d6a8c", 0.4))
  text(i - 0.22, min(bw$bwt), paste0("n = ", length(x)), cex = 0.8)
}

驗證環境:R 4.6.0 + MASS 7.3.65。四種圖全部只用 base R,不需要安裝任何東西——這一頁的立場是「畫得比長條圖好」根本不需要新工具。抖動點一定要固定 seed,否則同一份資料每次重畫的點位都不同。

期刊已經開始要求畫出個別資料點

這件事不是風格偏好,已經進了投稿規範。

Weissgerber 等人在 PLOS Biology(2015)調查了頂尖生理學期刊的論文,發現絕大多數連續變項都畫成長條圖加誤差線, 而且相當多的樣本數小到那兩個摘要量幾乎沒有意義。他們的核心論點就是本頁第五節那張圖: 同一張長條圖對應到很多份長相完全不同的資料。

之後的變化:

  • PLOS Biology 的投稿規範建議連續資料要用讓讀者能評估分布的畫法(散點、盒鬚、直方), 並且規定樣本數小的資料(每組 9 個以下的獨立觀測值)必須畫出完整分布,不能只畫摘要量。
  • eLife 要求圖說寫明樣本數與誤差線的定義(連同統計方法與重複次數), 也就是把上一節那個「圖說沒寫就不能解讀」的問題直接寫進規範。
  • 越來越多期刊在圖表規範裡不鼓勵用長條圖表達連續變項。

實務上的判準很簡單:

  • 每組不到二十個觀測值 → 直接把每一個點畫出來(點圖或 raincloud),不要摘要。
  • 每組數十到數百 → 盒鬚圖或小提琴圖,能疊上抽樣後的點更好。
  • 每組上千 → 點會糊成一片,用小提琴圖或直方圖,並且把樣本數寫在圖上。
  • 任何情況 → 圖說要寫明誤差線是什麼、樣本數是多少。

那長條圖什麼時候是對的

長條圖不是壞圖,是被用錯了地方。它的本業是計數與比例:類別變項各層有幾個人、幾成, 柱長從 0 起算而且真的代表「有多少」。這種時候柱長是可加的、可比的,長條圖是正確的選擇—— 細節見 卡方檢定與比例的比較

至於連續變項,即使你只想報摘要量,也還有兩個選擇比長條圖好:

  • 報平均數與其信賴區間的點區間圖(不畫柱子)。柱子本身沒有帶任何資訊,卻佔掉整個縱軸空間。
  • 偏態變項改報中位數與四分位距。 該報平均數還是中位數,判準在 Table 1 與標準化平均差那一頁「平均數還是中位數」那一節。

常見誤用

誤用為什麼錯
連續變項畫成長條圖加誤差線每組只剩兩個數字,樣本數、形狀、離群值、個別觀測值全部消失
圖說只寫「error bars」不寫是哪一種SD、SE、95% CI 在圖上長得一樣,長度差好幾倍,讀者無法解讀
用 SE 當誤差線讓組間看起來分開SE 是三者中最短的;它描述的是平均數的精確度,不是個體的離散
把「鬍鬚比較長」讀成「那一組比較不一致」SE 的長度主要由樣本數決定,本頁的例子裡方向是反過來的
用兩組誤差線有沒有重疊代替檢定要看的是差距本身的信賴區間,不是兩個各自區間有沒有碰到
各組人數差很多卻不標出來讀者無法判斷哪一根柱子是穩定的估計
小提琴圖有兩個鼓包就宣稱有兩個亞群峰數隨頻寬變動,本頁三組在放寬頻寬後全部只剩一個峰
看到平均數差得多就說個別病人差得多本頁的例子裡隨機各抽一人的優越機率只有 0.654
只因為誤差線重疊就說「兩組沒有差異」只能說本圖未顯示分離;要主張相當需要非劣性設計與事先設定的界限
類別變項的次數也改畫小提琴圖計數與比例本來就該用長條圖,別把本頁的結論套過頭

重跑本頁的所有數字

/opt/homebrew/bin/Rscript figures/scripts/B1-05-distribution-plots.R

讀讀看這張圖

答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。

dynamite plot 上,人數最少的那一組(26 人)的誤差線是三根裡最長的。這代表那一組的嬰兒體重比較不一致嗎?

看答案與解析

正確答案: 不是。那一組的標準差 638.7 公克其實是三組裡最小的——標準誤等於標準差除以人數的平方根

三組的標準差幾乎一樣,最大與最小差不到兩成,可是三根標準誤誤差線的長度差了 1.7 倍。最乾淨的例子就是這一組:標準差 638.7 公克是三組裡最小的,標準誤卻是三組裡最長的,因為它只有 26 個人。所以「哪一組的鬍鬚比較長」這個視覺印象,講的不是那一組的人比較不一致,而是那一組的人比較少——這是一個方向會反過來的錯覺,不是程度上的失真。258.0 是同一組的信賴區間半長,大約是標準誤的兩倍,換一種誤差線並不會改變上面那件事:三種誤差線在圖上長得一模一樣,只有圖說能區分。

白人組與黑人組的平均出生體重差 383 公克,在長條圖上是肉眼可見的兩根不同高度的柱子。把這個組間差距放到一個病人身上,有多大?

看答案與解析

正確答案: 從兩組各隨機抽一個嬰兒,前一組那個比較重的機率是 0.654——比丟硬幣好一些

機率優越性 0.654 跟原始單位無關,而且每個讀者都懂一半是什麼意思:它回答的正是「這個組間差距放到單一個病人身上有多大」,答案是比丟硬幣好一些。0.302 確實是前一組落在後一組四分位距裡的比例,但這個比例低不代表兩組不重疊——四分位距只涵蓋中間一半的人,落在它外面是常態,而兩組的數值範圍其實從一千一百多公克一路交集到三千八百多。0.462 是反方向的同一種比例,它描述的是重疊,不是差距的大小。組間平均數差得看起來很多、個別的人卻重疊得很厲害,正是長條圖最會誤導的地方;而這個量不是檢定,也不取代 ANOVA 與事後比較做的推論,它回答的是另一個問題。

同一組資料的三種誤差線半長分別是 727.9、74.3 與 147.5 公克,而圖說只寫了 error bars 四個字。這張圖能不能解讀?

看答案與解析

正確答案: 不能。標準差的棒子是標準誤棒子的 9.8 倍長,換一種定義讀者看到的圖就差了一個數量級

三種誤差線在圖上長得一模一樣,只有圖說能區分,而它們的長度差了將近一個數量級:標準差的棒子是標準誤棒子的 9.8 倍。所以圖說沒寫明是哪一種時,這一格資料就當作沒有讀到——不是「解讀得不夠精確」,是不能解讀。「看相對長度推回去」在只有一張圖的時候做不到,讀者手上沒有另外兩根可以比;信賴區間確實大約是標準誤的 2.0 倍,但那是在你已經知道兩者都畫出來的前提下。至於 74.3 是三者中最短的,而最短的那一種會讓組間看起來最分開,這也是它最常被選的原因之一。另外,誤差線有沒有重疊不能當成檢定的替代品:要判斷組間差距,看的是差距本身的信賴區間,不是兩個各自的區間有沒有碰到。

三份刻意構造的資料,樣本數、平均數與標準差都相同,所以它們的長條圖是同一張圖畫三次,柱子的高度都是 3000 公克。哪一份的柱子高度落在一個沒有任何觀測值靠近的位置?

看答案與解析

正確答案: 密度有 2 個峰的那一份——兩群人各自聚在柱子的左右兩側,中間那一段是空的,平均數就落在那段空隙裡

三份的樣本數、平均數、標準差、標準誤完全相同,長條圖畫出來是同一張圖,差別全在圖上看不到的地方。四個極端值那一份的中位數 2832 公克確實被拉離了 3000,但「平均數不等於中位數」不等於「平均數附近沒有人」——那一份的觀測值連成一片,離 3000 最近的那一個幾乎就站在柱子的高度上,它失真的方式是柱子代表不了典型的病人,不是柱子落在空地上。對稱那一份更直接,對稱不是平坦,它是單峰的,密度最高的位置正好就是柱子的高度,三份裡只有它的長條圖沒有說謊。真正落在空地上的是有兩個峰的那一份——兩群人各自聚在兩側,中間空了五百多公克,平均數就落在那段沒有人的空隙裡。遇到這種形狀該做的不是換一種圖,是回頭問這一組是不是其實不是一組(有反應與沒反應、兩種亞型、兩個中心的收案差異),圖只是讓你有機會問這個問題。

這份資料三組的密度曲線在預設頻寬下最多有 3 個局部極大值,看起來像有次族群;把頻寬放寬一半之後,三組全部只剩 1 個。該怎麼下結論?

看答案與解析

正確答案: 多出來的峰是平滑參數的產物。放寬之後只剩 1 個,而「密度有幾個峰」是你選的頻寬的性質,不是資料的性質

看到論文的小提琴圖有兩個鼓包,下結論之前要問的是作者用了什麼頻寬——而多數論文不會寫。這份資料就是例子:預設頻寬下最多的一組有三個局部極大值,放寬一半之後三組全部只剩一個。預設值是一個經驗公式,不是資料的結論,所以不能拿它當作次族群存在的證據;反過來說,放寬頻寬也不是在抹掉訊號,是在問這個峰撐不撐得住。被四分位距規則標成離群值的個數說明這份資料相當乾淨,但那件事跟峰數的判讀無關。這也是 raincloud 把個別點畫出來的另一個理由:點畫出來之後,讀者不必相信任何平滑參數。

審稿人說「多收一百個人,誤差線就會變短,圖看起來會更有說服力」。這句話對哪一種誤差線成立?

看答案與解析

正確答案: 只對標準誤與信賴區間成立。標準誤 74.3 公克等於標準差除以人數的平方根,人愈多它愈短

標準差描述的是個體之間有多分散,它是這群人的性質:多收一百個人,估計會更穩,但數值大致不變,這一組是 727.9 公克。標準誤描述的則是平均數這個估計有多精確,等於標準差除以人數的平方根,所以人愈多它愈短,這一組是 74.3 公克,而信賴區間大約是它的兩倍,會跟著一起縮。3.7 是最大組與最小組的人數比,它確實解釋了三根標準誤誤差線為什麼長度不同,但它不會讓標準差跟著變——三組的標準差幾乎一樣。至於「圖看起來更有說服力」這句話本身就值得警覺:讓組間看起來最分開的那一種誤差線,正好是最短的那一種。

素材來源與授權

回報內容問題

這個站的統計內容由 AI 撰寫、AI 互審,人工只做抽查。你看得出來的錯,我們不一定看得出來。

寫得越具體越修得動,例如哪一句話跟哪本教科書/哪篇論文的說法不一致。

留了才回得了信;不留也會看。

一併送出的資訊

這些是自動帶上的,每一項都可以取消。