0.写在前面
从我学生信开始,画热图用的就是pheatmap,有时复杂化的需求会用到ComplexHeatmap。作为R语言画图的绝对霸主,ggplot2的热图却无法在热图的世界占到与pheatmap相匹敌的地位。硬伤有二:
- 不会聚类
- 没有直观的分组注释条条
这个函数+推文,我从晚上11:05写到了凌晨两点,原计划是12点钱发出去,想写完整详细版代码,后来觉得有点麻烦,细节太多。所以我把它写成了函数,工作量翻了几倍,但是以后直接使用就好啦,虽然没来得及昨天更推文,但是很值得!好久没有熬夜了,为了这个小突破,任性一次也没关系的!注意,这个函数是1.3.4以上版本的tinyarray可用o。
但当我想用patchwork将pheatmap与点图放到一起的时候,找到了解决办法,as.ggplot将pheatmap转换为ggplot2对象。后来,就发现了pheatmap的拼图硬伤,图例无法收集,大小也不能像ggplot一样自动匹配对齐。
所以我就想,如果我非要用ggplot2来画热图呢?注释条条要,聚类也可以要,有没有办法实现呢?
本文部分借鉴了CRAN的R包ggrisk的思维,就是做一个假的注释条条,然后和热图按比例拼到一起!
至于聚类,借鉴了豆豆的思维,只实现聚类的操作,不显示聚类树。
1. 数据和R包准备
#devtools::install_github("xjsun1221/tinyarray")
library(tinyarray)
library(ggplot2)
library(patchwork)
输入数据是一个表达矩阵(exp_dat)和分组信息(group),分组信息要整理成因子,水平(levels)设置对照组在前,实验组在后。因子正文顺序无所谓。
rm(list = ls())
exp_dat = matrix(sample(100:1000,40),ncol = 4)
exp_dat[seq(1,(nrow(exp_dat)),2),] = exp_dat[seq(1,(nrow(exp_dat)),2),]-1000
rownames(exp_dat) = paste0("sample",1:nrow(exp_dat))
colnames(exp_dat) = paste0("gene",1:ncol(exp_dat))
exp_dat[1:4,1:4]
## gene1 gene2 gene3 gene4
## sample1 -808 -424 -496 -104
## sample2 327 510 161 694
## sample3 -405 -739 -1 -234
## sample4 266 566 295 503
group = rep(c("A","B"),times = nrow(exp_dat)/2)
group = factor(group,levels = c("A","B"))
group
## [1] A B A B A B A B A B
## Levels: A B
3.出图!
输入数据准备好,一步就画图。
默认不聚类,如果想要聚类,那就加参数cluster = T。下图是不聚类(p1)和聚类(p2)的对比。聚类算法和pheatmap一致,目前只支持hclust,如果以后有人提需求,我就加上别的算法~
p1 = ggheat(exp_dat,group)
p2 = ggheat(exp_dat,group,cluster = T)
p1/p2
还有几个参数可调整,例如是否显示热图行列名,以及图例名称修改。具体的意义可以看字面意思或帮助文档。
ggheat(exp_dat,group,cluster = T,show_rownames = F,
show_colnames = F,groupname = "risk",expname = "expression")
4.拼图毫无压力!
这样画出来的图,是根正苗红的ggplot2!所以配上patchwork拼图,那叫一个整整齐齐!
po1 = ggplot(iris,aes(Species,Sepal.Length,fill = Species))+
geom_boxplot()+theme_bw()
po2 = ggplot(iris,aes(Species,Sepal.Length,color = Species))+
geom_jitter()+theme_bw()
po1/po2/p1