个人向ggplot2箱线图总结

主要从如何看图、用图与作图三个方面来对箱线图进行理解和总结。

1、看图

箱线图概述图1
箱线图概述图2

如图所示,箱线图是将一组数据按照大小顺序排列后进行绘制的,包含6个数据节点,分别表示出数据的上边缘、上四分位数点Q3(数据从小到大排列后处在75%位置上的数据)、中位数、下四分位数Q1(数据从小到大排列后处在25%位置上的数据)、下边缘和异常值。由此,箱线图很形象地分为中心、延伸以及分布状态的全部范围。

异常值的筛选是根据数值与外限和内限的位置差异来进行的。内限即异常值截断点为Q3+1.5IQR和Q1-1.5IQR,外限为Q3+3IQR和Q1-3IQR。其中IQR=Q3-Q1,为四分位距。处在内限以外位置的点表示的数据都是异常值,其中在内限与外限之间的异常值为温和异常值,在外限以外的为极端异常值。软件绘图中一般不会标出内限和外限。

2、用图

2、1 可以用于反映数据的形状

除须以外,箱子包含了50%的数据,因此,箱子的宽度在一定程度上反映了数据的波动程度,箱子越扁说明数据越集中,须越短也说明数据越集中。

2、2 可以用于反映数据的偏态

中位数如果偏离上下四分位数的中心位置,分布的偏态性就越强。当中位数靠近上四分位点时,说明下四分位点与中位数之间的数据变化幅度大,中位数与上四分位点之间的数据变化幅度小;当中位数靠近下四分位点时,则反之。

2、3 可以用于表示数据的变化趋势或者进行数据之间比较

将多个箱线并行排列,可以看出数据整体的变化趋势。如下图中可以很明显的看出60天向100天过渡的过程中,长度的总体态势是逐渐增长的,但是113天却往下掉了。


boxplot of length.jpeg

同时也将几批数据的箱线图并行排列后,这几批数据的中位数、尾长、异常值和分布区间等信息一目了然,可以进行粗略的比较,如下图所示。


并行排列几批数据后绘制成的箱线图

2、4 可以用于体现与筛选数据的异常值

异常值的存在会对数据的计算分析过程产生影响,因此如果能体现与筛选异常值,分析其产生的原因,就可以发现问题并进而进行改进。识别异常值的经典方法中3σ法则和z分数法都是以数据服从正态分布为前提进行筛选的,而箱线图的绘制是依靠实际数据,不需事先假定数据服从的分布形式,同时因为四分位数具有一定的耐抗性,所以利用箱线图识别异常值的结果会比较客观。

以上部分参考自https://www.jianshu.com/p/5b3bec6d38ed

3、作图

箱线图的数据格式通常为两列,一列为类型变量,表示所属类别;一类为连续型数字变量,表示数值。通过这样的两列绘制出来的箱线图称为并列箱线图。而在某些情况中,需要绘制分组的箱线图进行比较,这样子就需要三个变量,即三列,包括两列类型变量和一列连续型的数字变量。


并列型箱线图

并列型箱线图的数据

分组型箱线图

分组型箱线图的数据

3、1 并列型箱线图作图

命令格式为

ggplot(表名,aes(x=表中列,y=表中列))+geom_boxplot(aes(fill=表中用于分类的列))

用fill分类完以后会自动填充颜色,当然fill=也可加具体颜色名或颜色代码用于统一填充颜色,若不加fill项,则会默认黑白色。

另一种格式是

ggplot(表名,aes(x=表中列,y=表中列,fill=用于分类的列))+geom_boxplt()

两种格式的效果是一样的。

3、2 分组型箱线图作图

因为并列箱线图中只有两列,所以其中一列必须同时是x轴(或y轴)和fill列,但是分组箱线图中有三列,所以其中一列为x轴,一列为y轴,一列为fill列,命令格式与并列箱线图相同。
当绘制过程中会出现类似下图的情况时


分面前

因为各组之间尺度相差过大而被拉扯,这种情况下需要用到facet函数进行分面。

facet_wrap(~分面所根据的变量,scales=“free”)
分面后

其中scales=“free”是使得分面后的各面有适应其图形的坐标。如果不加scales=“free”,则只是分面而不改变坐标轴。如下图所示:


无scales=“free”分面后

这种尺度过于拉大导致无法看图的情况其实在并列型箱线图中也存在,但是这种分面的方法更适用于分组型的箱线图。

当然也可以把同一组的分到一起

ggplot(xiang,aes(x=Organ_type,
                 y=Count,
                fill=Expression_level))+
  geom_boxplot()+
  facet_wrap(~Expression_level,scale="free")
同组同一颜色

3、3 自定义坐标轴排序

