当前位置: 涵芬教育 > mg游戏 > 正文

教程 | 如何用ggplot2绘制y轴断裂的统计图

2018-09-03 08:40 2

有时候我们会遇到一些很特别的数据,其中某些数值变化特别大,而有的数值变化特别小。而如果把它们都放在同一个线性的坐标轴里面画图,只有那些变化特别大的能够在视觉上体现出来,而那些变化小的,看起来就跟没变化的一样了。

比如我们现在有这样实验:过表达基因A,并考察对基因B~E表达量的影响。通过qPCR实验,我们获得了这样一组数据:

我们先用常规的方法给画个图:

我们会发现,基因D和E本来有2倍的变化,但是因为y轴被基因A的变化给拉得特别大(毕竟是过表达A基因),因此体现不出来。

假设我们把坐标轴弄成log10坐标:

这时候,虽然变化开始体现出来了,但是,log坐标对许多读者来说不够直观。

在一些软件中,比如GraphPad,原生支持绘制断裂的坐标轴(axis break),省略坐标轴中间许多空白的区域,从而将这类数据完美展示出来。比如下面这个例子,就是展示[0,4],然后省略y轴中间的部分,再继续展示[100,200]的部分。

但如果想用ggplot2来做,应该怎么办呢?有没有原生支持的函数呢?

其实这是个老问题,很多人都在google forum或者gayhub(雾——)上request这个feature,然而ggplot2的作者Hadley Wickham如是说:支持是不可能支持的,这辈子都不可能支持的……

难道就没有办法了吗?非也,我们只需要动动脑筋就可以了。具体的实现思路是:绘制两个坐标轴不一样的图,然后再把它们上下叠起来!

我们先对数据进行走流程的简单处理,求均数、标准差、标准误:

library(plyr)

mydata

mydata.tidy

然后开始绘制第一个图:

library(ggplot2)

library(cowplot)

myplot1

? geom_point(data = mydata, aes(x = Gene, y = Relative.Exp, color = Group), position = position_jitterdodge(0.7), alpha = 1, size = 5) +

? geom_errorbar(aes(ymin = mean-sd, ymax = mean+sd), width = .2, size = 1, position = position_dodge(0.7)) +

? scale_y_continuous(expand = c(0,0), limits = c(0, 4)) +

? labs(x = "", y = "") +

? geom_hline(yintercept = 4, size = 1, linetype="dashed")

myplot1

? legend.text = element_text(size = 26, face = "bold"),

? legend.key.height = unit(2, "line"),

? legend.key=element_blank(),

? legend.title = element_blank(),

? axis.text = element_text(size = 26, face = "bold", colour = "black"),

? panel.grid.major.x =? element_line(colour = "grey95"),

? panel.grid.minor = element_blank(),

? axis.line.x = element_line(size = 1),

? axis.ticks.x = element_line(size = 1),

? axis.line.y = element_line(size = 1),

? axis.ticks.y = element_line(size = 1)

)

myplot1

这样我们就会得到第一张图。我们发现,这就是之前那张图的下半部分。(注意,geom_point和geom_errorbar用的是不同套dataframe。点图用的是原始数据,errorbar是我们通过summaries函数算出来的统计量。)

这一部分最重要的代码是scale_y_continuous(expand = c(0,0), limits = c(0, 4)),也就是说,将y坐标设为[0,4]。

同时,我们还在y=4这个位置,加了一条虚线:geom_hline(yintercept = 4, size = 1, linetype="dashed")

由于基因A的3个蓝色数据点超出范围,因此并没有显示出来。

注意,我这里同时加载了cowplot这个包,它是一个ggplot2的插件,可以自动帮我们生成满足论文发表风格的图,比如默认去掉了丑丑的灰色背景。同时它还有一个很大的用途,后面说。

我们用一模一样的代码,绘制另一部分。但是,我们将y轴设为[100,200],虚线的位置也改一改:

scale_y_continuous(expand = c(0,0), limits = c(100, 200))

geom_hline(yintercept = 100, size = 1, linetype="dashed")

同时,在theme里面,把x轴所有元素给去掉:

? axis.line.x = element_blank()

? axis.ticks.x = element_blank()

? axis.text.x = element_blank()

(对了,记得把图片的名字也换掉,比如叫myplot2,别把myplot1给覆盖掉了)

然后,我们再通过cowplot里面自带的排版函数,把这两个图给上下叠起来(比ggplot2原生的facet好用多了):

plot_grid(myplot2, myplot1, ncol = 1, align = "v")

大功告…………桥多麻袋!!!那两个legend怎么办???

这里有两个办法,我们可以通过代码消掉一个(自己想……很简单),或者illustrator魔改一下就好了。

ggsave(filename = "sample.pdf", device = "pdf", useDingbats = FALSE)

是不是so easy?

(Tips 1:本文介绍的方法,只适用于dotplot,而如果是柱状图或者其他类型的,则没办法做到。因为底部的那个超出范围的柱子,是完全不画出来的,而不是画一截。除非自己写个判断函数,将dataframe里面所有超过一定范围的数值,都改成固定数值再画图。但太折腾了,宝宝不干。)

(Tips 2:如果你不想用ggplot2,还有一个包叫做plotrix,原生支持这种断裂坐标轴。不过我个人还是习惯ggplot2,稍微动动手就可以达到同样的效果了。)

全套代码以及示例数据文件,

均可在MG电子游艺星球【生物狗窝】中获取!

入窝需注明专业或领域,

非生物医学专业的学生或从业者勿扰。

欢迎 发表评论:

Copyright ? 2018 涵芬教育
友情链接:顶级娱乐城>