图例
默认情况下,热图和简单注释会自动生成图例,生成的图例放在热图的右侧。复杂注释没有图例,但可以手动构建和添加它们。所有图例都是由构造函数Legend()
内部构造的 。在后面的部分中,我们首先介绍了连续图例和离散图例的设置,然后我们将讨论如何配置与热图和注释关联的图例,以及如何将新图例添加到图中。
所有的图例(无论是单个图例还是一组图例)都属于Legends
类。该类只有一个槽位grob
,它是真实 grid::grob
对象或grid::gTree
记录如何绘制图形的对象。Legends
类的包装和类设计的方法使图例成为单个对象,并且可以像点一样绘制在指定视图上的一个位置。
热图和注释的图例可以由 Heatmap()
中的heatmap_legend_param
参数或HeatmapAnnotation()
中的annotation_legend_param
参数控制。函数Legend()
中的大部分参数都可以直接设置在参数名称相同的两个参数中。设置热图图例和注释图例参数的详细信息在第5.4
节中介绍。
5.1连续图例
由于大多数热图包含连续值,我们首先介绍连续图例的设置。
连续图例需要一个颜色映射函数,它应该由 circlize::colorRamp2()
. 在自动生成的热图图例和注释图例中, 从Heatmap()
或HeatmapAnnotation()
函数通过col
参数传递颜色映射函数 ,而如果您构建自定义图例,则需要提供颜色映射函数。
颜色映射函数中提供的中断值(例如 c(0, 0.5, 1)
在以下示例中)将与图例中的中断值不完全相同)。图例中显示的最终中断值经过内部调整,使标签数量接近 5 或 6。
首先我们展示一个垂直连续图例的默认样式:
library(circlize)
col_fun = colorRamp2(c(0, 0.5, 1), c("blue", "white", "red"))
lgd = Legend(col_fun = col_fun, title = "foo")
lgd
是一个Legends
类对象。图例的大小可以通过ComplexHeatmap:::width()
和ComplexHeatmap:::height()
函数获得 。
ComplexHeatmap:::width(lgd)
## [1] 9.90361111111111mm
ComplexHeatmap:::height(lgd)
## [1] 30.2744052165491mm
图例实际上是一个由矩形、线条和文本组成的图形对象。它可以通过draw()
函数添加到绘图中。在 ComplexHeatmap包中,您不需要直接在图例对象上使用draw()
,但如果您在其他地方使用图例对象,它可能会很有用。
pushViewport(viewport(width = 0.9, height = 0.9))
grid.rect() # border
draw(lgd, x = unit(1, "cm"), y = unit(1, "cm"), just = c("left", "bottom"))
draw(lgd, x = unit(0.5, "npc"), y = unit(0.5, "npc"))
draw(lgd, x = unit(1, "npc"), y = unit(1, "npc"), just = c("right", "top"))
popViewport()
如果您只想配置热图或注释生成的图例,则无需Legends
自行构建对象。 后面介绍的参数可以直接通过Heatmap()
中的参数heatmap_legend_param
和 自定义图例HeatmapAnnotation()
中的参数annotation_legend_param
(5.4
节介绍 )。在以下示例中看到这些参数如何改变图例的样式后效果依然很好。以下是一个简单的示例,展示了如何在热图和热图注释中配置图例。
Heatmap(matrix(rnorm(100), 10),
heatmap_legend_param = list(
title = "rnorm", at = c(-2, 0, 2),
labels = c("neg_two", "zero", "pos_two")
),
top_annotation = HeatmapAnnotation(
foo = 1:10,
annotation_legend_param = list(foo = list(title = "foo_top_anno"))
))
在下面的例子中,我们只展示了如何构造图例对象,而不展示绘制图例的代码。只记得你可以在Legends
对象上使用draw()
函数在图上绘制单个图例。
对于连续图例,您可以通过设置手动调整图例中的中断值at
。注意高度是自动调整的。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.25, 0.5, 0.75, 1))
中断值对应的标签由labels
设置。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.5, 1),
labels = c("low", "median", "high"))
垂直连续图例的高度由legend_height
设置。 legend_height
只能为垂直连续图例设置,值为图例主体的高度(不包括图例标题)。
lgd = Legend(col_fun = col_fun, title = "foo", legend_height = unit(6, "cm"))
如果是垂直图例,则grid_width
控制图例主体的宽度。grid_width
最初是为离散图例设计的,其中图例中的每个级别都是一个网格,但在这里我们对控制图例宽度的参数使用相同的名称。
lgd = Legend(col_fun = col_fun, title = "foo", grid_width = unit(1, "cm"))
标签的图形参数由labels_gp
控制。
lgd = Legend(col_fun = col_fun, title = "foo", labels_gp = gpar(col = "red", font = 3))
图例的边框以及中断值的刻度由border控制
。border
的值可以是逻辑值或颜色字符串。
lgd = Legend(col_fun = col_fun, title = "foo", border = "red")
title_position
控制标题的位置。对于垂直的图例,这个值应该是一个topleft
,topcenter
,lefttop-rot
和 leftcenter-rot
。以下两张图显示了lefttop-rot
标题和leftcenter-rot
标题的效果。
lgd = Legend(col_fun = col_fun, title = "foooooooo", title_position = "lefttop-rot",
legend_height = unit(4, "cm"))
lgd = Legend(col_fun = col_fun, title = "foooooooo", title_position = "leftcenter-rot",
legend_height = unit(4, "cm"))
图例标题和标签可以设置为数学公式。
lgd = Legend(col_fun = col_fun, title = expression(hat(beta) == (X^t * X)^{-1} * X^t * y),
at = c(0, 0.25, 0.5, 0.75, 1), labels = expression(alpha, beta, gamma, delta, epsilon))
可以使用gridtext包(gridtext)添加更复杂的文本。
lgd = Legend(col_fun = col_fun,
title = gt_render("<span style='color:orange'>**Legend title**</span>"),
title_gp = gpar(box_fill = "grey"),
at = c(-3, 0, 3),
labels = gt_render(c("<span style='color:blue'>*negative*</span> three", "zero",
"<span style='color:red'>*positive*</span> three"))
)
用于水平连续图例设置是几乎相同的垂直图例,所不同的是现在控制图例的宽度,legend_width
和标题位置只能topcenter
,topleft
,lefttop
和 leftcenter
之一。
水平图例的默认样式:
lgd = Legend(col_fun = col_fun, title = "foo", direction = "horizontal")
手动设置at
:
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.25, 0.5, 0.75, 1),
direction = "horizontal")
手动设置labels
:
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.5, 1),
labels = c("low", "median", "high"), direction = "horizontal")
设置legend_width
:
lgd = Legend(col_fun = col_fun, title = "foo", legend_width = unit(6, "cm"),
direction = "horizontal")
设置标签的图形参数:
lgd = Legend(col_fun = col_fun, title = "foo", labels_gp = gpar(col = "red", font = 3),
direction = "horizontal")
设置标签的旋转。
lgd = Legend(col_fun = col_fun, title = "foo", labels_rot = 45,
direction = "horizontal")
标题可以设置为topleft
,topcenter
或lefttop
和leftcenter
。
lgd = Legend(col_fun = col_fun, title = "foooooooo", direction = "horizontal",
title_position = "topcenter")
lgd = Legend(col_fun = col_fun, title = "foooooooo", direction = "horizontal",
title_position = "lefttop")
在我们上面展示的例子中,每两个中断值之间的间隔是相等的。实际上at
也可以设置为间隔不等的中断值。在这种情况下,图例上的刻度仍然在原始位置,而相应的文本被移动以消除重叠。然后,有连接刻度线和标签的线。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1))
如果标签不需要调整,它们仍然在原来的地方。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.3, 1),
legend_height = unit(4, "cm"))
水平图例类似:
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
direction = "horizontal")
将标签的旋转设置为 90 度。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
direction = "horizontal", title_position = "lefttop", labels_rot = 90)
当标题位置设置为lefttop
时,在计算标签调整位置时也会考虑标题下方的区域。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.5, 0.75, 1),
labels = c("mininal", "q10", "median", "q75", "maximal"),
direction = "horizontal", title_position = "lefttop")
如果按降序设置at
,则图例反转,即 最小值 在图例的顶部。
lgd = Legend(col_fun = col_fun, title = "foo", at = c(1, 0.8, 0.6, 0.4, 0.2, 0))
大多数连续的图例都有等距的图例中断, 例如,第一次和第二次中断之间的距离与第二次和第三次中断之间的距离相同。但是,仍然存在一些特殊情况,如何设置不等距的图例中断呢?
在以下示例中,颜色映射函数col_fun_prop
将比例值可视化为c(0, 0.05, 0.1, 0.5, 1)
中的中断。距离不等的图例中断可能反映了c(0, 1)
中值的不同重要性。例如,也许我们想在c(0, 0.1)
中查看更多详细信息。
以下是图例的默认样式,其中从 0 到 1 以相等的距离选择中断。
col_fun_prop = colorRamp2(c(0, 0.05, 0.1, 0.5, 1),
c("green", "white", "red", "black", "blue"))
lgd = Legend(col_fun = col_fun_prop, title = "Prop")
你看不到c(0, 0.1)
间隔中的细节,因为设置中断colorRamp2()
仅定义了颜色映射,而不能确定图例中的中断。
如果我们手动选择中断值,颜色条保持不变。标签被移动,线将它们连接到原始位置。在这种情况下,颜色条中的距离仍然与中断值的实际差异成正比,即 0.5-1 之间的距离是 0-0.1 的五倍。
col_fun_prop = colorRamp2(c(0, 0.05, 0.1, 0.5, 1),
c("green", "white", "red", "black", "blue"))
lgd = Legend(col_fun = col_fun_prop, title = "Prop",
at = c(0, 0.05, 0.1, 0.5, 1))
从版本 2.7.1 开始,Legend()
函数有一个新参数break_dist
,用于控制图例中两个相邻中断值之间的距离。 可能会令人困惑,但从这里开始,当提到“中断距离”时,它总是指图例中的视觉距离。
break_dist
的值的长度应为 1,这意味着所有中断值在图例中的距离相等,或者length(at) - 1
.
lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = 1)
在下面的示例中,顶部的两个中断间隔比底部的两个间隔长三倍。
lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = c(1, 1, 3, 3))
如果我们通过legend_height
参数增加图例高度,标签将有足够的空间,它们的位置不再调整。
lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = c(1, 1, 3, 3),
legend_height = unit(4, "cm"))
想象以下用户案例,我们想对c(0, 0.1)
中的值使用一种颜色方案,对c(0.1, 1)
中的值使用第二种颜色方案,进而强调这两个区间非常不同。颜色映射可以定义为:
col_fun2 = colorRamp2(c(0, 0.1, 0.1+1e-6, 1), c("white", "red", "yellow", "blue"))
所以在这里我只是在(1e-6
)到 0.1 上添加了一个微小的偏移,并将其设置为第二个配色方案的下限。图例如下:
lgd = Legend(col_fun = col_fun2, title = "Prop", at = c(0, 0.05, 0.1, 0.5, 1),
break_dist = c(1, 1, 3, 3), legend_height = unit(4, "cm"))
现在您可以看到颜色从 0 到 1 并没有平滑地变化,并且有两种不同的配色方案。
5.2 离散图例
离散图例用于离散颜色映射。通过仅提供颜色和中断值,连续颜色映射也可以变化为离散颜色映射。
您可以指定at
或labels
,但最有可能指定 labels
。颜色应由legend_gp
指定。
lgd = Legend(at = 1:6, title = "foo", legend_gp = gpar(fill = 1:6))
lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6))
连续颜色映射的离散图例:
at = seq(0, 1, by = 0.2)
lgd = Legend(at = at, title = "foo", legend_gp = gpar(fill = col_fun(at)))
标题位置:
lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6),
title_position = "lefttop")
lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6),
title_position = "leftcenter-rot")
网格的大小由grid_width
和grid_height
控制。
lgd = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "foo",
grid_height = unit(1, "cm"), grid_width = unit(5, "mm"))
标签的图形参数由labels_gp
控制。
lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo",
labels_gp = gpar(col = "red", fontsize = 14))
标题的图形参数由title_gp
控制。
lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo",
title_gp = gpar(col = "red", fontsize = 14))
通过结合gridtext包,标题和标签可以是复杂的文本(拓展知识):
lgd = Legend(
title = gt_render("<span style='color:orange'>**Legend title**</span>"),
title_gp = gpar(box_fill = "grey"),
at = c(-3, 0, 3),
labels = gt_render(c("**negative** three", "*zero*", "**positive** three")),
legend_gp = gpar(fill = 1:3)
)
网格的边界由border
控制。
lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo",
border = "red")
您可以将离散图例的网格排列成多行或者多列。如果ncol
设置为数字,则网格按ncol
列排列。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10),
title = "foo", ncol = 3)
仍然根据多列图例计算标题位置。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo",
ncol = 3, title_position = "topcenter")
您可以通过设置by_row = TRUE
来选择按行列出图例级别。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo",
ncol = 3, by_row = TRUE)
两列之间的间隙由gap
或column_gap
控制。这两个参数的处理方式相同。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo",
ncol = 3, gap = unit(1, "cm"))
行之间的间隙由row_gap
控制。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo",
ncol = 3, row_gap = unit(5, "mm"))
您还可以通过nrow
指定布局代替ncol
。但请注意,不能同时使用ncol
和nrow
。
lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10),
title = "foo", nrow = 3)
一种极端情况是所有级别都放在一排并且标题旋转 90 度。图例的高度将是旋转标题的高度。
lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foooooo",
nrow = 1, title_position = "lefttop-rot")
很多人可能会喜欢以下风格:
lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foooooo",
nrow = 1, title_position = "leftcenter")
Legend()
还支持使用简单的图形(例如点、线、箱线图)作为图例。type
参数可以指定为points
或者p
,可以使用数字或单字母作为pch
。
lgd = Legend(labels = month.name[1:6], title = "foo", type = "points",
pch = 1:6, legend_gp = gpar(col = 1:6), background = "#FF8080")
lgd = Legend(labels = month.name[1:6], title = "foo", type = "points",
pch = letters[1:6], legend_gp = gpar(col = 1:6), background = "white")
设置type = "lines"
/type = "l"
使用线条作为图例:
lgd = Legend(labels = month.name[1:6], title = "foo", type = "lines",
legend_gp = gpar(col = 1:6, lty = 1:6), grid_width = unit(1, "cm"))
设置type = "boxplot"
/type = "box"
使用箱线图作为图例:
lgd = Legend(labels = month.name[1:6], title = "foo", type = "boxplot",
legend_gp = gpar(fill = 1:6))
当pch
是整数时,其中的数字26:28
对应以下符号:
lgd = Legend(labels = paste0("pch = ", 26:28), type = "points", pch = 26:28)
在上面显示的所有示例中,标签都是单行。还支持多行标签。如以下示例所示,多线标签的图例网格会自动延长。
lgd = Legend(labels = c("aaaaa\naaaaa", "bbbbb\nbbbbb", "c", "d"),
legend_gp = gpar(fill = 1:4))
如果图例排列成多行或多列,则图例网格的大小将调整为行数最多的标签。
lgd = Legend(labels = c("aaaaa\naaaaa", "c", "d", "bbbbb\nbbbbb"),
legend_gp = gpar(fill = 1:4), nrow = 2)
最后一个有用的参数graphics
可用于自定义图例图形。graphics
的值是一个带有四个参数的函数列表:x
和y
:图例网格的中心,w
和h
:图例网格的宽度和高度。of 的长度graphics
应与at
或labels
相同。如果graphics
名称对应命名列表 labels
,则graphics
自动调整列表的顺序。
lgd = Legend(labels = letters[1:4],
graphics = list(
function(x, y, w, h) grid.rect(x, y, w*0.33, h, gp = gpar(fill = "red")),
function(x, y, w, h) grid.rect(x, y, w, h*0.33, gp = gpar(fill = "blue")),
function(x, y, w, h) grid.text("A", x, y, gp = gpar(col = "darkgreen")),
function(x, y, w, h) grid.points(x, y, gp = gpar(col = "orange"), pch = 16)
))
5.3 图例列表
图例列表可以构建或打包为一个Legends
对象,其中各个图例在特定布局内排列。图例列表可以单独发送packLegend()
或作为列表发送。图例可以垂直或水平排列。在**ComplexHeatmap **内部使用packLegend()
来排列多个图例。通常您不需要手动控制多个图例的排列,但如果您想手动构建图例列表并应用于其他图,以下部分将非常有用。
lgd1 = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "legend1")
lgd2 = Legend(col_fun = col_fun, title = "legend2", at = c(0, 0.25, 0.5, 0.75, 1))
lgd3 = Legend(labels = month.name[1:3], legend_gp = gpar(fill = 7:9), title = "legend3")
pd = packLegend(lgd1, lgd2, lgd3)
# which is same as
pd = packLegend(list = list(lgd1, lgd2, lgd3))
与单个图例类似,您可以按draw()
功能绘制打包图例。您还可以获得pd
byComplexHeatmap:::width()
和 的大小ComplexHeatmap:::height()
。
ComplexHeatmap:::width(pd)
## [1] 19.1675555555556mm
ComplexHeatmap:::height(pd)
## [1] 78.6988333333334mm
通过设置水平排列图例,只需direction = "horizontal"
。
pd = packLegend(lgd1, lgd2, lgd3, direction = "horizontal")
packLegend()
的一个特点是,例如,如果包装是垂直的并且包装图例的总和超过了指定的高度max_height
,它将被重新排列为多列布局。在以下示例中,最大高度为10cm
。
当所有图例放入多列时,column_gap
控制两列之间的空间。
pd = packLegend(lgd1, lgd3, lgd2, lgd3, lgd2, lgd1, max_height = unit(10, "cm"),
column_gap = unit(1, "cm"))
类似于水平包装:
lgd1 = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "legend1",
nr = 1)
lgd2 = Legend(col_fun = col_fun, title = "legend2", at = c(0, 0.25, 0.5, 0.75, 1),
direction = "horizontal")
pd = packLegend(lgd1, lgd2, lgd3, lgd1, lgd2, lgd3, max_width = unit(10, "cm"),
direction = "horizontal", column_gap = unit(5, "mm"), row_gap = unit(1, "cm"))
打包的图例pd
也是一个Legends
对象,这意味着您可以通过指定位置来绘制draw()
它。
pd = packLegend(lgd1, lgd2, lgd3, direction = "horizontal")
pushViewport(viewport(width = 0.8, height = 0.8))
grid.rect()
draw(pd, x = unit(1, "cm"), y = unit(1, "cm"), just = c("left", "bottom"))
draw(pd, x = unit(1, "npc"), y = unit(1, "npc"), just = c("right", "top"))
popViewport()
再次重申,packLegend()
在内部用于管理热图和注释图例列表。
5.4 热图和注释图例
热图图例的设置由Heatmap()
中的heatmap_legend_param
参数控制。Legend()
的值是支持的参数列表heatmap_legend_param
。
m = matrix(rnorm(100), 10)
Heatmap(m, name = "mat", heatmap_legend_param = list(
at = c(-2, 0, 2),
labels = c("low", "zero", "high"),
title = "Some values",
legend_height = unit(4, "cm"),
title_position = "lefttop-rot"
))
annotation_legend_param
控制注释的图例。由于一个 HeatmapAnnotation
可能包含多个注释,因此annotation_legend_param
的值是每个注释的配置列表。
ha = HeatmapAnnotation(foo = runif(10), bar = sample(c("f", "m"), 10, replace = TRUE),
annotation_legend_param = list(
foo = list(
title = "Fooooooh",
at = c(0, 0.5, 1),
labels = c("zero", "median", "one")
),
bar = list(
title = "Baaaaaaar",
at = c("f", "m"),
labels = c("Female", "Male")
)
))
Heatmap(m, name = "mat", top_annotation = ha)
如果热图是水平连接的,则所有热图和行注释图例都被分组,所有列注释图例都被分组。我们假设水平方向作为主要信息,而垂直方向提供次要信息。
ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
Heatmap(m, name = "mat1", top_annotation = ha1) +
rowAnnotation(sth = runif(10)) +
Heatmap(m, name = "mat2", top_annotation = ha2)
类似地,如果热图垂直连接,则所有热图的列注释都被分组,所有行注释的图例也被分组。
ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE),
annotation_name_side = "left")
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
Heatmap(m, name = "mat1", top_annotation = ha1) %v%
Heatmap(m, name = "mat2", top_annotation = ha2,
right_annotation = rowAnnotation(sth = 1:10))
show_legend
在HeatmapAnnotation()
中 和show_heatmap_legend
在 Heatmap()
中控制是否显示图例。注意:show_legend
可以是单个逻辑值、逻辑向量或控制注释子集的命名向量。
ha = HeatmapAnnotation(foo = runif(10),
bar = sample(c("f", "m"), 10, replace = TRUE),
show_legend = c(TRUE, FALSE), # it can also be show_legend = c(bar = FALSE)
annotation_name_side = "left")
Heatmap(m, name = "mat1", top_annotation = ha) +
Heatmap(m, name = "mat2", show_heatmap_legend = FALSE)
在draw()
中的merge_legend
函数控制是否将所有图例合并为一个组。通常,当注释和热图很多时,图例的数量总是很大。在这种情况下,图例会自动排列成多列(或多行,如果它们放在热图的底部)以摆脱图形页面。如果热图有热图注释,放置图例的顺序是:左注释的图例,顶部注释的图例,热图的图例,底部注释的图例和右注释的图例。
ha1 = HeatmapAnnotation(foo1 = runif(10),
bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = rowAnnotation(foo2 = runif(10),
bar2 = sample(letters[1:3], 10, replace = TRUE))
ha3 = rowAnnotation(foo3 = runif(10),
bar3 = sample(month.name[1:3], 10, replace = TRUE))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) +
Heatmap(m, name = "mat2", left_annotation = ha2) +
ha3
draw(ht_list, merge_legend = TRUE)
如果您希望热图图例成为“纯热图图例”,您可以设置 legend_grouping = "original"
强制将所有注释图例放在一起,无论它们是行注释图例还是列注释图例。
draw(ht_list, legend_grouping = "original")
通过设置color_bar = "discrete"
,连续颜色映射可以具有离散图例,均适用于热图图例和注释图例。
Heatmap(m, name = "mat", heatmap_legend_param = list(color_bar = "discrete"),
top_annotation = HeatmapAnnotation(foo = 1:10,
annotation_legend_param = list(
foo = list(color_bar = "discrete"))))
如果value
是字符向量,无论是注释还是热图的单行一列矩阵,图例标签的默认顺序都是sort(unique(value))
,如果value
是因子,则图例标签的顺序是levels(value)
。永远记住顺序可以分别通过Heatmap()
在heatmap_legend_param()
/ annotation_legend_param()
/HeamtapAnnotation()
函数中设置at
和labels
参数进行微调。
chr = sample(letters[1:3], 10, replace = TRUE)
chr
## [1] "a" "c" "b" "a" "c" "a" "a" "c" "c" "b"
fa1 = factor(chr)
fa2 = factor(chr, levels = c("c", "a", "b"))
Heatmap(m, top_annotation = HeatmapAnnotation(chr = chr, fa1 = fa1, fa2 = fa2, fa3 = fa2,
annotation_legend_param = list(fa3 = list(at = c("b", "c", "a")))))
5.5 添加自定义图例
自定义图例(由Legend()
构造)可以通过heatmap_legend_list
参数添加到热图图例列表draw()
中,注释的图例可以通过annotation_legend_list
参数添加到注释图例列表中 。
在 拓展知识 中有一个很好的添加自定义图例的例子 ,但这里我们展示一个简单的例子。
如前所述,只有热图和简单的注释才能在图上生成图例。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 = 4:5, 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"), row_km = 2)
接下来,我们为点、线和箱线图构建图例。
lgd_list = list(
Legend(labels = c("red", "green"), title = "pt", type = "points", pch = 16,
legend_gp = gpar(col = 2:3)),
Legend(labels = c("darkblue", "lightblue"), title = "ln", type = "lines",
legend_gp = gpar(col = 4:5, 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)
5.6 边缘图例
默认情况下,热图图例和注释图例放在图的右侧。两种类型图例的热图相对的一侧可以由函数draw()
中的heatmap_legend_side
和annotation_legend_side
参数控制。可以为两个参数设置的值是 left
,right
,bottom
和top
。
m = matrix(rnorm(100), 10)
ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) +
rowAnnotation(sth = runif(10)) +
Heatmap(m, name = "mat2", top_annotation = ha2)
draw(ht_list, heatmap_legend_side = "left", annotation_legend_side = "bottom")
当图例放在底部或顶部时,图例水平排列。我们可能还需要设置每一个图例的水平图例,这需要通过设置Heatmap()
和HeatmapAnnotation()
函数中的heatmap_legend_param
和 annotation_legend_param
参数:
ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE),
annotation_legend_param = list(
foo1 = list(direction = "horizontal"),
bar1 = list(nrow = 1)))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE),
annotation_legend_param = list(
foo2 = list(direction = "horizontal"),
bar2 = list(nrow = 1)))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1,
heatmap_legend_param = list(direction = "horizontal")) +
rowAnnotation(sth = runif(10),
annotation_legend_param = list(sth = list(direction = "horizontal"))) +
Heatmap(m, name = "mat2", top_annotation = ha2,
heatmap_legend_param = list(direction = "horizontal"))
draw(ht_list, merge_legend = TRUE, heatmap_legend_side = "bottom",
annotation_legend_side = "bottom")