在箱线图绘制过程中,系统会对各列进行自动排序,有时候往往不是我们想要的顺序。如下图中,理想顺序是60、70、80、90、100、113、CK,但实际上顺序并不一样。


系统读取后的坐标轴排序

这种情况下需要使用命scale_x_discrete命令来进行调整。

scale_x_discrete(limits=c(“60”,“70”,“80”,“90”,“100”,“113”,“CK”))

同时也可以用这个命令摘出部分想要的子集。

scale_x_discrete(limits=c(“60”,“70”,“80”,“90”))

3、4 修改颜色

箱线图的绘制中需要调整各个箱线的颜色。
3.1中所绘制的箱线图是用填充色将分类所表现出来,而将3.1命令中的fill改成colour,即colour=表中用于分类的列,即可实现用边框色将分类表现出来。完整的命令为:

ggplot2(表名,aes(x=表中列,y=表中列))+geom_boxplot(aes(colour=表中用于分类的列),width=0.5)#width用于调整整个箱线的宽度

当然,fill和color也可以同时使用

ggplot(chang,aes(x=days,y=length,fill="orange",color="red"))+
  geom_boxplot(alpha=0.4)
color与fill同时调色后

用填充色将不同箱线图表现出来以后,若要调整填充色,可以使用RColorBrewer调色盘进行调色,需加上scale_fill_brewer()
如果不在括号中加入具体的某一调色盘的名称,默认为冷色调,如果想改成其他的颜色组合,应是

scale_fill_brewer(palette=“Set1”)

括号中的Set1是具体的该调色盘中的名称。调色盘还有以下几种:


调色盘

调色盘的颜色种类为8-12种,但是箱线图绘制过程中出现的箱线一般不会超过12个,所以对绘制并无太大影响。
同样地,若将命令中的fill改成colour也同样适用,只是调色盘的颜色会显示在边框上。
另外,如果想降低打印成本,可以使用灰度调色板,命令为

scale_fill_grey()

括号中可以填start或end,若start=1,则箱线颜色从左往右逐渐加深;若end=1,则箱线颜色从左往右逐渐变浅。start和end的取值范围皆为0-1。


使用灰度调色盘后

3、5 添加槽口

在geom_boxplot()括号中加入notch=TRUE即可在箱子上生成槽口,即

geom_boxplot(notch=TRUE,notchwidth=0.8)#notchwidth越小则越往里凹
添加槽口后

3、6 添加均值标记

箱线中的均值标记常以钻石来表示,所以命令为

stat_summary(fun.y=“mean”,geom=“point”,shape=23,size=3,fill=“white”)
添加均值标记后

3、7 添加最大值与最小值线

用基础R包绘图绘制的箱线图中具有最大最小值线(即概述图中的上边缘和下边缘),但是用ggplot2绘制的箱线图中,是没有最大最小值线的。


用基础R包绘制的箱线图

想要使ggplot2所绘制的箱线图带有最大最小值线,可用stat_boxplot命令,完整如下:

stat_boxplot(geom=“errorbar”,width=0.15,aes(color=用于分类的列))

其中aes是为最大最小值先添加颜色的,可以去掉,去掉即为黑色。

要注意的是,因为ggplot2的规则是图层叠加,所以如果是先作箱线图,即先输入geom_boxplot(),再输入stat_boxplot(),会导致箱线图中出现十字。


箱线上出现十字

所以输入命令时,必须先输入stat_boxplot(),再输入geom_boxplot()。
举例为

ggplot(changdu,aes(factor,long))+stat_boxplot(geom = "errorbar",width=0.15)+geom_boxplot(aes(fill=factor))

3、8 离群点(异常值)

关于离群点的参数有outlier开头的多个,如:
outlier.colour:离群点的颜色参数
outlier.fill:离群点的填充色参数
outlier.shape:离群点的形状参数
outlier.size:离群点的大小参数
outlier.alpha:离群点的透明度参数
使用时放在geom_boxplot中,如:

geom_boxplot(outlier.colour="red", outlier.shape=7,outlier.size=4)

3、9 将箱线图转置

添加

coord_flip()

即可。效果图如下:


转置后的箱线图

3、10 可变宽度

箱线图只能反映数据的整体态势,而不能反映数据的密度,但是如果数据密度越大,箱子的宽度也随之增大,则可在一定程度上了解数据的密度。
使用命令

geom_boxplot(varwidth = TRUE)

使宽度可随着数据密度成正相关变化

3、11 将散点在箱线中体现(1)

在箱线图中列出散点可以更直观地看出数据在箱线中的分布。有四种方法。
第一种方法是使用geom_point()将数据的散点图重叠在箱线图之上,但缺点是画出的散点只能排列在同一x坐标上,会导致重叠,观察不出数据的分布密度。

