生物学に限らず、様々な分野の科学論文において、私たちは箱ひげ図を目にすると思います。箱ひげ図は主に群間におけるデータの分布を可視化するために用いられますが、いくつかの致命的な欠点を抱えています。そのため、箱ひげ図を使う際は、特にデータの分布について注意を払う必要があります。しかしながら、非意図的なのかあえてなのか分かりませんが、箱ひげ図を使った不適切な可視化をしている論文が次から次へと出版されています。ここでは、以下に示す箱ひげ図の欠点を補ったプロット方法を紹介します。不適切な箱ひげ図がなくなりますように・・・!
よりよい方法があればご教示いただければ幸いです。
環境
R version 4.3.1
ggplot2 3.4.2
箱ひげ図の主要な欠点
- サンプルサイズが分からない
- データの分布に関する情報が失われる
詳しくは以下のサイトを参照してください。
ベーシックな箱ひげ図
irisデータセットを使って、まずは普通にプロットしてみます。
library(tidyverse)
library(viridis)
plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length))+
geom_boxplot(width = 0.5, color = "black", alpha=0.7)+
theme_bw(base_size = 12)+
labs(title="Sepal.Length")+
theme(legend.position="none")
シンプルできれいな図ですが、サンプル数やデータの分布の情報は完全に欠落しています。そういった情報も残した可視化をしたいところです。
今回提案する箱ひげ図
を描くコードがこちら。
plot2 <- ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species))+
geom_violin(alpha = 0.6)+
scale_fill_viridis(option = "D", discrete = T)+
geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
position = position_nudge(-0.05))+
geom_boxplot(width = 0.1, color = "black", alpha=0.7,
position = position_nudge(+0.05))+
theme_bw(base_size = 10)+
labs(title="Sepal.Length")+
#labs(x = NULL, y = NULL)+
theme(legend.position="none")
サンプルサイズとデータの分布の情報が失われていない&それらが視覚的に分かりやすい理想的な図!
サンプルサイズの表示を追加してみる
どうせならサンプル数がいくつなのか示せれば、さらに親切ですね。
samplesize <- iris %>%
group_by(Species) %>%
tally()
まずはサンプルサイズを取得します。
plot3 <- ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species))+
geom_violin(alpha = 0.6)+
scale_fill_viridis(option = "D", discrete = "True")+
geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
binwidth = 0.1, position = position_nudge(-0.05))+
geom_boxplot(width = 0.1, color = "black", alpha=0.7,
position = position_nudge(+0.05))+
theme_bw(base_size = 12)+
labs(title="Sepal.Length")+
#labs(x = NULL, y = NULL)+
theme(legend.position="none")+
geom_text(data = samplesize,
aes(Species, Inf, label = paste0("n = ", n)),
vjust = 1.25, size=3, color="black") #サンプルサイズの書き込み
ちょっときついですが、スペースを調整すればいい感じになりそう。
X軸にサンプル数を表示したい場合は以下を参照してください。
Violin plot with included boxplot and sample size in ggplot2
おまけ
The R Graph Galleryにある箱ひげ図が苦手そうなデータでも図示してみます。
data <- data.frame(
name=c(rep("A",500), rep("B",500), rep("B",500), rep("C",20), rep('D', 100)),
value=c(rnorm(500, 10, 5), rnorm(500, 13, 1), rnorm(500, 18, 1), rnorm(20, 25, 4), rnorm(100, 12, 1))
)
# 引用: https://r-graph-gallery.com/89-box-and-scatter-plot-with-ggplot2.html
plot4 <- ggplot(data, aes(x = name, y = value, fill = name))+
geom_violin(alpha = 0.6)+
scale_fill_viridis(option = "D", discrete = "True")+
geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
binwidth = 0.25, position = position_nudge(-0.05))+
geom_boxplot(width = 0.1, color = "black", alpha=0.7,
position = position_nudge(+0.05))+
theme_bw(base_size = 12)+
labs(title="data")+
theme(legend.position="none")
オオン・・・。
サンプル数が多いときはドットプロットよりジッタープロットの方がいいかもしれませんね。
最後に
当たり前ですが、今回紹介したプロットはあらゆるデータに適合するわけではありません。データの分布や数によって、最適な可視化方法を探索していきましょう!