ggplot2 - 箱线图(Box - plot)

简介

箱线图,顾明思义,是形状像箱子并展示一组或多组数据分布的统计图,被认为是一个优于柱形图的数据可视化方案,文章中指出了很多箱线图的优点。
在ggplot2 中做箱线图的图形变换是geom_boxplot(),小提琴图是geom_violin。
可识别的美学映射?(geom_boxplot):

  • x

  • lower

  • upper

  • middle

  • ymin

  • ymax

  • alpha

  • colour

  • fill

  • group

  • linetype

  • shape

  • size

  • weight
    详情参见vignette("ggplot2-specs"),直接在R中运行即可阅读。

箱线图(包含其变体小提琴图、Bean-plot)可以更真实的反应数据的分布,并且可以更轻松地在三个或更多样本之间进行比较。它使用25%,第50%和75%以及四分位数范围(IQR = Q3-Q1)来表征样本,其结果覆盖了中心数据的50%。 而且四分位数对异常值不敏感,并保留有关中心和差值的信息,加上异常值(outliers)的体现,使箱形图的内容更丰富。如果加上散点则可以更好的体现样品数,点越多,结果的稳定性、可靠性越好;而小提琴图(Violin plot)还可以通过箱体的宽窄在箱形图的基础上展示出数据分布的概率密度。

1. 简单箱线图

library(ggplot2)
ggplot(data = ToothGrowth) + geom_boxplot(aes(x = supp, y = len))
boxplot.png

细节说明

  1. 首先看箱体:下边线代表下四分位数(第一四分位数,Q1),表示整体数据中有25%的数据少于该值;上边线代表上四分位数(第三四分位数,Q3),表示整体数据中有75%的数据少于该值;

  2. 箱体中间的线代表中位数,是一组数从小到大排列,居于正中间的单个数或正中间两个数的均值;

  3. 箱体的长度代表第三四分位数和第一四分位数的差值,也称为四分位间距(interquartile range,IQR);

  4. 箱体两端的衍生线最左延伸至Q1 - 1.5 x IQR(下极限),最右延伸至 Q3 + 1.5 x IQR(上极限);

  5. 超出上下极限线的点(或其他标记)表示潜在异常值(outliers)。

2. 水平箱线图

和其他图形一样,如果x轴上的label过长,一方面字体重叠影响阅读,另一方面旋转后破坏了图片中文字的一致性,显得不是很美观,最好就是生成水平箱线图。
在原图的基础上,加上坐标轴旋转参数coord_flip()就可以了。

3. 分组

简单分组(fill, color)

在aes()里面添加fill 或者 color 参数。

ggplot(data = ToothGrowth) + geom_boxplot(aes(x = supp, y = len, 
fill = factor(dose)))
boxplot.png

3.箱线图与抖动图

加上散点则可以更好的体现样品数,点越多,结果的稳定性、可靠性越好。

ggplot(data = ToothGrowth) + geom_boxplot(aes(x = supp, y = len)) + 
  geom_jitter(aes(x = supp, y = len))
boxplot.png

散点分组

当散点图也需要分组时,如果直接添加fill 和 color 就不够了,ggplot2 函数会分组混乱。

ggplot(data = ToothGrowth) + 
  geom_boxplot(aes(x = supp, y = len, color = factor(dose))) + 
  geom_jitter(aes(x = supp, y = len, color = factor(dose)))
boxplot.png

解决办法

a. position_jitterdodge

ggplot(data = ToothGrowth) + 
  geom_boxplot(aes(x = supp, y = len, color = factor(dose))) + 
  geom_jitter(aes(x = supp, y = len, color = factor(dose)), 
              position = position_jitterdodge())
boxplot.png

其他有趣的解法

b. 产生一个新的分组变量,使其同时包含两个分组信息。
在数据集中创建一个新的变量supp_dose,其值是将supp 和 dose粘贴到一起,这样新的一列数据就包含了两种分组信息。

 ToothGrowth$supp_dose <-  paste(ToothGrowth$supp, ToothGrowth$dose, sep="_")
# 然后以新的分组信息为x轴,代码不变。
 ggplot(data = ToothGrowth) + 
  geom_boxplot(aes(x = supp_dose, y = len, color = factor(dose))) + 
  geom_jitter(aes(x = supp_dose, y = len, color = factor(dose)))
boxplot.png

c. Interaction函数
b. 确实解决了上述问题,但坐标轴居然有6个,毕竟我们产生的新坐标系统确实包括6个不同的chr,interaction()base{}通过计算因子间关系产生可新的变量,可以

d. 移动所有点的坐标。

  1. 分组变量可以通过as.numeric()转化为连续数字变量:1,2,3,4,5,这样就生成了箱线图在x轴上的坐标。
as.numeric(factor(ToothGrowth$supp))
  1. 在此基础上,按照另一个分组变量获得一个索引。然后对每一组进行增加或者减少值,生成散点的x轴坐标。
as.numeric(factor(ToothGrowth$dose))
ToothGrowth$xpos <- as.numeric(factor(ToothGrowth$supp)) + c(- 0.25, 0, 0.25)[as.numeric(factor(ToothGrowth$dose))]
  1. 箱形图x坐标不变,散点图x坐标平移。
ggplot(data = ToothGrowth) + 
  geom_boxplot(aes(x = supp, y = len, color = factor(dose))) + 
  geom_jitter(aes(x = xpos, y = len, color = factor(dose)))
boxplot.png

4.小提琴图(Violin plot)

image.png

5. raincloud = violin plot + boxplot + raw data

云雨图开始是一个咨询问答产物,连接直达源代码;yyplot里面有封装好的包。但是,有时候下载这个包可能会遇到安装不上的情况,所以没法下载的可以去问答界面拿源码自己打包一下。

箱线图离群值标签

return_outliers <- function(data, key){
  p1 <- ggplot(data = data) + geom_boxplot(aes_string(y = key)) 

  box_min <- ggplot_build(p1)[["data"]][[1]][["ymin"]]
  box_max <- ggplot_build(p1)[["data"]][[1]][["ymax"]]
  
  # selectting outliers
  outliers <- subset(data, data[[key]] < box_min | data[[key]] > box_max)
  return(outliers)
}


outliers <- return_outliers(mtcars, "mpg")


ggplot() + geom_boxplot(aes(y = mpg), outlier.colour = "red", data = mtcars) + 
  ggrepel::geom_label_repel(aes(x = 0, y = mpg, label = rownames(outliers)), 
                            data = outliers)
image.png

内限和外限

https://www.jianshu.com/p/1f6bbd9550c0

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

推荐阅读更多精彩内容