第二种方法是使用geom_dotplot。相比于第一种方法,geom_dotplot画出来的图较为分散美观且可以加入抖动参数。


geom_dotplot作图

命令如下例:

ggplot(chang,aes(x=days,y=length,color=days))+
  geom_boxplot()+
  geom_dotplot(binaxis = "y",
               stackdir = "center",
               position="jitter",
               dotsize = 0.4,)

dotplot的具体参数信息可以参考下面这个网址:
https://www.cnblogs.com/ljhdo/p/4886067.html

第三种方法,是使用ggpurb包进行作图。
命令如下:

ggboxplot(chang,
          x="days",
          y="length",
          color="days",
          palette = "jama",
          add = "jitter")
使用ggpurb作图

与dotplot对比可以看出,dotplot的散点只能随着箱线作图映射时fill或color进行颜色改变,fill则为填充色,color则为轮廓色,两者只能选择其一,不能同时变色,这也导致了dotplot作出的图中的散点与异常值点外观上有区别。
同时因为ggpurb是ggplot2的扩展包,所以它能实现以上许多功能,除了添加均值标记和自定义坐标轴顺序。

还有一种方法是使用geom_jitter体现出抖动的点,例如:

ggplot(chang,aes(x=days,y=length,fill=days))+
  geom_boxplot()+
scale_fill_viridis(discrete=T,alpha=0.6)+
  geom_jitter(color="black",size=0.89,alpha=0.9)+
  theme_ipsum_rc()
使用geom_jitter后

此方法完美兼容本文中其他命令且不用担心散点与异常值点的不协调不美观,因此推荐使用第四种方法。

3、11 将散点在箱线中体现(2)

可以使用ggExtra包中的ggMarginal()功能将箱线放在散点图的周围

p<-ggplot(mtcars,aes(x=wt,y=mpg))+geom_point()
p1<-ggMarginal(p,type = "boxplot",fill="slateblue",size=6)

ggMarginal中的fill与size都是设置散点图周围箱线的参数的。
效果图如下:


ggMarginal作图后

该方法不仅限于散点图和箱线图,也可用与直方图、箱线图、密度图与其他图的结合。

3、12 其他

关于其他一些基本的参数,如坐标轴名称,标题名称位置等,可用ggThemeAssist进行傻瓜式调整。具体见https://mp.weixin.qq.com/s/NWXvuTNAgjW3_EzT5J01Zw

4、总结的总结

下面是并列型箱线图包含上述内容的总命令,在实践中为求方便的话可以复制粘贴后再根据自己的需要进行删除和修改。

ggplt2(表名,aes(x=表中列,y=表中列))+
 stat_boxplot(geom = "errorbar",width=0.15)+
 geom_boxplot(aes(fill=表中用于分类的列),
               notch=TRUE,outlier.colour="red", outlier.shape=7,outlier.size=4)+
 scale_x_discrete(limits=c(“A”,“B”,“C”,“D”,“E”,“F”,“G”))+
 scale_fill_brewer(palette=“Set1”)+
 stat_summary(fun.y=“mean”,geom=“point”,shape=23,size=3,fill=“white”)+
 theme_bw()+theme(panel.border = element_blank(),panel.grid.major = element_blank(),
                   panel.grid.minor = element_blank(),
                   axis.line = element_line(colour = "black"))#使背景为空白并保留坐标轴为黑色

下面是分组型箱线图包含上述内容的总命令,在实践中为求方便的话可以复制粘贴后再根据自己的需要进行删除和修改。

ggplt2(表名,aes(x=表中列,y=表中列))
 stat_boxplot(geom = "errorbar",width=0.15)+
 geom_boxplot(aes(fill=表中用于分类的列),notch=TRUE,
                   outlier.colour="red", outlier.shape=7,outlier.size=4)+
 facet_wrap(~分面所根据的变量,scales=“free”)+
 scale_fill_brewer(palette=“Set1”)+
 stat_summary(fun.y=“mean”,geom=“point”,shape=23,size=3,fill=“white”)+
 theme_bw()+theme(panel.border = element_blank(),panel.grid.major = element_blank(),
                   panel.grid.minor = element_blank(),axis.line = element_line(colour = "black"))

如果想要尝试,可以从https://pan.baidu.com/s/1PQWiOGjSzdyVMTsa1sGwWA
中下载文件。

箱线图能够形象地体现数据的分布态势,但是在这同时,也会掩盖数据的密度分布,这也是箱线图的缺点所在。因此才有了小提琴图等。

这是对箱线图绘制过程的初步总结,包括了绘制简单箱线图的内容。添加显著性差异标识、均值点连线、和其他图联动等方面的内容以后会继续进行补充。

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

推荐阅读更多精彩内容