一文学会ComplexHeatmap包图文注释
大家好,我是风。这里是风风的CNS美图复现系列专栏。我们今天继续学习ComplexHeatmap的图文注释,废话不多说,直接开始吧!
传送门
学一个R包给文章加一张CNS级别的美图(六)
加载包
我们还是构建一个跟前面推文一致的数据:
# 加载R包library(ComplexHeatmap)library(circlize)# 构建一个跟之前一样的矩阵set.seed(123)nr1 = 4; nr2 = 8; nr3 = 6; nr = nr1 + nr2 + nr3nc1 = 6; nc2 = 8; nc3 = 10; nc = nc1 + nc2 + nc3mat <- cbind(rbind(matrix(rnorm(nr1*nc1, mean = 1, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc1, mean = 0, sd = 0.5), nr = nr2), matrix(rnorm(nr3*nc1, mean = 0, sd = 0.5), nr = nr3)), rbind(matrix(rnorm(nr1*nc2, mean = 0, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc2, mean = 1, sd = 0.5), nr = nr2), matrix(rnorm(nr3*nc2, mean = 0, sd = 0.5), nr = nr3)), rbind(matrix(rnorm(nr1*nc3, mean = 0.5, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc3, mean = 0.5, sd = 0.5), nr = nr2),         matrix(rnorm(nr3*nc3, mean = 1,   sd = 0.5), nr = nr3)))mat <- mat[sample(nr, nr), sample(nc, nc)] rownames(mat) = paste0("gene", seq_len(nr))colnames(mat) = paste0("Sample", seq_len(nc))head(mat)## Sample1 Sample2 Sample3 Sample4 Sample5 Sample6## gene1 0.90474160 -0.35229823 0.5016096 1.26769942 0.8251229 0.16215217## gene2 0.90882972 0.79157121 1.0726316 0.01299521 0.1391978 0.46833693## gene3 0.28074668 0.02987497 0.7052595 1.21514235 0.1747267 0.20949120## gene4 0.02729558 0.75810969 0.5333504 -0.49637424 -0.5261114 0.56724357## gene5 -0.32552445 1.03264652 1.1249573 0.66695147 0.4490584 1.04236865## gene6 0.58403269 -0.47373731 0.5452483 0.86824798 -0.1976372 -0.03565404## Sample7 Sample8 Sample9 Sample10 Sample11 Sample12## gene1 -0.2869867 0.68032622 -0.1629658 0.8254537 0.7821773 -0.49625358## gene2 1.2814948 0.38998256 -0.3473535 1.3508922 1.1183375 2.05005447## gene3 -0.6423579 -0.31395304 0.2175907 -0.2973086 0.4322058 -0.25803192## gene4 0.8127096 -0.01427338 1.0844780 0.2426662 0.8783874 1.38452112## gene5 2.6205200 0.75823530 -0.2333277 1.3439584 0.8517620 0.85980233## gene6 -0.3203530 1.05534136 0.7771690 0.4594983 0.2550648 -0.02778098## Sample13 Sample14 Sample15 Sample16 Sample17 Sample18## gene1 -0.0895258 -0.35520328 0.1072694 0.96322199 -0.39245223 -0.1878014## gene2 1.3770269 -0.77437640 0.9829664 0.23854381 -0.53589561 1.3003544## gene3 -0.5686518 -0.51321045 -0.0451598 0.82272880 -0.02251386 0.2427300## gene4 0.8376570 0.10797078 0.4520019 0.81648036 0.02650211 0.4072600## gene5 1.9986067 -0.50928769 0.7708173 -0.09421702 -1.15458444 1.2715970## gene6 -0.2112484 0.01669142 -0.3259750 0.54460361 0.89101254 0.3699738## Sample19 Sample20 Sample21 Sample22 Sample23 Sample24## gene1 1.08736320 0.7132199 -0.1853300 -0.14238650 0.6407669 1.3266288## gene2 0.14237891 0.4471643 0.4475628 -0.31251963 0.7057150 0.8120937## gene3 1.09511516 0.5852612 0.1926402 0.51278568 1.6361334 1.1339175## gene4 -0.02625664 0.9556956 0.3443201 0.07668656 1.7857291 0.5280084## gene5 0.60599022 0.8304101 -0.1902355 -0.14753574 1.0123366 0.2140750## gene6 0.81537706 1.2737905 1.8575325 0.88491126 0.5670193 0.5372756
图片注释
所谓图片注释就是把热图中的信息用特定图片进行反应,比如使用箱式图、密度图等等,就像是使用ggplot2绘制相关性图片时在边缘叠加其他类型图片,我们分别来看看有哪些可以进行图文注释吧!

