第 3 章 热图注释
热图注释是热图的重要组成部分,它显示与热图中的行或列相关联的附加信息。 ComplexHeatmap包为设置注释和定义新的注释图形提供了非常灵活的支持。注释可以放在热图的四个侧面,由top_annotation
,bottom_annotation
, left_annotation
和right_annotation
参数组成。
接下来我们将对不同第注释函数anno_*()
进行说明,如空注释anno_empty()
、块注释anno_block()
、图像注释anno_image()
、点注释anno_points()
、线注释anno_lines()
、条形图注释anno_barplot()
、箱线图注释anno_boxplot()
、直方图注释anno_histogram()
、密度注释anno_density()
等注释方法。
四个参数的值应该在HeatmapAnnotation
类中并且由HeatmapAnnotation()
函数构造,如果是行注释则由rowAnnotation()
函数构造。(rowAnnotation()
只是一个与HeatmapAnnotation(..., which = "row")
相同的辅助函数) ,热图注释的简单用法如下。
set.seed(123)
mat = matrix(rnorm(100), 10)
rownames(mat) = paste0("R", 1:10)
colnames(mat) = paste0("C", 1:10)
column_ha = HeatmapAnnotation(foo1 = runif(10), bar1 = anno_barplot(runif(10)))
row_ha = rowAnnotation(foo2 = runif(10), bar2 = anno_barplot(runif(10)))
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
是条形图。类似向量的注解在这里称为“简单注释”,条形图注解称为“复杂注释”。您已经可以看到注释必须定义为名称=值对(例如 foo = ...
)。
热图注释也可以独立于热图。它们可以通过+
(水平连接)或%v%
(垂直连接)到热图列表。
# code only for demonstration
Heatmap(...) + rowAnnotation() + ...
Heatmap(...) %v% HeatmapAnnotation(...) + ...
HeatmapAnnotation()
返回一个HeatmapAnnotation
类对象。对象通常由几个注释组成。如以下部分,首先介绍单个注释的设置,然后展示如何将它们组合在一起。
可以看到column_ha
和row_ha
对象的信息:
column_ha
## A HeatmapAnnotation object with 2 annotations
## name: heatmap_annotation_0
## position: column
## items: 10
## width: 1npc
## height: 15.3514598035146mm
## this object is subsetable
## 5.92288888888889mm extension on the left
## 9.4709mm extension on the right
##
## name annotation_type color_mapping height
## foo1 continuous vector random 5mm
## bar1 anno_barplot() 10mm
row_ha
## A HeatmapAnnotation object with 2 annotations
## name: heatmap_annotation_1
## position: row
## items: 10
## width: 15.3514598035146mm
## height: 1npc
## this object is subsetable
## 9.96242222222222mm extension on the bottom
##
## name annotation_type color_mapping width
## foo2 continuous vector random 5mm
## bar2 anno_barplot() 10mm
在本章的以下示例中,除非必要,否则我们将仅显示没有热图的注释图形。如果你想用一个热图来试试吧,你只需指定HeatmapAnnotation
,我们是以ha
名称来作为top_annotation
,bottom_annotation
,left_annotation
或 right_annotation
讨论对象。
列注释和行注释的设置基本相同。如果没有什么特别的,我们只以列注释作为示例。如果您想尝试一行注释,只需添加which = "row"
到 HeatmapAnnotation()
或直接切换到rowAnnotation()
功能。
3.1简单注释
所谓的“简单注释”是最常用的注释样式,它是类似热图或类似网格的图形,其中使用颜色映射到注释值。要生成一个简单的注释,您只需简单地将一个特定的名称注释向量放入HeatmapAnnotation()
中。
ha = HeatmapAnnotation(foo = 1:10)
离散型数据注释:
ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE))
除了HeatmapAnnotation()
,您可以使用任何字符串作为注释名称。
如果未指定颜色,则随机生成颜色。col
设置注释的颜色,col
需要设置命名列表。
对于连续值注释,颜色映射应该是由 circlize::colorRamp2()
生成的颜色映射函数。
library(circlize)
col_fun = colorRamp2(c(0, 5, 10), c("blue", "white", "red"))
ha = HeatmapAnnotation(foo = 1:10, col = list(foo = col_fun))
对于离散注释,颜色应该是命名向量,其中名称对应于注释中的级别。
ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE),
col = list(bar = c("a" = "red", "b" = "green", "c" = "blue")))
如果您指定多个向量,则会有多个注释(foo
和bar
)。您还可以看到foo
和bar
全部放入单个HeatmapAnnotation()
中是如何设置col
. 也许现在您可以理解颜色列表中的名称实际上是用来映射到注释名称的。col
中的值将用于构建简单注释的图例。
ha = HeatmapAnnotation(
foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
NA
值的颜色由na_col
参数控制。
ha = HeatmapAnnotation(
foo = c(1:4, NA, 6:10),
bar = c(NA, sample(letters[1:3], 9, replace = TRUE)),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
na_col = "black"
)
gp
主要控制网格边界的图形参数。
ha = HeatmapAnnotation(
foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
gp = gpar(col = "black")
)
简单注释也可以是矩阵(数字或字符),矩阵中的所有列共享相同的颜色映射模式。注意矩阵中的列对应于列注释中的行。矩阵的列名称也用作注释名称。
ha = HeatmapAnnotation(foo = cbind(a = runif(10), b = runif(10)))
如果矩阵没有列名,则仍然使用注解的名称,但绘制在注解的中间。
ha = HeatmapAnnotation(foo = cbind(runif(10), runif(10)))
由于简单的注释可以采用不同的模式(例如数字或字符),它们可以组合为数据帧并发送到df
参数。在你的项目中成像,你可能已经有了一个注释表,你可以直接通过 df
.
anno_df = data.frame(foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE))
ha = HeatmapAnnotation(df = anno_df,
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
单个注释和数据框可以混合使用。在以下示例中,foo2
由于未指定颜色,将使用随机颜色。
ha = HeatmapAnnotation(df = anno_df,
foo2 = rnorm(10),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
border
控制每个注释的边界。
ha = HeatmapAnnotation(
foo = cbind(1:10, 10:1),
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
border = TRUE
)
简单注释的高度由simple_anno_size
参数控制。由于所有单个注释具有相同的高度,因此 的值 simple_anno_size
是单个unit
值。注意有喜欢争论 width
,height
,annotation_width
和annotation_height
,但它们是用来调整的完整heamtap注释(这总是混合几种注释)的宽度/高度。
ha = HeatmapAnnotation(
foo = cbind(a = 1:10, b = 10:1),
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
simple_anno_size = unit(1, "cm")
)
当您有多个热图时,最好将所有热图上的简单注释的大小保持相同的大小。ht_opt$simple_anno_size
可以设置全局控制简单注解的大小。
3.2简单注释作为注释函数
HeatmapAnnotation()
通过将注释设置为函数来支持“复杂注释”。annotation 函数定义了如何在热图中的列或行对应的某个位置绘制图形。ComplexHeatmap包中预定义了很多注释函数 。在本章的最后,我们将介绍如何通过AnnotationFunction
类构造自己的注释函数。
对于anno_*()
形式的所有注释函数,如果在HeatmapAnnotation()
或rowAnnotation()
中指定 ,则不需要明确地做任何anno_*()
事情来判断它是应该绘制在行上还是列上。anno_*()
将会自动检测是行注释环境还是列注释环境。
上一节中的简单注解是由anno_simple()
注解函数内部构造的 。直接使用anno_simple()
不会自动为最终绘图生成图例,但是,它可以为更多的注释图形提供更大的灵活性(注意在第5章 我们将展示,虽然anno_simple()
不能自动生成图例,但可以控制图例并添加到最终绘图中手动)。
对于上一节中的示例:
# code only for demonstration
ha = HeatmapAnnotation(foo = 1:10)
实际上等同于:
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_simple(1:10))
anno_simple()
制作类似热图的注释(或简单的注释)。基本上如果用户只做类似热图的注释,他们不需要直接使用anno_simple()
,但是这个功能允许在注释网格上添加更多符号。
anno_simple()
允许在注释网格顶部添加“点”或单字母符号。pch
,pt_gp
和pt_size
控制点的设置。pch
的值可以是具有可能NA
值的向量。
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1,
pt_gp = gpar(col = "red"), pt_size = unit(1:10, "mm")))
设置pch
为向量:
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1:10))
设置pch
为字母向量:
ha = HeatmapAnnotation(foo = anno_simple(1:10,
pch = sample(letters[1:3], 10, replace = TRUE)))
设置pch
为带有NA
值的向量(pch 值为NA
不绘制任何内容):
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = c(1:4, NA, 6:8, NA, 10, 11)))
如果 anno_simple()
的值是矩阵,pch
也可以使用。 pch
的长度应该与矩阵的行数或列数甚至矩阵的长度相同(矩阵的长度是矩阵中所有数据点的长度)。
pch
的长度对应矩阵的列:
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:2))
pch
对应于矩阵行的长度:
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:10))
pch
是一个矩阵:
pch = matrix(1:20, nc = 2)
pch[sample(length(pch), 10)] = NA
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = pch))
到现在为止,您可能想知道如何设置已添加到简单注释中的符号的图例。在这里,我们将仅向您展示一个简单的示例,在下面的例子中,我们假设简单的注释是一种 p 值,我们将 p 值小于 0.01 的添加*
。
set.seed(123)
pvalue = 10^-runif(10, min = 0, max = 3)
is_sig = pvalue < 0.01
pch = rep("*", 10)
pch[!is_sig] = NA
# color mapping for -log10(pvalue)
pvalue_col_fun = colorRamp2(c(0, 2, 3), c("green", "white", "red"))
ha = HeatmapAnnotation(
pvalue = anno_simple(-log10(pvalue), col = pvalue_col_fun, pch = pch),
annotation_name_side = "left")
ht = Heatmap(matrix(rnorm(100), 10), name = "mat", top_annotation = ha)
# now we generate two legends, one for the p-value
# see how we define the legend for pvalue
lgd_pvalue = Legend(title = "p-value", col_fun = pvalue_col_fun, at = c(0, 1, 2, 3),
labels = c("1", "0.1", "0.01", "0.001"))
# and one for the significant p-values
lgd_sig = Legend(pch = "*", type = "points", labels = "< 0.01")
# these two self-defined legends are added to the plot by `annotation_legend_list`
draw(ht, annotation_legend_list = list(lgd_pvalue, lgd_sig))
anno_simple()
的高度可以通过height
参数或 simple_anno_size
内部控制。simple_anno_size
控制单行注释的大小和height
/width
控制简单注释的总高度/宽度。如果设置了height
/ width
, simple_anno_size
则被忽略。
ha = HeatmapAnnotation(foo = anno_simple(1:10, height = unit(2, "cm")))
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1),
simple_anno_size = unit(2, "cm")))
对于我们后面介绍的所有注释函数,单个注释的高度或宽度都应该在anno_*()
函数内部进行设置。
# code only for demonstration
anno_*(..., width = ...)
anno_*(..., height = ...)
同样,width
,height
,annotation_width
和annotation_height
在参数HeatmapAnnotation()
被用于调整多个注释的大小。
3.3 空注释
anno_empty()
是一个不绘制任何内容的占位符。以后可以通过decorate_annotation()
功能添加用户定义的图形。
ha = HeatmapAnnotation(foo = anno_empty(border = TRUE))
在后续章节中将介绍装饰函数的使用,但在这里我们举一个简单的例子。在基因表达表达分析中,有些情况下我们将热图分成几组,我们希望突出显示每组中的一些关键基因。在这种情况下,我们只需将基因名称添加到热图的右侧,而不将它们与相应的行对齐。(anno_mark()
可以将标签正确地与其对应的行对齐,但在在这里显示的示例中,这不是必需的)。
在以下示例中,由于行被拆分为四个切片,因此空注释也被拆分为四个切片。基本上我们所做的是在每个空的注释切片中,我们添加一个彩色段和文本。
random_text = function(n) {
sapply(1:n, function(i) {
paste0(sample(letters, sample(4:10, 1)), collapse = "")
})
}
text_list = list(
text1 = random_text(4),
text2 = random_text(4),
text3 = random_text(4),
text4 = random_text(4)
)
# note how we set the width of this empty annotation
ha = rowAnnotation(foo = anno_empty(border = FALSE,
width = max_text_width(unlist(text_list)) + unit(4, "mm")))
Heatmap(matrix(rnorm(1000), nrow = 100), name = "mat", row_km = 4, right_annotation = ha)
for(i in 1:4) {
decorate_annotation("foo", slice = i, {
grid.rect(x = 0, width = unit(2, "mm"), gp = gpar(fill = i, col = NA), just = "left")
grid.text(paste(text_list[[i]], collapse = "\n"), x = unit(4, "mm"), just = "left")
})
}
空注释的第二个用途是添加复杂的注释图形,其中空注释伪装成虚拟绘图区域。可以AnnotationFunction
为复杂的注释图形按类构造注释函数,允许子集和拆分,但仍然可以作为次要选择,直接在空注释内部绘制,实现起来更容易、更快(但灵活性较差,不允许拆分)。
下面我们将展示如何添加点注释的“复杂版本”。唯一需要注意的是x轴(y轴如果是行注释)上的位置应该对应列重新排序后的列索引。
ha = HeatmapAnnotation(foo = anno_empty(border = TRUE, height = unit(3, "cm")))
ht = Heatmap(matrix(rnorm(100), nrow = 10), name = "mat", top_annotation = ha)
ht = draw(ht)
co = column_order(ht)
value = runif(10)
decorate_annotation("foo", {
# value on x-axis is always 1:ncol(mat)
x = 1:10
# while values on y-axis is the value after column reordering
value = value[co]
pushViewport(viewport(xscale = c(0.5, 10.5), yscale = c(0, 1)))
grid.lines(c(0.5, 10.5), c(0.5, 0.5), gp = gpar(lty = 2),
default.units = "native")
grid.points(x, value, pch = 16, size = unit(2, "mm"),
gp = gpar(col = ifelse(value > 0.5, "red", "blue")), default.units = "native")
grid.yaxis(at = c(0, 0.5, 1))
popViewport()
})
3.4块注释
块注释更像是一个颜色块,它在热图的行或列被拆分时标识组。
Heatmap(matrix(rnorm(100), 10), name = "mat",
top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4))),
column_km = 3)
标签可以添加到每个块。
Heatmap(matrix(rnorm(100), 10),
top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
labels = c("group1", "group2", "group3"),
labels_gp = gpar(col = "white", fontsize = 10))),
column_km = 3,
left_annotation = rowAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
labels = c("group1", "group2", "group3"),
labels_gp = gpar(col = "white", fontsize = 10))),
row_km = 3)
请注意,labels
或图形参数的长度应与切片数具有相同的长度。
anno_block()
函数为行/列切片绘制矩形,其中一个矩形仅对应一个切片。那么,如果我们想在多个切片上绘制矩形以显示它们属于某些组,该怎么办,如下面的热图所示?
set.seed(123)
mat2 = matrix(rnorm(50*50), nrow = 50)
ha = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5]))
split = rep(1:5, each = 10)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
目前,很难在anno_block()
中直接支持它,但仍然有解决方法。实际上,要在多个切片上绘制矩形,我们需要知道两件事:1. 切片在图中的位置 2. 绘制矩形的空间。庆幸的是位置可以通过直接转到对应的视窗获得,并且可以通过anno_empty()
函数分配空间。
在下面的代码中,我们使用anno_empty()
创建一个空注释:
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
假设我们要将前三列切片作为一组,将后两列切片作为第二组。
用于注释的第一和第三切片的位置"empty"
可以通过以下方式获得:
seekViewport("annotation_empty_1")
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport("annotation_empty_3")
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
loc2
## $x
## [1] 4.07403126835173inches
##
## $y
## [1] 6.51051067246731inches
视图窗口名称"annotation_empty_1"
对应于注释的第一个切片empty
,我们取第一个“空”注释切片的左下角和第三个切片的右上角,保存在loc1
和 loc2
变量中。
这里重要的是grid::deviceLoc()
函数的使用。它直接将在某个视口中测量的位置转换为图形设备中的位置。
最后,我们去"global"
视口,因为"global"
视口的大小是图形设备的大小,绘制矩形并添加标签。
seekViewport("global")
grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y,
just = c("left", "bottom"), gp = gpar(fill = "red"))
grid.text("group 1", x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5)
注释的视图窗口名称采用固定格式,即 annotation_{annotation_name}_{slice_index}
. 可以通过list_components()
函数获取完整的视口名称集。
list_components()
## [1] "ROOT" "global"
## [3] "global_layout" "global-heatmaplist"
## [5] "main_heatmap_list" "heatmap_mat2"
## [7] "mat2_heatmap_body_wrap" "mat2_heatmap_body_1_1"
## [9] "mat2_heatmap_body_1_2" "mat2_heatmap_body_1_3"
## [11] "mat2_heatmap_body_1_4" "mat2_heatmap_body_1_5"
## [13] "mat2_dend_row_1" "mat2_dend_column_1"
## [15] "mat2_dend_column_2" "mat2_dend_column_3"
## [17] "mat2_dend_column_4" "mat2_dend_column_5"
## [19] "annotation_empty_1" "annotation_foo_1"
## [21] "annotation_empty_2" "annotation_foo_2"
## [23] "annotation_empty_3" "annotation_foo_3"
## [25] "annotation_empty_4" "annotation_foo_4"
## [27] "annotation_empty_5" "annotation_foo_5"
## [29] "global-heatmap_legend_right" "heatmap_legend"
如果要添加多个组级矩形,我们可以将代码包装成一个简单的函数group_block_anno()
:
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE, height = unit(8, "mm")),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
library(GetoptLong) # for the function qq()
group_block_anno = function(group, empty_anno, gp = gpar(),
label = NULL, label_gp = gpar()) {
seekViewport(qq("annotation_@{empty_anno}_@{min(group)}"))
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport(qq("annotation_@{empty_anno}_@{max(group)}"))
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
seekViewport("global")
grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y,
just = c("left", "bottom"), gp = gp)
if(!is.null(label)) {
grid.text(label, x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5, gp = label_gp)
}
}
group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
当热图被分割时,块注释中的每个块都可以被认为是一个虚拟的绘图区域。anno_block()
允许一个新参数graphics
,该参数接受在每个切片中绘制图形的自定义函数。它必须有两个参数:
- 当前切片的行/列索引(我们称之为
index
), - 来自 split 变量的与当前切片相对应的水平向量(我们称之为
level
)。当 e.grow_km
仅设置或row_split
仅设置为一个分类变量时,则level
是长度为 1 的向量。如果有多个分类变量用row_km
和设置row_split
,level
则是一个长度与分类变量个数相同的向量。
设置图形时,将忽略 anno_block 中的所有其他图形参数。请参阅以下示例:
col = c("1" = "red", "2" = "blue", "A" = "green", "B" = "orange")
Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) +
rowAnnotation(foo = anno_block(
graphics = function(index, levels) {
grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
txt = paste(levels, collapse = ",")
txt = paste0(txt, "\n", length(index), " rows")
grid.text(txt, 0.5, 0.5, rot = 0,
gp = gpar(col = col[levels[1]]))
},
width = unit(3, "cm")
))
3.5图像标注
图像可以作为注释。anno_image()
支持png
, svg
, pdf
, eps
, jpeg/jpg
,tiff
格式的图像。它们作为注释导入的方式如下:
-
png
、jpeg/jpg
和tiff
图像由png::readPNG()
、jpeg::readJPEG()
和tiff::readTIFF()
导入并由grid::grid.raster()
绘制。 -
svg
图像首先由rsvg::rsvg_svg()重新格式化
,然后由grImport2::readPicture()
导入和grImport2::grid.picture()
绘制。 -
pdf
和eps
图像由grImport::PostScriptTrace()
和grImport::readPicture()
导入,然后由grImport::grid.picture()
绘制。
以下示例的免费图标来自 https://github.com/Keyamoon/IcoMoon-Free。图像路径向量被设置为 的第一个参数anno_image()
。
image_png = sample(dir("IcoMoon-Free-master/PNG/64px", full.names = TRUE), 10)
image_svg = sample(dir("IcoMoon-Free-master/SVG/", full.names = TRUE), 10)
image_eps = sample(dir("IcoMoon-Free-master/EPS/", full.names = TRUE), 10)
image_pdf = sample(dir("IcoMoon-Free-master/PDF/", full.names = TRUE), 10)
# we only draw the image annotation for PNG images, while the others are the same
ha = HeatmapAnnotation(foo = anno_image(image_png))
不同格式的图像可以在输入向量中混合使用。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_image(c(image_png[1:3], image_svg[1:3],
image_eps[1:3], image_pdf[1:3])))
边框和背景颜色(如果图像具有透明背景)可以通过gp
设置。
ha = HeatmapAnnotation(foo = anno_image(image_png,
gp = gpar(fill = 1:10, col = "black")))
border
控制整个边界的注释。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_image(image_png, border = "red"))
图像周围的填充或空间由 space
设置。
ha = HeatmapAnnotation(foo = anno_image(image_png, space = unit(3, "mm")))
如果只需要绘制部分图像,可以将image
向量中的其它元素设置为''
或NA
。
image_png[1:2] = ""
ha = HeatmapAnnotation(foo = anno_image(image_png))
3.6 点注释
点注释anno_points()
为实现显示数据点在列表中的分布。数据点对象x
可以是单个向量或矩阵。如果它是一个矩阵,图形属性设置(例如pch
,size
和gp
)可以关联到矩阵的列。再次注意,如果x
是矩阵,则行x
对应于热图矩阵中的列。
ha = HeatmapAnnotation(foo = anno_points(runif(10)))
ha = HeatmapAnnotation(foo = anno_points(matrix(runif(20), nc = 2),
pch = 1:2, gp = gpar(col = 2:3)))
ylim
控制“y轴”或“数据轴”上的范围(如果是行注释,则数据轴为水平),extend
控制数据轴方向上的扩展空间。axis
控制是否显示轴并控制轴 axis_param
的设置。轴的默认设置为:
default_axis_param("column")
## $at
## NULL
##
## $labels
## NULL
##
## $labels_rot
## [1] 0
##
## $gp
## $fontsize
## [1] 8
##
##
## $side
## [1] "left"
##
## $facing
## [1] "outside"
##
## $direction
## [1] "normal"
你可以覆盖其中的一些:
ha = HeatmapAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
axis_param = list(
side = "right",
at = c(0, 0.5, 1),
labels = c("zero", "half", "one")
))
)
控制轴标签的旋转可能对你有用。
ha = rowAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
width = unit(2, "cm"),
axis_param = list(
side = "bottom",
at = c(0, 0.5, 1),
labels = c("zero", "half", "one"),
labels_rot = 45
))
)
轴的配置与其他具有轴的注释功能相同。
点注释的默认大小为 5mm。它可以由height
/width
中的参数控制 anno_points()
。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_points(runif(10), height = unit(2, "cm")))
3.7 线注释
anno_lines()
通过段列表连接数据点。与 anno_points()
类似,数据变量可以是数值向量:
ha = HeatmapAnnotation(foo = anno_lines(runif(10)))
或矩阵:
ha = HeatmapAnnotation(foo = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)),
gp = gpar(col = 2:3), add_points = TRUE, pt_gp = gpar(col = 5:6), pch = c(1, 16)))
如上所示,可以通过设置将点添加到线中add_points = TRUE
。
通过设置smooth = TRUE
可以添加平滑线(by loess()
)而不是原始线,但应谨慎使用,因为热图中列的顺序用作拟合的“x值”,并且仅当您认为拟合反对重新排序的顺序是有道理的。
当输入数据变量是对每一列单独执行平滑的矩阵时,平滑也有效。
如果smooth
是TRUE
,add_points
则默认设置为TRUE
。
ha = HeatmapAnnotation(foo = anno_lines(runif(10), smooth = TRUE))
线注释的默认大小为 5 毫米。它可以由height
/ 中的width
参数控制 anno_lines()
。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_lines(runif(10), height = unit(2, "cm")))
3.8条形图标注
数据点可以表示为条形图。 anno_barplot()
的一些参数:如ylim
,axis
,axis_param
和 anno_points()
是一样的。
ha = HeatmapAnnotation(foo = anno_barplot(1:10))
条行图的宽度由 bar_width
控制。它是热图中单元格宽度的相对值。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, bar_width = 1))
图形参数由gp
控制。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, gp = gpar(fill = 1:10)))
您可以通过baseline
选择条形的基线。
ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = "min"))
ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = 0))
如果输入值是一个矩阵,它将是堆叠的条形图。
ha = HeatmapAnnotation(foo = anno_barplot(matrix(nc = 2, c(1:10, 10:1))))
gp
参数的长度可以是矩阵中的列数:
ha = HeatmapAnnotation(foo = anno_barplot(cbind(1:10, 10:1),
gp = gpar(fill = 2:3, col = 2:3)))
条形图注释的默认大小为 5 毫米。它可以由height
/width
中的参数控制 anno_barplot()
。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_barplot(runif(10), height = unit(2, "cm")))
以下示例显示了可视化比例矩阵的条形图注释(行总和为 1)。
m = matrix(runif(4*10), nc = 4)
m = t(apply(m, 1, function(x) x/sum(x)))
ha = HeatmapAnnotation(foo = anno_barplot(m, gp = gpar(fill = 2:5),
bar_width = 1, height = unit(6, "cm")))
轴的方向可以反转,这在注释放在热图左侧时很有用。
ha_list = rowAnnotation(axis_reverse = anno_barplot(m, gp = gpar(fill = 2:5),
axis_param = list(direction = "reverse"),
bar_width = 1, width = unit(4, "cm"))) +
rowAnnotation(axis_normal = anno_barplot(m, gp = gpar(fill = 2:5),
bar_width = 1, width = unit(4, "cm")))
draw(ha_list, ht_gap = unit(4, "mm"))
direction = "reverse"
也适用于其他具有轴的注释函数,但它常用于条形图注释。
add_numbers
可以将参数设置为TRUE
,以便在条形顶部绘制与条形关联的数字。对于列注释,文本默认旋转 45 度。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, add_numbers = TRUE,
height = unit(1, "cm")))
3.9箱线图注释
Boxplot注解以及后面介绍的注解函数更适合小矩阵。不适合就有多列矩阵的列注释。
对于anno_boxplot()
,输入数据变量应该是矩阵或列表。如果 x
是矩阵,如果是列注释,则箱线图的统计量按列计算,如果是行注释,则按行计算。
set.seed(12345)
m = matrix(rnorm(100), 10)
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm")))
图形参数由gp
控制。
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"),
gp = gpar(fill = 1:10)))
框的宽度由box_width
控制。outline
控制是否显示离群点。
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"),
box_width = 0.9, outline = FALSE))
anno_boxplot()
只为一行绘制一个箱线图。多个箱线图注释演示了如何定义为单行绘制多个箱线图的注释函数,单个箱线图演示如何为一组行绘制单个箱线图。
3.10直方图标注
作为直方图的注释更适合作为行注释。数据变量的设置与anno_boxplot()
相同,可以是矩阵或列表。
与anno_boxplot()
类似,输入数据变量应该是矩阵或列表。如果 x
是矩阵,如果是列注释,则直方图按列计算,如果是行注释,则直方图按行计算。
m = matrix(rnorm(1000), nc = 100)
ha = rowAnnotation(foo = anno_histogram(m)) # apply `m` on rows
直方图的中断次数由n_breaks
控制。
ha = rowAnnotation(foo = anno_histogram(m, n_breaks = 20))
颜色由gp
控制。
ha = rowAnnotation(foo = anno_histogram(m, gp = gpar(fill = 1:10)))
3.11密度曲线注释
与直方图注释类似,anno_density()
将分布显示为拟合曲线。
ha = rowAnnotation(foo = anno_density(m))
可以控制密度峰值的高度,使分布看起来像一个“joyplot”。
ha = rowAnnotation(foo = anno_density(m, joyplot_scale = 2,
gp = gpar(fill = "#CCCCCC80")))
或者将分布可视化为小提琴图。
ha = rowAnnotation(foo = anno_density(m, type = "violin",
gp = gpar(fill = 1:10)))
当输入变量中有太多行时,正常密度峰值的空间可能太小。在这种情况下,我们可以通过热图可视化分布。
m2 = matrix(rnorm(50*10), nrow = 50)
ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm")))
热图分布的颜色模式由heatmap_colors
控制。
ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm"),
heatmap_colors = c("white", "orange")))
在ComplexHeatmap包中,有一个densityHeatmap()
函数可以将分布可视化为热图。将在密度热图介绍 。
3.12 Joyplot注释
anno_joyplot()
特定于所谓的 Joyplot ( http://blog.revolutionanalytics.com/2017/07/joyplots.html )。输入数据应该是矩阵或列表。
anno_joyplot()
如果输入是矩阵,则注释始终应用于列。因为joyplot可视化了平行分布,矩阵不是必需的格式,列表已经足够了,如果你不确定如何设置为矩阵,只需将其转换为列表来使用它。
m = matrix(rnorm(1000), nc = 10)
lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"),
gp = gpar(fill = 1:10), transparency = 0.75))
或者只显示线条(scale
参数控制曲线的相对高度)。
m = matrix(rnorm(5000), nc = 50)
lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"), gp = gpar(fill = NA),
scale = 4))
输入变量的格式很特殊。它可以是以下两个之一:
- 一个矩阵(记住
anno_joyplot()
总是应用于矩阵的列),其中 x 坐标1:nrow(matrix)
对应于矩阵中的每一列对应于图中的一个分布。 - 一个数据框列表,其中每个数据框有两列对应于 x 坐标和 y 坐标。
3.13地平线图标注
水平线图 作为注释只能添加为行注释。输入变量的格式与上面介绍anno_horizon()
的相同anno_joyplot()
。
地平线图注释的默认样式为:
lt = lapply(1:20, function(x) cumprod(1 + runif(1000, -x/100, x/100)) - 1)
ha = rowAnnotation(foo = anno_horizon(lt))
每个轨道中的值通过 归一化x/max(abs(x))
。
对于正值和负值的颜色是由gpar()
中pos_fill
和neg_fill
控制。
ha = rowAnnotation(foo = anno_horizon(lt,
gp = gpar(pos_fill = "orange", neg_fill = "darkgreen")))
pos_fill
和neg_fill
可以作为向量分配。
ha = rowAnnotation(foo = anno_horizon(lt,
gp = gpar(pos_fill = rep(c("orange", "red"), each = 10),
neg_fill = rep(c("darkgreen", "blue"), each = 10))))
负值的峰值是从底部还是从顶部开始。
ha = rowAnnotation(foo = anno_horizon(lt, negative_from_top = TRUE))
每两个相邻图表之间的空间。
ha = rowAnnotation(foo = anno_horizon(lt, gap = unit(1, "mm")))