终章:再复现一张美图
大家好,我是风。这里是风风的CNS美图复现系列专栏。上周那张20多分Cancer Cell的美图大家复现出来了吗?咱们先不要求能够看懂每一句代码的意思,先能够用推文给的数据跑通代码出来图片,然后替换成自己的数据之后还能够做出一张类似的图片放在自己的文章中,这个要求就没那么难了吧?我最近也是做了一张类似的图片,准备将它作为我论文的Figure 3,我们尽量在花了时间学一个东西之后能够迅速转化为自己的成果,所学即所得,也能在“所得”的时候发现自己在“所学”过程中忽略了的问题,最忌讳的做法就是“贪多嚼不烂”,短时间学习了很多内容,结果没有转化成成果,那学的内容不就跟你那些躺在百度网盘的资料一样,永不见天日了嘛!
传送门
ComplexHeatmap系列学习了这么长的时间,我们从最开始的参数学习,到不断升级组合搭配,再到现在复现高级论文的图片,总共经历了n期,也给大家展示了学习一个R包从无到有到升华的基本过程,现在也到了收尾的时候了,所以这将是ComplexHeatmap最后一期的内容,同样提醒大家如果你使用了ComplexHeatmap包,请记得引用相关文献:发表于bioinformatics的这篇文献 “Gu, Z. (2016) Complex heatmaps reveal patterns and correlations in multidimensional genomic data. DOI: 10.1093/bioinformatics/btw313”,
我们今天一样以复现一张文章图片作为最后一期:
这一样是一张组合图,通过热图和叠加柱状图展示一份数据的多个维度:
1.行名是样本名,总共有8个样本分为2组;
2.列名跟我们以前看到的图片都不一样,直接展示多种不同的注释内容,包括Mean methylation、Number of DMRs、Significantly correlated genes Distance to TSS、Gene annotation、CGI annotation、Enrichment to genomic features、Overlap to Chromatin states、Enrichment to chromatin states,用叠加柱状图和热图展示不同数据。
这张图片咋看简单,仔细一看,感觉比上回画的热图还难是不?上回画的热图好歹还能看出来规律,这一次就像是多个图片直接拼接在一起,难道这真的是多个图拼在一起?我们复现试试:
数据处理
画图第一步,同样是熟悉我们的数据,数据同样在后台回复关键词获取,我们先将数据读取进来:
rm(list = ls())# 加载R包library(ComplexHeatmap)library(circlize)library(RColorBrewer)# 读取数据load("data.rda")# 加载数据后发现数据有10个List,老规矩,看看都有什么内容:View(lt)names(lt)## [1] "label""mean_meth""n_gr""n_corr"## [5] "dist_tss""gene_anno""cgi_anno""mat_enrich_gf"##  [9] "mat_pct_st""mat_enrich_st"# label:DMRs集的标签,存在四个亚组的DMR,对于每个子组,DMR分为高甲基化DMR和低甲基化DMR。# mean_meth:肿瘤样品和正常样品中DMR的平均甲基化水平。# n_gr:每组中DMR的数量。# n_corr:与邻近基因有显着相关性的DMR的百分比,分别计算正相关和负相关。# dist_tss:到邻近基因TSS的距离,该值是当前集中DMR的比例。# gene_anno:与基因或基因间区域重叠的DMR的比例。# cgi_anno:与CpG岛屿或CGI重叠的DMR的比例。# mat_enrich_gf:扩充到一系列基因组的特征。# mat_pct_st:与染色质状态重叠的DMR的比例。# mat_enrich_st:染色质状态的富集。# 由于后续画图所有数据都来源于数据集lt,为了简化代码,我们使用attach函数锁定画图数据,将所有这些变量附加到工作环境中:attach(lt)
自定义颜色
接下来我们需要定义颜色,因为我们有很多统计数据要可视化:
# 使用RColorBrewer包和circlize包的配色找到自己喜欢的配色display.brewer.all()
# 这里提取Set3的配色方案brewer.pal(12, "Set3")## [1] "#8DD3C7""#FFFFB3""#BEBADA""#FB8072""#80B1D3""#FDB462""#B3DE69"## [8] "#FCCDE5""#D9D9D9""#BC80BD""#CCEBC5""#FFED6F"?colorRamp2# 接下来进行配色meth_col_fun = colorRamp2(c(0, 0.5, 1), c("#80B1D3", "white", "#FB8072"))corr_col = c("blue", "red")dist_tss_col = c("#8DD3C7", "#FFFFB3", "#BEBADA", "#FB8072")gene_anno_col = c("#BEBADA", "blue")cgi_anno_col = c("#B3DE69", "#FCCDE5")z_score_col_fun = colorRamp2(c(-200, 0, 200), c("#80B1D3", "white", "red"))state_col = c("#FF0000", "#008000", "#C2E105", "#8A91D0", "#CD5C5C", "#808080", "#000000")
开始画图
跟前面画的其他图一样,我们先构建热图注释:
# 热图list的构建非常简单,每个统计信息都构造为热图或行注释# 构建行注释ht_list = rowAnnotation(text = anno_text(label, location = unit(1, "npc"), just = "right", gp = gpar(fontsize = 12)))ht_list## A HeatmapAnnotation object with 1 annotation## name: heatmap_annotation_0 ## position: row ## items: 8 ## width: 12.8143mm ## height: 1npc ## this object is subsetable## ## name annotation_type color_mapping width##  text     anno_text()               12.8143mm#使用Heatmap函数叠加热图,然后使用rowAnnotation叠加注释信息,这里使用图形注释ht_list = ht_list + Heatmap(mean_meth, name = "mean_meth", col = meth_col_fun, cluster_rows = FALSE, row_title = NULL, cluster_columns = FALSE, show_row_names = FALSE, heatmap_legend_param = list(title = "Methylation"), width = ncol(mean_meth)*unit(4, "mm")) +rowAnnotation("n_gr" = anno_barplot(n_gr, bar_width = 1, width = unit(3, "cm")), show_annotation_name = FALSE) +rowAnnotation("n_corr" = anno_barplot(n_corr, bar_width = 1, gp = gpar(fill = corr_col), width = unit(3, "cm")), show_annotation_name = FALSE) +rowAnnotation("dist_tss" = anno_barplot(dist_tss, bar_width = 1, gp = gpar(fill = dist_tss_col), width = unit(3, "cm")), show_annotation_name = FALSE) +rowAnnotation("gene_anno" = anno_barplot(gene_anno, bar_width = 1, gp = gpar(fill = gene_anno_col), width = unit(3, "cm")), show_annotation_name = FALSE) +rowAnnotation("cgi_anno" = anno_barplot(cgi_anno, bar_width = 1, gp = gpar(fill = cgi_anno_col), width = unit(3, "cm")), show_annotation_name = FALSE) +Heatmap(mat_enrich_gf, name = "enrich_gf", col = z_score_col_fun, cluster_columns = FALSE, width = unit(ncol(mat_enrich_gf)*4, "mm"), column_title = "", heatmap_legend_param = list(title = "Z-score")) +rowAnnotation("pct_st" = anno_barplot(mat_pct_st, bar_width = 1, gp = gpar(fill = state_col), width = unit(3, "cm")), show_annotation_name = FALSE) +Heatmap(mat_enrich_st, name = "enrich_st", col = z_score_col_fun, cluster_columns = FALSE, width = unit(ncol(mat_enrich_st)*6, "mm"), column_title = "", show_heatmap_legend = FALSE, column_names_gp = gpar(col = state_col), show_row_names = FALSE)ht_list
# 前面我们看到的多种图形,其实只需要用我们之前讲过的图形注释,然后使用+连接即可
由于注释条形图不会生成图例,因此我们可以使用Legend()函数手动构造这些图例:
# 构建图例lgd_list = list( Legend(labels = c("gene", "intergenic"), title = "Gene annotation", legend_gp = gpar(fill = gene_anno_col)), Legend(labels = c("<1kb", "1kb~5kb", "5kb~10kb", ">10kb"), title = "Distance to TSS", legend_gp = gpar(fill = dist_tss_col)), Legend(labels = c("CGI", "CGI shore"), title = "CGI annotation", legend_gp = gpar(fill = cgi_anno_col)), Legend(labels = colnames(mat_enrich_st), title = "Chromatin states", legend_gp = gpar(fill = state_col)))
最后就到了绘制图片的时候了,还是使用draw函数将上面的结果整合在一起,观察原始图片发现,在绘制热图时,所有热图和注释的行都分为两个主要组,所以在对应于平均甲基化矩阵的第一个Heatmap()中,我们将row_title=NULL设置为从行拆分中删除行标题,由于我们将为注释添加标题,因此我们通过padding参数在整个绘图区域的顶部设置为空白,同样,我们将自定义图例列表连接到热图图例列表,并将它们水平放置在热图列表的底部:
draw(ht_list, padding = unit(c(2, 2, 20, 2), "mm"), row_split = gsub("\\d+$", "", label), heatmap_legend_list = lgd_list, heatmap_legend_side = "bottom")anno_title = c("n_gr" = "Number of\nDMRs", "n_corr" = "Significantly\ncorrelated genes","gene_anno" = "Gene annotation", "dist_tss" = "Distance to TSS","cgi_anno" = "CGI annotation", "pct_st" = "Overlap to\nChromatin states")for(an in names(anno_title)) { decorate_annotation(an, { grid.text(anno_title[an], y = unit(1, "npc") + unit(3, "mm"), just = "bottom") })}ht_title = c("mean_meth" = "Mean\nmethylation", "enrich_gf" = "Enrichment to\ngenomic features","enrich_st" = "Enrichment to\nchromatin states")for(an in names(ht_title)) { decorate_heatmap_body(an, { grid.text(ht_title[an], y = unit(1, "npc") + unit(3, "mm"), just = "bottom") })}
这样我们整个图片就复现完成啦,其实使用的方法都在我们前面的推文都讲解过了,这些图片也只是看着好像很难,用了合适的参数之后代码也就那么多行!好啦,这也是我们ComplexHeatmap系列最后一起推文,同时也是我们CNS美图复现系列专栏系列最后一期了,在本专栏中,我们利用ComplexHeatmap包,给大家展示了多种复合图形的画法,这个过程包括突变图、单细胞数据处理、甲基化数据处理和复合热图、多维度数据整合等等内容,这些内容都可以让你的文章与众不同,即使是水文,也会看起来不那么水!在文章中展示高阶图片,让自己的内容显得不那么单调,同时在一个图片中展示多种信息,这是可视化独特的魅力,不要再说可视化简单了,如果你觉得可视化简单,那就找一张自己觉得好看的图片,然后去复现它,我“赌”一顿地摊美食,很多说“可视化简单”的人,你拿一张图片给他们,他们其实从哪里开始复现都不知道(●ˇ∀ˇ●)。
美图复现系列到此结束,虽然没有赶上2020和2021新旧交替的时候,但是也相差不远,我们即将开始新的篇章,高人气国漫《一人之下》中,王也道长说过一句经典名言:“过去无可挽回,未来可以改变”!如果你没登上上一班车,那请在车门关闭之前踏上下一班车,2020无可挽回,2021可以改变,我在2021的新篇章等你!
后台回复“feng32”获得本次代码和绘图数据,我们下次再见吧!*^_^*
END

撰文丨风   风
排版丨四金兄
值班 | 风   风
主编丨小雪球
欢迎大家关注解螺旋生信频道-挑圈联靠公号~
继续阅读
阅读原文