データを可視化するときにいくつかの方法があります。その一つがバイオリンプロットです。
バイオリンプロットは複数のデータを比較する時に便利な方法です。バイオリンプロットを書いているだけで、「この人出来る」というような印象があるかもしれません。是非チャンスがあれば使ってみてください。
それでは書き方にいきます。ついでにドットプロットでデータの分布を確認してみます。
データ生成と分布の確認
データを作ってみます。自分のデータがある場合にはそちらを使ってみてください。
#作業ディレクトリのセットとtidyverse、ggbeeswarmの起動
#ggbeeswarmはドットプロットを描くためです
setwd("~/Rpractice/")
library(tidyverse)
library(ggbeeswarm)
#データを生成します
dat <- list(
X <- rnorm(100, 5, 10),
Y <- rnorm(100, 20, 10),
Z <- rnorm(100, 15, 15)
)
#データを整えます
#単に使いやすいデータの形にするだけです
df <- data.frame(matrix(unlist(dat), nrow=100))
colnames(df) <- c("A","B","C")
df.long <- pivot_longer(df, cols = A:C, names_to = "Categories", values_to = "Values")
#ドットプロットです
ggplot(df.long, aes(x = Categories, y = Values))+
geom_beeswarm(aes(color = Categories),
size = 2,
cex = 2,
alpha = .8)+
theme_classic()+
theme(legend.position = "none")
ドットプロット、ggbeeswarmについてはこちらからどうぞ。またデータをpivot_longerで縦長に変換しています。
それでは、バイオリンプロットを描いていきましょう!
バイオリンプロットを描く
ggplot2でバイオリンプロットはgeom_violin()を使います!
theme_classic()で背景を白くします。
ggplot(df.long, aes(x = Categories, y = Values))+
geom_violin()+
theme_classic()
これがバイオリンプロットの基本形になります。バイオリンプロットの両端が切れていますね。この上にドットプロットを重ねてみると、その答えがわかります。
ggplot(df.long, aes(x = Categories, y = Values))+
geom_violin()+
geom_beeswarm(aes(color = Categories),
size = 2,
cex = 2,
alpha = .8)+
theme_classic()
このバイオリンプロットの両端は最大値と最小値でカットされていることがわかります。これをカットしないのはgeom_violin(trim = FALSE)で指定します。
ドットプロットも重ねてみます。
ggplot(df.long, aes(x = Categories, y = Values))+
geom_violin(trim = FALSE)+
geom_beeswarm(aes(color = Categories),
size = 2,
cex = 2,
alpha = .8)+
theme_classic()
このように点のないところまで上下に伸びますので要注意です。
バイオリンに色をつける
バイオリンに色を付ける場合、枠に色をつけるか、中を塗りつぶすかで指定の仕方を変えます。
枠に色を付ける
枠に色をつけるのはcolorで指定します。
ggplot(df.long, aes(x = Categories, y = Values, color = Categories))+
geom_violin()+
theme_classic()
重ね合わせの時にバイオリンだけ色をつけたい、などでcolorをgeom_violinのaesで指定もできます。
ggplot(df.long, aes(x = Categories, y = Values))+
geom_violin(aes(color = Categories))+
theme_classic()
出てくる図は上と同じです。慣れた人には当たり前なんですが、初心者のうちは意外に迷うものです。
バイオリンの中に色を塗る
バイオリンの中を塗りつぶす時には、fillを使います。
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin()+
theme_classic()
色を変えるときにはいくつか方法があります。今回はscale_fill_brewerで指定をしてみます。
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin()+
scale_fill_brewer(palette = "Set2")+
theme_classic()
平均値や中央値を入れる
バイオリンプロットに平均値や中央値を入れるのは、stat_summaryを使います。
平均値をマークする
平均値をマークしてみましょう。
ggplot(df.long, aes(x = Categories, y = Values, color = Categories))+
geom_violin()+
stat_summary(fun = mean, geom = "point",
shape =16, size = 2, color = "red")+
theme_classic()
平均値を赤い点にしました。stat_summary()の中のshapeとcolorで形と色を指定をしています。
stat_summaryのshapeはpchと同じです。
数値に対応する図形はこのようになっています!
中央値をマークする
今度は中央値です。
ボックスプロットを重ねれば必ずしも必要ないかもしれませんが、先程と同じようにstat_summaryを使うことができます。shapeで十字マーク(shape = 3)にしています。
ggplot(df.long, aes(x = Categories, y = Values, color = Categories))+
geom_violin()+
stat_summary(fun = median, geom = "point",
shape = 3, size = 2, color = "red")+
theme_classic()
平滑化の度合いを変更する
平滑化の度合いを変更したいときにはgeom_violinの中でadjustを指定します。
デフォルトはadjust = 1です。
まずはadjustの値を小さくしてみます。adjustを0.2にしてみましょう!
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin(adjust = .2)+
theme_classic()
細かい並々がたくさんできました。反対にadjustを大きくしてみます。
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin(adjust = 2)+
theme_classic()
今度は赤の群にあったくびれがなくなってしまいました。
ボックスプロットと重ね合わせる
ボックスプロットとの重ね合わせはよく使われます。
ボックスプロットを重ねることでその威力を発揮します。
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin()+
geom_boxplot(width = .1, fill = "white")+
theme_classic()
外れ値を表示しないようにするにはoutlier.color = NAを指定します。
ggplot(df.long, aes(x = Categories, y = Values, fill = Categories))+
geom_violin()+
geom_boxplot(width = .1, fill = "white", outlier.color = NA)+
theme_classic()
ボックスプロットを黒く塗って、中央値を白丸にする方法です。白黒印刷物に投稿する場合は役に立ちます。
ggplot(df.long, aes(x = Categories, y = Values))+
geom_violin()+
geom_boxplot(width = .1, fill = "black", outlier.color = NA) +
stat_summary(fun = median, geom = "point", fill = "white", shape = 21, size = 3) +
theme_classic()
これでバイオリンプロットも描けると思います。お役に立ちましたら幸いです。