背景
画热图的体系用的比较多的是pheatmap和ComplexHeatmap这两个包,前者胜在代码简单,功能强大,而后者胜在细节无穷无尽,只有你想不到,没有它做不到。
ggplot2在画热图这件事上,是存在感不太强的。但有时候还必须得用它来画,以期和其他ggplot2的图严丝合缝的拼在一起。
因此我收集了一下ggplot2的成果,发现又解锁了y叔的一个新包aplot,以及前段时间刚出的ggheatmap(居然是大三的学生写的,后生可畏)。我写了三种方法,ggheatmap最为简单,可以直接去看方法3。
画图数据
热图的输入数据嘛,是一个数值型矩阵:
test = matrix(rnorm(200), 20, 10)
test[1:10, seq(1, 10, 2)] = test[1:10, seq(1, 10, 2)] + 3
test[11:20, seq(2, 10, 2)] = test[11:20, seq(2, 10, 2)] + 2
test[15:20, seq(2, 10, 2)] = test[15:20, seq(2, 10, 2)] + 4
colnames(test) = paste("Test", 1:10, sep = "")
rownames(test) = paste("Gene", 1:20, sep = "")
方法1 ggh4x
给ggplot2加聚类树的R包ggh4x,里面的scale_y_dendrogram函数。
library(ggh4x)
library(ggplot2)
library(tidyverse)
yclust <- hclust(dist(test))
xclust <- hclust(dist(t(test)))
p = test %>%
as.data.frame() %>%
rownames_to_column() %>%
pivot_longer(cols = 2:ncol(.),
names_to = "sample",
values_to = "exp") %>%
ggplot(aes(x = sample,y = rowname))+
geom_tile(aes(fill = exp))+
scale_fill_gradient2(midpoint = 2.5,
low = '#2fa1dd',
mid="white",
high = '#f87669') +
scale_y_dendrogram(hclust = yclust) +
scale_x_dendrogram(hclust = xclust,position = 'top') +
theme(panel.grid = element_blank(), panel.background = element_rect(fill = NA),
legend.background = element_rect(fill = NA), plot.background = element_rect(fill = NA),
axis.line = element_blank(), axis.ticks = element_blank(),
axis.title = element_blank())
p
图还是有模有样的,只是行名列名贴着聚类树,不如pheatmap画的好看。所以我尝试了一下把基因名放到右边,失败辽。但是又找到了另外一个做法:
方法2 ggtree
还是神奇Y叔的包,树状图可视化用的ggtree,配合拼图用的aplot,简直不要太方便。
p1 = test %>%
as.data.frame() %>%
rownames_to_column() %>%
pivot_longer(cols = 2:ncol(.),
names_to = "sample",
values_to = "exp") %>%
ggplot(aes(x = sample,y = rowname))+
geom_tile(aes(fill = exp))+
scale_fill_gradient2(midpoint = 2.5,
low = '#2fa1dd',
mid="white",
high = '#f87669') +
scale_y_discrete(position = "right")+
theme(panel.grid = element_blank(), panel.background = element_rect(fill = NA),
legend.background = element_rect(fill = NA), plot.background = element_rect(fill = NA),
axis.line = element_blank(), axis.ticks = element_blank(),
axis.title = element_blank())
library(ggtree)
p2<-ggtree(yclust)
p2+
geom_tiplab()+
xlim(NA,10)
p3<-ggtree(xclust)+layout_dendrogram()
p3+
geom_tiplab()+
xlim(NA,12)
library(aplot)
p1%>%
insert_left(p2,width = 0.2) %>%
insert_top(p3,height = 0.2)
本来以为拼图需要把主体热图的行列顺序调整一下才能拼,结果神奇的aplot能实现无缝连接,顺序调整犹如merge函数一样,自动搞定了嘿~
看到ggheatmap也用到了aplot包,应该是同一种方法咯。写成新的函数无比方便
方法3 ggheatmap
试了一下行列聚类和加注释条的操作,还是很丝滑的。只是annotation_color没有默认颜色,我jio的作者可以在下一版里设置上默认值。
library("ggheatmap")
ggheatmap(test,cluster_rows = T,cluster_cols = T,
color = colorRampPalette(c("#2fa1dd", "white", "#f87669"))(100))
annotation_col = data.frame(
CellType = factor(rep(c("CT1", "CT2"), 5))
)
rownames(annotation_col) = paste("Test", 1:10, sep = "")
col <- list(CellType=c(CT1 = "#2fa1dd",CT2 = "#f87669"))
ggheatmap(test,cluster_rows = T,cluster_cols = T,
color = colorRampPalette(c("#2fa1dd", "white", "#f87669"))(100),
annotation_cols = annotation_col,
annotation_color = col,
scale = "row")
这个配色我太喜欢了,恨不得走到哪都带着。