ggbeeswarm 包画蜂群图:一种更优雅的画散点图的方法

【简说基因】蜂群图事实上也是一种散点图,不过比传统散点图和抖动散点图更加优雅,也比箱线图和小提琴图能够展示更多细节。

蜂群图(也称为柱形散点图或小提琴散点图)是一种绘制数据点的方式,通常情况下这些点会重叠在一起,蜂群图则将它们相邻排列。除了减少重叠,它还有助于可视化每个数据点的数据密度(类似于小提琴图),同时仍然显示每个数据点的具体数值。

画蜂群图的 R 包主要有:beeswarm 和 ggbeeswarm,本文介绍后者,它为画更好的散点图提供两个几何对象:

  • geom_quasirandom:准随机散点图几何对象。

  • geom_beeswarm:蜂群图几何对象。

安装

install.packages('ggbeeswarm')

示例

使用 iris 数据集,先比较一下抖动散点图和准随机散点图:

set.seed(12345)
library(ggplot2)
library(ggbeeswarm)
library(patchwork)
#compare to jitter
p1 = ggplot(iris,aes(Species, Sepal.Length)) + geom_jitter() + ggtitle("jitter")
p2 = ggplot(iris,aes(Species, Sepal.Length)) + geom_quasirandom() + ggtitle("quasirandom")
p1 / p2
3077cdc48258c038acedcebf2e640c2e.png

geom_quasirandom()

#default geom_quasirandom
ggplot(mpg,aes(class, hwy)) + geom_quasirandom()
b3f43ef35818169c256da2dcc2d62e1a.png
# With categorical y-axis
ggplot(mpg,aes(hwy, class)) + geom_quasirandom(groupOnX=FALSE)
eda5212aa3c3b0392ced88a6ced850c3.png
# Some groups may have only a few points. Use `varwidth=TRUE` to adjust width dynamically.
ggplot(mpg,aes(class, hwy)) + geom_quasirandom(varwidth = TRUE)
8e787c1af077b6cacfc370e58c523255.png
# Automatic dodging
sub_mpg <- mpg[mpg$class %in% c("midsize", "pickup", "suv"),]
ggplot(sub_mpg, aes(class, displ, color=factor(cyl))) + geom_quasirandom(dodge.width=1)
b6dc580b58c35d6035e8e6782f219a30.png

改变方法

geom_quasirandom 还有许多其他方法用于分布点,例如:

ggplot(iris, aes(Species, Sepal.Length)) + geom_quasirandom(method = "tukey") + ggtitle("Tukey texture")
096b590f4446131b6e7c68f4fced2837.png
ggplot(iris, aes(Species, Sepal.Length)) + geom_quasirandom(method = "tukeyDense") +
    ggtitle("Tukey + density")
2376652ad18bdd818d3a7a258de89334.png
ggplot(iris, aes(Species, Sepal.Length)) + geom_quasirandom(method = "frowney") +
    ggtitle("Banded frowns")
53e9482b75a6d68af622d491bb01be84.png
ggplot(iris, aes(Species, Sepal.Length)) + geom_quasirandom(method = "smiley") +
    ggtitle("Banded smiles")
92fac5f8155ba2c789df9a8d68859172.png
ggplot(iris, aes(Species, Sepal.Length)) + geom_quasirandom(method = "pseudorandom") +
    ggtitle("Jittered density")
fb93b132d3d0a960fa58b51f3fc83588.png

geom_beeswarm()

ggplot(iris, aes(Species, Sepal.Length)) + geom_beeswarm() + ggtitle("Beeswarm")
3616f6f27bfb0b42a302a7b7610a3b81.png
ggplot(iris,aes(Species, Sepal.Length)) + geom_beeswarm(side = 1L)
bb05c1822f4f7dae9de4fb0594366ad5.png
ggplot(mpg,aes(class, hwy)) + geom_beeswarm(size=.5)
e2dc47bef28f55a2234b15381a2f5711.png
# With categorical y-axis
ggplot(mpg,aes(hwy, class)) + geom_beeswarm(size=.5)
f3a832fbbec14ae07d36688bd9fd9af0.png
# Also watch out for points escaping from the plot with geom_beeswarm
ggplot(mpg,aes(hwy, class)) + geom_beeswarm(size=.5) + scale_y_discrete(expand=expansion(add=c(0.5,1)))
a0bf498d885ec48643941326af37c106.png
ggplot(mpg,aes(class, hwy)) + geom_beeswarm(size=1.1)
0e506182bebcdc7e1088a1caeab326bf.png
# With automatic dodging
ggplot(sub_mpg, aes(class, displ, color=factor(cyl))) + geom_beeswarm(dodge.width=0.5)
804024ba275366f34ac01d24b9484924.png

