学一个R包给文章加一张CNS级别的美图(四)
重剑无锋,大巧不工
大家好,我是风。在上次最后一个图片中,我们利用注释对ComplexHeatmap绘制的热图进行了修饰和美化,那这些修饰都应该怎么进行操作呢?
ComplexHeatmap在注释方面提供了非常多的可选择性,可以在图片的上、下、左、右分别加上注释的信息,分别用top_annotation,bottom_annotation,left_annotation和right_annotation, 而其中我们还可以用另外两个函数来封装注释信息,分别是HeatmapAnnotation或rowAnnotation,为了让大家能够衔接前面的内容,这次用的数据还是前面的三次推文构建的数据。传送门 手把手教你复现一篇CNS级别美图!附代码,建议收藏! CNS级别的美图复现起来难不难?小白也能快速上手(附代码)(二)
那我们还是构建一个跟前面推文一致的数据:
加载R包
library(ComplexHeatmap)
library(circlize)
构建一个跟之前一样的矩阵
set.seed(123)
nr1 = 4; nr2 = 8; nr3 = 6; nr = nr1 + nr2 + nr3
nc1 = 6; nc2 = 8; nc3 = 10; nc = nc1 + nc2 + nc3
mat <- 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
# 随机添加注释信息
column_ha <- HeatmapAnnotation(foo1 = runif(24,10,20), bar1 = anno_barplot(runif(24,10,20)))
row_ha <- rowAnnotation(foo2 = runif(18,10,20), bar2 = anno_barplot(runif(18,10,20)))
Heatmap(mat, name = "mat", top_annotation = column_ha, right_annotation = row_ha)
Heatmap(mat, name = "mat", bottom_annotation = column_ha, left_annotation = row_ha)
# 在上面的代码中,column_ha和row_ha都具有两个注释,其中foo1和foo2是数字矢量注释信息,而bar1和bar2是图形注释信息,像矢量一样的注释在这里被称为“简单注释”,而图形注释被称为“复杂注释”,我们把注释信息赋予了一个特定的值,比如这里的foo1和bar1
在上面的例子中我们已经看到了数字矢量进行热图注释,并且将其称为简单注释。那么什么是简单注释呢?所谓的简单注释是最常用的注释风格,它是类似热图或网格图形的注释,颜色用于映射具体值。要生成一个简单的注释,只需将注释向量以特定的名称放在HeatmapAnnotation就可以,比如这样:
ha = HeatmapAnnotation(foo = 1:24)
Heatmap(mat, name = "mat", top_annotation = ha)
ha = HeatmapAnnotation(foo = sample(c("normal","tumor"), 24, replace = TRUE))
Heatmap(mat, name = "mat", top_annotation = ha)
大家不妨运行多几次上面的代码,是不是发现每次颜色都不一样?那我们可以设定我们喜欢的颜色吗?当然可以:
# 使用colorRamp2设置颜色,并添加col函数添加注释信息的颜色
# 对连续型注释信息进行颜色添加
col_fun = colorRamp2(c(0, 50, 100), c("navy", "white", "red"))
ha1 = HeatmapAnnotation(foo = runif(24,0,100), col = list(foo = col_fun))
Heatmap(mat, name = "mat", bottom_annotation = ha1)
# 对离散型注释信息进行颜色添加
colours <- list(SampleType = c("normal"="navy","tumor"="red"))
ha2 = HeatmapAnnotation("SampleType" = sample(c("normal","tumor"), 24, replace = TRUE),
col = colours)
Heatmap(mat, name = "mat", top_annotation = ha2)
# 同时放入离散型变量和连续型变量
ha3 = HeatmapAnnotation(
foo = runif(24,0,100),
SampleType = sample(c("normal","tumor"), 24, replace = TRUE),
col = list(foo = col_fun,
SampleType = c("normal"="navy","tumor"="red")
)
)
Heatmap(mat, name = "mat", top_annotation = ha3)
# 如果样本中有NA值,则使用na_col赋予颜色
ha4 = HeatmapAnnotation(
foo = runif(24,0,100),
SampleType = c(NA,sample(c("normal","tumor"), 23, replace = TRUE)),
col = list(foo = col_fun,
SampleType = c("normal"="lightblue","tumor"="red")
),
na_col = "black"
)
Heatmap(mat, name = "mat", top_annotation = ha4)
# 前面学过的gp一样使用于注释信息
ha5 = HeatmapAnnotation(
foo = runif(24,0,100),
SampleType = sample(c("normal","tumor"), 24, replace = TRUE),
col = list(foo = col_fun,
SampleType = c("normal"="navy","tumor"="red")
),
gp = gpar(col = "orange"),
annotation_width=unit(c(1, 4), "cm"),
gap = unit(2, "mm")
)
Heatmap(mat, name = "mat", top_annotation = ha5)
# 更多时候可能我们的数据是一个数据框
# 可以把自己的注释信息整理成表格然后读取进来,不限制个数
clinical <-data.frame(age = runif(24,0,100),
SampleType = sample(c("normal","tumor"), 24, replace = TRUE))
ha6 = HeatmapAnnotation(df = clinical,col = list(foo = col_fun,
SampleType = c("normal"="navy","tumor"="red")),
border = TRUE,
simple_anno_size = unit(1, "cm"))
Heatmap(mat, name = "mat", top_annotation = ha6)
# 下面同步展示一种常见的错误注释方法,注意比较ha6和ha7
clinical <- cbind(runif(24,0,100),
sample(c("normal","tumor"), 24, replace = TRUE))
ha7 = HeatmapAnnotation(clinical = clinical)
Heatmap(mat, name = "mat", top_annotation = ha7)
OK,简单注释我们就说这么多,接下来我们继续说说用函数进行简单注释。
HeatmapAnnotation可以通过将注释设置为函数来支持“复杂注释”,注释函数定义如何在与热图中的列或行相对应的特定位置绘制图形。对于所有形式为anno_开头的注释函数,如果在HeatmapAnnotation或rowAnnotation中指定了注释功能,则无需对anno_进行任何映射,anno_会自动检测它是行注释环境还是列注释环境:
# 前面我们用了这样的注释信息
ha = HeatmapAnnotation(foo = 1:24)
# 其实完整的写法应该是这样
ha = HeatmapAnnotation(foo = anno_simple(1:24))
# anno_simple进行类似于热图的注释(或简单注释),这个函数一般用来在注释网格上添加更多符号,比如我们常见的打×或者▲等等
ha8 = HeatmapAnnotation(foo = anno_simple(1:24, pch = 1:24))
Heatmap(mat, name = "mat", bottom_annotation = ha8)
# 或者自定义pch的值
ha9 = HeatmapAnnotation(foo = anno_simple(1:24,
pt_gp = gpar(col = "blue"),
pch = sample(c("N","T"), 24, replace = TRUE)))
Heatmap(mat, name = "mat", bottom_annotation = ha9)
# 如果含有NA,也可以留空白
ha10 = HeatmapAnnotation(foo = anno_simple(1:24, pch = c(1:8, NA,NA,NA, 12:18, NA, 20:24)))
Heatmap(mat, name = "mat", bottom_annotation = ha10)
# anno simple的对象也可以是一个矩阵
ha11 = HeatmapAnnotation(foo = anno_simple(cbind(1:24, 24:1), pch = 1:2))
Heatmap(mat, name = "mat", bottom_annotation = ha11)
ha12 = HeatmapAnnotation(foo = anno_simple(cbind(1:24, 24:1), pch = 1:24))
Heatmap(mat, name = "mat", bottom_annotation = ha12)
# 对比上面ha11和ha12我们会发现anno函数自动检测了添加的图形是匹配了行还是列
# 如果matrix中有NA值,一样可以进行修饰
pch = matrix(1:48, nc = 2)
pch[sample(length(pch), 10)] = NA
ha13 = HeatmapAnnotation(foo = anno_simple(cbind(1:24, 24:1), pch = pch))
Heatmap(mat, name = "mat", bottom_annotation = ha13)
# 我们可以先计算p值,然后对p < 0.05 的结果打上*
set.seed(123)
pvalue = round(10^-runif(24, min = 0, max = 3),3) # 计算p值
is_sig = pvalue < 0.05 # 判断p<0.05
pch = rep("*", 24) # 给24个对象都打上星号
pch[!is_sig] = NA # 将不满足p<0.05的结果变换成NA
# 打上颜色
pvalue_col_fun = colorRamp2(c(0, 2, 3), c("navy", "white", "red"))
ha = HeatmapAnnotation(
pvalue = anno_simple(-log10(pvalue), col = pvalue_col_fun, pch = pch),
annotation_name_side = "left")
ht <- Heatmap(mat, name = "mat", top_annotation = ha)
draw(ht)
# 对p值的图例进行定义
lgd_pvalue = Legend(title = "p-value", col = pvalue_col_fun, at = c(0, 1, 2, 3),
labels = c("1", "0.1", "0.05", "0.01"))
# 对<0.01的p值进行定义
lgd_sig = Legend(pch = "*", type = "points", labels = "< 0.05")
# 添加两个自定义的图例
draw(ht, annotation_legend_list = list(lgd_pvalue, lgd_sig))
好了,今天的内容看似简单,其实组合排列花样很多,正是应了那句话“重剑无锋,大巧不工”。今天我们先到这,下回我们开始复杂的注释内容,我们下期再见吧!(●‘◡’●)
欢迎大家关注解螺旋生信频道-挑圈联靠公号~
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。