交流群有一个昵称是“今西”的小伙伴说他做了一个常规的转录组分析,实验和对照两个组,各三个样本。他的老师希望能把一个基因集里所有的基因(一个通路里面的,或者上下调最显著的基因列表)都做箱线图,表现在两个组中的表达情况。一个基因集中的基因往往超过十个,这次就不能像之前那样一个个的画图拼接,必须要用循环做图了。
但是循环的时候就报错了,他求助了他的师兄,发现问题就出在aes() 上,搜索到:
如下所示:
You need to explicitly print() the object returned by ggplot() in a for loop because auto-print()ing is turned off there (and a few other places).
You also need to use aes_string() in place of aes() because you aren't using i as the actual variable in filter(提问者的dataframe) but as a character string containing the variable (in turn) in filter to be plotted.
让我们来演示一下“今西”小伙伴遇到的问题:
df = as.data.frame(rbind(matrix(rnorm(260),nrow = 10),
matrix(rexp(260),nrow = 10)
))
colnames(df)=paste0('gene',LETTERS)
condition = rep(c('case','control'),each=10)
library(ggplot2)
gencounts = as.data.frame(cbind(condition,df))
gencounts[1:4,1:4]
如下所示:
> gencounts[1:4,1:4]
condition geneA geneB geneC
1 case -1.1783525 0.5862758 0.8885539
2 case 0.5305503 -0.2297670 0.1225264
3 case -1.9248160 1.7752445 -0.6351263
4 case 2.8276993 0.5792767 -1.6000259
总共是26个基因,它们都是在case 和 control两个分组需要看表达量差异,而且case 和 control两个分组内部都是10个病人。
# 任意一个基因绘图
ggplot(gencounts, aes (x=condition, y= geneY)) +
geom_boxplot(width=0.3,aes(fill=factor(condition)),show.legend = FALSE) +
theme_bw()
如下所示:
选取一个基因进行绘图
因为要写循环,对全部的基因批量绘图,所以“今西”小伙伴使用了如下所示的代码:
i =2
colnames(gencounts)[i]
# 不报错,但是绘图是失败的后面的aes_string的差异
# 这里需要着重强调 aes 和
if(T){
ggplot(gencounts, aes (x=condition, y= colnames(gencounts)[i])) +
geom_boxplot(width=0.3,aes(fill=factor(condition)),show.legend = FALSE) +
theme_bw()
}
然后就报错了,如果需要让上面的代码成功,需要做一个简单的修改, 就是ggplot的aes和aes_string的差异:
# 成功的绘图
ggplot(gencounts, aes_string (x='condition', y= colnames(gencounts)[i])) +
geom_boxplot(width=0.3,aes(fill=factor(condition)),show.legend = FALSE) +
theme_bw()
测试后,就可以批量绘图并且拼接啦;
pl = lapply(2:ncol(gencounts), function(i){
ggplot(gencounts, aes_string (x='condition', y= colnames(gencounts)[i])) +
geom_boxplot(width=0.3,aes(fill=factor(condition)),show.legend = FALSE) +
theme_bw()
})
#cowplot::plot_grid(plotlist = pl, align = "h", nrow = 4)
patchwork::wrap_plots(pl,byrow = T, nrow =7)
如下所示:
批量绘图并且拼接
当然了,这个箱线图还可以进一步美化, 比如添加统计学检验指标:
# 箱线图可以更加自定义,比如添加统计学显著指标
i =2
colnames(gencounts)[i]
ggplot(gencounts, aes_string (x='condition', y= gencounts[,i]) ) +
stat_boxplot(geom="errorbar",position=position_dodge(width=0.7),width=0.2,alpha=0.8,color="black") +
geom_boxplot(width=0.3,aes(fill=factor(condition)),show.legend = FALSE) +
theme_bw()+ labs(y="Expression Level") +
theme(panel.grid.major = element_blank(), #panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.line = element_line(colour = "black",size=1),
axis.title.y=element_text(size=14),axis.text.y=element_text(size=14),
axis.title.x=element_blank(),axis.text.x=element_text(size=14)
) +
ggsignif::geom_signif(comparisons = list(c( 'case','control' )),
map_signif_level=T,vjust=0.5,color="black",
textsize=5,test=t.test,step_increase=0.1) +
scale_fill_manual(values=c("RoyalBlue", "firebrick3")) +
ggtitle( colnames(gencounts)[i] )
如下所示:
添加统计学显著指标
如果你要从ggplot2开始一步步调制成为它这样的美图,需要下很深的功夫,一张统计图就是从数据到几何对象(点、线、条形等)的图形属性(颜色、形状、大小等)的一个映射。
前面我们介绍了绘图小白神包:
链接:https://ggplot2-book.org/facet.html
书名是:ggplot2: Elegant Graphics for Data Analysis 作者:Hadley Wickham
This is the online version of work-in-progress 3rd edition of “ggplot2: elegant graphics for data analysis”
虽然这本书有对应的中文译本,但是时间上相对滞后,建议直接看这个在线实时更新版本。
链接:https://ggplot2.tidyverse.org/reference/
链接:http://www.sthda.com/english/wiki/ggplot2-essentials
书籍本身提供售卖,价格是17欧元,不过内容都是电子化了,大家直接网页浏览,就是免费的哈!
链接:http://www.cookbook-r.com/Graphs/
这个有中文翻译版本,务必直接下单购买,放在书桌旁边随时翻阅。
你会发现,你想实现的各种稀奇古怪的绘图需求,只需要你能使用英文描述出来,就是能找到答案的!