R 数据可视化 —— ggplot 箱线图和小提琴图

箱线图

箱线图用于展示 5 个统计量:最大值、最小值、中位数、第一分位数和第三分位数。

从箱线图中可以很容易的看出数据是否对称分布、以及是否包含离散数据,分布的离散程度。也可以用于比较不同变量的分布

示例

来个最简单的箱线图

p <- ggplot(mpg, aes(class, hwy))
p + geom_boxplot()

翻转方向

ggplot(mpg, aes(hwy, class)) + geom_boxplot()

设置凹槽

p + geom_boxplot(notch = TRUE)

凹槽的宽度可以通过 notchwidth 参数设置,默认为 0.5

p <- ggplot(mpg, aes(class, hwy))
p + geom_boxplot(notch = TRUE, notchwidth = 0.9)

默认情况下,每个箱子的宽度是一样的,我们可以设置 varwidth = TRUE,使得宽度与组内观测值的平方根成正比

p + geom_boxplot(varwidth = TRUE)

为箱子设置颜色

p + geom_boxplot(fill = "white", colour = "#3366FF")

geom_boxplot 函数中有专门的几个参数用于设置离散值的属性:

  • outlier.colour = NULL,
  • outlier.color = NULL,
  • outlier.fill = NULL,
  • outlier.shape = 19,
  • outlier.size = 1.5,
  • outlier.stroke = 0.5,
  • outlier.alpha = NULL,

例如

p + geom_boxplot(outlier.colour = "red", outlier.shape = 1)

设置透明度

p + geom_boxplot(outlier.fill = "blue", outlier.shape = 21, alpha = 0.5)

但是,当我们想要组合绘制箱线图和散点图时,可能需要将离散点删除

p + geom_boxplot(outlier.shape = NA) + geom_jitter(width = 0.2)

当我们绘制分组箱线图时,默认以并列的方式排列

p + geom_boxplot(aes(colour = drv))

而对于连续型 x 变量,需要指定分组。可以搭配 cut_width 使用

ggplot(diamonds, aes(carat, price)) +
  geom_boxplot(aes(group = cut_width(carat, 0.5)))

如果数据中已经计算过这些统计量,那么也可以将这些变量传递进去。

例如

tibble(
  x = rep(LETTERS[1:10], 10),
  y = rnorm(100)
) %>% group_by(x) %>%
  summarise(y0 = min(y), y25 = quantile(y, 0.25), y50 = median(y),
            y75 = quantile(y, 0.75), y100 = max(y)) %>%
  ggplot(aes(x)) +
  geom_boxplot(
    aes(ymin = y0, lower = y25, middle = y50, upper = y75, ymax = y100, 
        fill = x),
    stat = "identity"
  )

组合图形

  1. 添加均值标记点
ggplot(mpg, aes(class, hwy)) + 
  geom_boxplot(aes(fill = class)) +
  stat_summary(fun = "mean", fill = "white", size = 2, geom = "point", shape = 23) 
  1. 再添加误差线
ggplot(mpg, aes(class, hwy)) + 
  stat_boxplot(geom = "errorbar", width = 0.2) +
  geom_boxplot(aes(fill = class)) +
  stat_summary(fun = "mean", fill = "white", 
               size = 2, geom = "point", shape = 23)
  1. 为分组箱线图添加误差线
ggplot(mpg, aes(class, hwy)) + 
  stat_boxplot(aes(colour = drv), geom = "errorbar",
               position = position_dodge2(preserve = 'single', padding = 0.5)) +
  geom_boxplot(aes(fill = drv), position = position_dodge2(preserve = 'single'))

注意:由于每种类型的分组并不是都存在,所以会出现箱线图宽度不一致的情况,所以设置了 preserve = 'single'

同时,在添加分组误差线时,需要指定分组 colour = drv

  1. 定制箱线图
# 先绘制一个虚线箱线图
p1 <- ggplot(mpg, aes(class, hwy)) + 
  geom_boxplot(linetype = 'dashed', outlier.colour = "red")
# 再绘制带颜色的中心矩形,覆盖原来的矩形
p2 <- p1 +
  stat_boxplot(aes(ymin = after_stat(lower), ymax = after_stat(upper),
                   fill = class)) 
# 设置上误差线,误差线的最小值设置为数据最大值
p3 <- p2 +
  stat_boxplot(aes(ymin = after_stat(ymax)), geom = "errorbar", 
               width = 0.2, colour = "#4daf4a")
# 设置下误差线
p3 + 
  stat_boxplot(aes(ymax = after_stat(ymin)), geom = "errorbar",
               width = 0.2, colour = "#377eb8")

plot_grid(p1, p2, p3, p4)

小提琴图

小提琴图用于显示数据的分布状态和概率密度,它同时具有箱线图和密度图的特征,用于显示数据的分布形状。

示例

来个最简单的例子

p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_violin()

更改方向

ggplot(mtcars, aes(mpg, factor(cyl))) +
  geom_violin()

可以通过设置 scale 参数的值来更改图像大小,支持三个参数值:

  • area:默认,保持所有图形大小一样
  • count:设置最大宽度与样本大小成正比
  • width:所有图形的最大宽度一样
p + geom_violin(scale = "count")

默认情况下,会删除图形的尾部数据,如果不想删除可以设置 trim = FALSE

p + geom_violin(trim = FALSE)

设置更小的 bandwidth(adjust) 来绘制更近似的拟合,默认为 1

p + geom_violin(adjust = .5)

分组小提琴图也是并列的方式排列

p <- ggplot(mtcars, aes(factor(cyl), mpg))

p1 <- p + geom_violin(aes(fill = cyl))

p2 <- p + geom_violin(aes(fill = factor(cyl)))

p3 <- p + geom_violin(aes(fill = factor(vs)))

p4 <- p + geom_violin(aes(fill = factor(am)))

plot_grid(p1, p2, p3, p4)

显示分位数线

p + geom_violin(draw_quantiles = c(0.25, 0.5, 0.75))

组合图形

  1. 添加中值点
ggplot(mpg, aes(class, displ)) + 
  geom_violin(aes(fill = class), show.legend = FALSE) +
  stat_summary(fun = median, geom = "point", shape = 23,
               size = 2, fill = "white")
  1. 添加均值和标准差
ggplot(mpg, aes(class, displ)) + 
  geom_violin(aes(fill = class), show.legend = FALSE) +
  stat_summary(fun.data = "mean_sdl", fun.args = list(mult = 1),
               colour = "white")

注意:如果在运行上述代码报错了

Hmisc package required for this function

需要安装一下 Hmisc,因为 mean_sdl 函数来自 Hmisc

install.packages("Hmisc")
  1. 添加箱线图
ggplot(mpg, aes(class, displ)) + 
  geom_violin(aes(fill = class), show.legend = FALSE) +
  geom_boxplot(width = 0.1)
  1. 添加抖动散点图
ggplot(mpg, aes(class, displ)) + 
  geom_violin(aes(fill = class), show.legend = FALSE) +
  geom_jitter(width = 0.1)
  1. 转换为极坐标
ggplot(mpg, aes(class, displ)) + 
  geom_violin(aes(fill = class), show.legend = FALSE) +
  geom_boxplot(width = 0.1) +
  coord_polar()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容