改变方法

df <- data.frame(
  x = "A",
  y = sample(1:100, 200, replace = TRUE)
)
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "swarm") + ggtitle('method = "swarm" (default)')
777e151b813697ccf3521742c7c37dfd.png
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "compactswarm") + ggtitle('method = "compactswarm"')
ba392e1dda799e4834c04d8f92bbb073.png
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "compactswarm") + ggtitle('method = "compactswarm"')
c13185651e539a3fa794a96e0ac49321.png
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "hex") + ggtitle('method = "hex"')
e3522eeb46256cde164c6487bc42924d.png
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "square") + ggtitle('method = "square"')
791e87062019d18e65d5a9de5d8457b0.png
ggplot(df, aes(x = x, y = y)) + geom_beeswarm(cex = 2.5, method = "center") + ggtitle('method = "center"')
44b782a9bfbfd5d1e36e0afd3a883772.png

点分布的优先级

#With different beeswarm point distribution priority
dat<-data.frame(x=rep(1:3,c(20,40,80)))
dat$y<-rnorm(nrow(dat),dat$x)
ggplot(dat,aes(x,y)) + geom_beeswarm(cex=2) + ggtitle('Default (ascending)') + scale_x_continuous(expand=expansion(add=c(0.5,.5)))
921725439860bf0a1c0a4b3d07da4eb3.png
ggplot(dat,aes(x,y)) + geom_beeswarm(cex=2,priority='descending') + ggtitle('Descending') + scale_x_continuous(expand=expansion(add=c(0.5,.5)))
ebf0cce7407ebbda4a28d9122fd3c21e.png
ggplot(dat,aes(x,y)) + geom_beeswarm(cex=2,priority='density') + ggtitle('Density') + scale_x_continuous(expand=expansion(add=c(0.5,.5)))
d2d5b04bca87bad7fc9bdafc50cc43c9.png
ggplot(dat,aes(x,y)) + geom_beeswarm(cex=2,priority='random') + ggtitle('Random') + scale_x_continuous(expand=expansion(add=c(0.5,.5)))
66181390b7c0be166568f68158b15a01.png

围捕逃逸点

set.seed(1995)
df2 <- data.frame(
  y = rnorm(1000),
  id = sample(c("G1", "G2", "G3"), size = 1000, replace = TRUE)
)
p <- ggplot(df2, aes(x = id, y = y, colour = id))

# use corral.width to control corral width
p + geom_beeswarm(cex = 2.5, corral = "none", corral.width = 0.9) + ggtitle('corral = "none" (default)')
9fed7f9cd5cac998773b674d68a787cf.png
p + geom_beeswarm(cex = 2.5, corral = "gutter", corral.width = 0.9) + ggtitle('corral = "gutter"')
089828924bd2bbaba16111877448d54e.png
p + geom_beeswarm(cex = 2.5, corral = "wrap", corral.width = 0.9) + ggtitle('corral = "wrap"')
7d79c416d6f12c33f514b8baf4dc4112.png
p + geom_beeswarm(cex = 2.5, corral = "random", corral.width = 0.9) + ggtitle('corral = "random"')
5b5d6d7c36c66abca4ef8af153786836.png
p + geom_beeswarm(cex = 2.5, corral = "omit", corral.width = 0.9) + ggtitle('corral = "omit"')
088f593ecfbbf33b130d533a88d88102.png

总结

蜂群图可以更好地展示数据点之间的关系,避免数据点的重叠,同时也可以进行分组和着色,方便进行数据的比较和分析。但是需要注意的是,由于数据点会在 x 轴上分散,因此其位置并不准确,需要根据具体情况进行分析和解释。

参考文献:

https://github.com/eclarke/ggbeeswarm



4521ca40264a7c6bf97eacdf45c877f1.png

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值