(翻)云(覆)雨图
《(翻)云(覆)雨图》这篇文章在2018年11月推送,当时并没有R包可以画这个半边的小提琴图,我在gglayer
包里打包了geom_flat_violin
的图层,代码来自于David Robinson,最近发现CRAN上有一个新的包,gghalves
,这个包实现了一半的小提琴图、箱式图和点图:
geom_half_boxplot geom_half_violin geom_half_point
于是像诸如一半箱式图,再加原始数据点之类的图,轻而易举:
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_half_boxplot(width=.3) +
geom_half_point(aes(color=Species))
于是更新此贴,使用gghalves
来画,而原先geom_flat_violin
也将从gglayer
包中删掉。gghalves
包在CRAN中,可以通过install.packages("gghalves")
来安装。
生物狗喜欢画barplot,但毕竟只有均值和标准误差信息量太低,万一有outliers呢?万一不是正态分布呢?所以就吐槽了又吐槽,但大家还是乐此不疲,因为大家都在用,因为很多人只会画barplot,所以产生各种反barplot运动,并呼吁大家使用boxplot,boxplot有四分位数的统计量,可以反应outlier和数据的分布,比barplot高得多了。
然而事情是不断在进化的,我们的手段是要跟上潮流的,现在的潮流就是除了要有统计量,还要有原始数据,甚至于有统计推断,全集中一图中,揭开数据的红盖头,给大家呈现全方位无死角的面貌。
所以现在流行的不单单是画boxplot,有以下几种方式是显得比较专业的:
boxplot + raw data
violin plot + boxplot
violin plot + raw data
violin plot + boxplot + raw data
反正就是原始数据+统计量(boxplot)+统计推断(violin plot, 概率密度)的组合。然而violin画出来是对称的,也就是说信息冗余,就有人提出来,能不能画一半的violin,但其实一半也挺丑的,但大家脑洞足够大,把violin往右移一点,它就像一朵云彩,而raw data就像是雨滴,于是乎云雨图(raincloud)应运而生,一下子俘获大家的芳心,包括我。
就这一个可视化方式,有人专门写文章介绍,并且还用主流语言实现了,https://peerj.com/preprints/27137v1/。
《ggridges:一种波涛汹涌,哦不对,是山峰叠峦的可视化方式》本身长得就像半个violin,这个包现在也支持raincloud,不过我还是喜欢单一的元素然后自己拼。
那么要实现这个图,最大的问题在于需要一半的violin,在这里,我要介绍的就是画一半图层的gghalves包。
violin + boxplot + raw data
require(ggplot2)
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_violin(alpha=.5) +
geom_boxplot(width=.1) +
geom_jitter()
统计量不一定要用boxplot来展示四分位数,你也可以是均值+-标准误差的方式,这样相当于你把barplot的信息也放进去了,所以说单纯barplot有多弱鸡。当然统计量也不限于此,有合适的都可以放进去。无非是拼图层,这也是图形语法的灵活所在,封装失去了自由组合的灵活性。
require(dplyr)
d <- group_by(iris, Species) %>%
summarize(mean = mean(Petal.Length),
sd = sd(Petal.Length))
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_violin(alpha=.5) +
geom_jitter() +
geom_pointrange(aes(y=mean, ymin=mean-sd, ymax=mean+sd, color=Species), data=d, size=2)
云雨图1:加上均值和标准误差
library(gghalves)
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_half_violin(position=position_nudge(x=.2), side=2) +
geom_jitter(aes(color=Species), width=.15) +
geom_pointrange(aes(y=mean, ymin=mean-sd, ymax=mean+sd),
data=d, size=1, position=position_nudge(x=.25)) +
coord_flip() + theme_bw() +
theme(legend.position="bottom")
云雨图2:加上boxplot
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_half_violin(position=position_nudge(x=.3), side=2) +
geom_jitter(aes(color=Species), width=.15) +
geom_boxplot(width=.1, position=position_nudge(x=.22)) +
coord_flip() + theme_bw() +
theme(legend.position="bottom")
云雨图3:用堆叠的点图当雨点
ggplot(iris, aes(Species, Petal.Length, fill=Species)) +
geom_half_violin(position=position_nudge(x=.2), side=2) +
geom_dotplot(binaxis="y", stackdir="down", dotsize=.35) +
geom_boxplot(width=.1, position=position_nudge(x=.1)) +
coord_flip() + theme_bw() +
theme(legend.position="bottom")
往期精彩