Barplot

# 普通条形图注释,计算每一列的平均值并用柱状图进行注释ha1 = HeatmapAnnotation(Mean = anno_barplot(colMeans(mat), gp = gpar(fill = 1:24)))Heatmap(mat, name = "mat", top_annotation = ha1)
# 叠加条形图注释,随机生成一份数据进行叠加图注释m = matrix(runif(10*24), nc = 10)m = t(apply(m, 1, function(x)x/sum(x)))ha2 = HeatmapAnnotation(Immune_Cell = anno_barplot(m, gp = gpar(fill = 2:11), bar_width = 1, height = unit(2, "cm")))Heatmap(mat, name = "mat", top_annotation = ha2)
# 叠加柱状图的注释是不是和我们常见的Cibersorts计算免疫浸润细胞的结果图片类似?所以我们以后可以将基因表达矩阵热图和免疫浸润细胞结果合在一起进行可视化Histogram# 能用柱状图那肯定也能用直方图啦ha4 = rowAnnotation(Mean = anno_histogram(mat, gp = gpar(fill = 2:5)))Heatmap(mat, name = "mat", right_annotation = ha4)

Density plot

# 同样使用mat矩阵进行密度图映射ha5 = rowAnnotation(Mean = anno_density(mat, joyplot_scale = 2, gp = gpar(fill = 2:4)))Heatmap(mat, name = "mat", right_annotation = ha5)
# 将密度图变为小提琴图ha6 = rowAnnotation(Mean = anno_density(mat, type = "violin", gp = gpar(fill = 2:4)))Heatmap(mat, name = "mat", right_annotation = ha6)
# 将密度图变为热图ha7 = rowAnnotation(Mean = anno_density(mat, type = "heatmap", width = unit(3, "cm")))Heatmap(mat, name = "mat", right_annotation = ha7)
文本注释
相对于图片注释的花里胡哨来说,文本注释可以在我们的日常绘图中反而更加常用:
# 使用月份名称替代基因注释,实际应用过程中可替代为各种表型名称ha8 = rowAnnotation(foo = anno_text(month.name, location = 1, rot = 0, # 旋转0度 just = "right", # 右对齐 gp = gpar(fontsize = 1:12+4)))Heatmap(mat[1:12,1:12], name = "mat", right_annotation = ha8)
# 也可以和我们之前讲过的其他参数结合起来ha9 = rowAnnotation(foo = anno_text(month.name, location = 0.5, just = "center", gp = gpar(fill = rep(2:5, each = 3), col = "gray40", border = "red"), width = max_text_width(month.name)*1.2))Heatmap(mat[1:12,1:24], name = "mat", right_annotation = ha9)
有时候我们只需要标注特定的文本,就像上次我们进行单细胞绘图注释一样,那么:ha = rowAnnotation(foo = anno_mark(at = c(1:4, 12:18), # 用at参数需要标注文本的行数 labels = month.name[1:11])) # labels对应at的个数Heatmap(mat, name = "mat", cluster_rows = FALSE, right_annotation = ha)
综合注释
接下来我们看一个综合注释的例子,这个例子包含一个整体热图,然后从整体热图中提取出两列特定的热图,接着再对这两列热图进行注释,映射相应特征:
set.seed(10086)m = matrix(rnorm(50*10), nrow = 50)ht_list = Heatmap(m, name = "Immune_Cell"# 热图主体ha = HeatmapAnnotation(summary = anno_summary(height = unit(3, "cm")))v = sample(letters[1:2], 50, replace = TRUE)ht_list = ht_list +  Heatmap(v, name = "IC_Mean", top_annotation = ha, width = unit(1, "cm")) # 映射的特定列1ha = HeatmapAnnotation(summary = anno_summary(gp = gpar(fill = 2:3), height = unit(3, "cm")))v = rnorm(50)ht_list = ht_list +  Heatmap(v, name = "TMB_Score", top_annotation = ha, width = unit(1, "cm")) # 映射的特定列2split = sample(letters[1:2], 50, replace = TRUE) # 设置聚类切割的样本类型lgd_boxplot = Legend(labels = c("group a", "group b"), title = "group", legend_gp = gpar(fill = c("red", "blue"))) # 设置legenddraw(ht_list, row_split = split, ht_gap = unit(5, "mm"), heatmap_legend_list = list(lgd_boxplot)) # 绘制热图
这种注释适用于我们要对热图主体的某一特征进行描述的时候,想象一下,热图主体是免疫细胞含量,mat1是每一行的平均值,mat2是TMB值,这样我们就可以直观地在一个图片中观察到免疫细胞含量、免疫细胞含量平均值、TMB三者之间的关系,这样的图片反应的信息更加丰富,自然也就显得比别人技高一筹啦!

当然我们有时候还想在热图主体的右边加一些其他个性化的注释,比如我们还是利用前面构建的mat函数绘图:
subgroup = sample(letters[1:3], 18, replace = TRUE, prob = c(1, 5, 10))rg = range(mat)panel_fun = function(index, nm) { pushViewport(viewport(xscale = rg, yscale = c(0, 2))) grid.rect() grid.xaxis(gp = gpar(fontsize = 8)) grid.boxplot(m[index, ], pos = 1, direction = "horizontal") popViewport()} # 自定义函数绘制boxplotanno = anno_zoom(align_to = subgroup, which = "row", panel_fun = panel_fun, size = unit(2, "cm"), gap = unit(1, "cm"), width = unit(4, "cm"))Heatmap(mat, name = "mat", right_annotation = rowAnnotation(foo = anno), row_split = subgroup)
热图修饰
一个“花里胡哨”的热图总是会在别人意想不到的地方添加更多的信息,而这些操作在ComplexHeatmap中无非就是多加几行参数罢了,现在我们通过前面的学习,已经基本把ComplexHeatmap的参数都学了,接下来就让我们把这些参数串起来,看看出来的结果可以有多花哨吧!
ha1 = HeatmapAnnotation(pt = anno_points(1:10, gp = gpar(col = rep(2:3, each = 5)), height = unit(2, "cm")), show_annotation_name = FALSE) # 绘制第一个热图的图形注释ha2 = HeatmapAnnotation(ln = anno_lines(cbind(1:10, 10:1), gp = gpar(col = 2:3, lty = 1:2), height = unit(2, "cm")), show_annotation_name = FALSE) # 绘制第二个热图的图形注释m = matrix(rnorm(100), 10)ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) + Heatmap(m, name = "mat2", top_annotation = ha2) + Heatmap(m[, 1], name = "mat3", top_annotation = HeatmapAnnotation( summary = anno_summary(gp = gpar(fill = 2:3)) ), width = unit(1, "cm"))draw(ht_list, ht_gap = unit(7, "mm"))
# 添加legend显示更多信息lgd_list = list( Legend(labels = c("red", "green"), title = "pt", type = "points", pch = 16, legend_gp = gpar(col = 2:3)), Legend(labels = c("red", "green"), title = "ln", type = "lines", legend_gp = gpar(col = 2:3, lty = 1:2)), Legend(labels = c("group1", "group2"), title = "km", type = "boxplot", legend_gp = gpar(fill = 2:3)))draw(ht_list, ht_gap = unit(7, "mm"), row_km = 2, annotation_legend_list = lgd_list)
还可以再复杂一点:
set.seed(123)mat = matrix(rnorm(80, 2), 8, 10)mat = rbind(mat, matrix(rnorm(40, -2), 4, 10))rownames(mat) = paste0("R", 1:12)colnames(mat) = paste0("C", 1:10)ha_column1 = HeatmapAnnotation(points = anno_points(rnorm(10)), annotation_name_side = "left")ht1 = Heatmap(mat, name = "ht1", km = 2, column_title = "Heatmap 1",    top_annotation = ha_column1, row_names_side = "left")ha_column2 = HeatmapAnnotation(type = c(rep("a", 5), rep("b", 5)), col = list(type = c("a" = "red", "b" = "blue")))ht2 = Heatmap(mat, name = "ht2", row_title = "Heatmap 2", column_title = "Heatmap 2",   bottom_annotation = ha_column2, column_km = 2)ht_list = ht1 + ht2 + rowAnnotation(bar = anno_barplot(rowMeans(mat), width = unit(2, "cm")))draw(ht_list, row_title = "Heatmap list", column_title = "Heatmap list")
好了,今天的内容又结束啦。到今天为止,我们把ComplexHeatmap的常用参数基本学完,再一次感谢R包的作者顾博士,曾经我以为可视化也不过如此,关键还是在于数据清洗,知道我学习了ComplexHeatmap之后,才发现原来可视化可以有这么多的玩法。并且!你以为ComplexHeatmap就只能用来画热图?Too Young Too Naive!
回复“风风26”得今天的代码哦~
下一次开始,我们将一起进一步学习ComplexHeatmap包,看看ComplexHeatmap的神奇操作还有哪一些,想发高水平杂志,那ComplexHeatmap的用法你一定不能错过,我们下次见!O(∩_∩)O
END

撰文丨阿  琛
排版丨四金兄
值班 | 小雪球

主编丨小雪球
欢迎大家关注解螺旋生信频道-挑圈联靠公号~
继续阅读
阅读原文