查看原文
其他

ComplexHeatmap 之 Legends 续(二)

JunJunLab 老俊俊的生信笔记 2022-08-15

点击上方关注我们




匆匆又夏天


这节将结束热图图例的所有内容。

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(00.250.50.751))
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() 函数绘制打包图例。也可以通过 ComplexHeatmap::width()ComplexHeatmap::height() 获得 pd 的大小:

ComplexHeatmap:::width(pd)
## [1] 19.1675555555556mm
ComplexHeatmap:::height(pd)
## [1] 78.6988333333334mm

只需设置 direction = "horizontal" 即可水平排列图例:

pd = packLegend(lgd1, lgd2, lgd3, direction = "horizontal")

packLegend() 的一个特性是,例如如果包装是垂直的,并且包装图例的总和超过 max_height 指定的高度,它将被重新排列为多列布局。在以下示例中,最大高度为 10 厘米。

当所有图例放入多列时, 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(00.250.50.751),
    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()

4、热图和注释图例

热图图例的设置由 Heatmap() 中的 heatmap_legend_param 参数控制。heatmap_legend_param 的值是 Legend() 支持的参数列表:

m = matrix(rnorm(100), 10)
Heatmap(m, name = "mat", heatmap_legend_param = list(
    at = c(-202),
    labels = c("low""zero""high"),
    title = "Some values",
    legend_height = unit(4"cm"),
    title_position = "lefttop-rot"
))

annotation_legend_param 控制注释的图例。由于一个 HeatmapAnnotation 可能包含多个 annotationannotation_legend_param 的值是每个 annotation 的配置列表:

ha = HeatmapAnnotation(foo = runif(10), bar = sample(c("f""m"), 10, replace = TRUE),
    annotation_legend_param = list(
        foo = list(
                title = "Fooooooh",
                at = c(00.51),
                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))

HeatmapAnnotation()中的 show_legendHeatmap() 中的 show_heatmap_legend 控制是否显示图例。注意 show_legend 可以是单个逻辑值、逻辑向量或控制注释子集的命名向量:

ha = HeatmapAnnotation(foo = runif(10),
    bar = sample(c("f""m"), 10, replace = TRUE),
    show_legend = c(TRUEFALSE), # 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"))))

如果值为 字符向量,无论是注释还是热图的单行一列矩阵,图例标签的默认顺序为 sort(unique(value)),如果值为因子,则图例标签的顺序是 levels(value)。记住,可以通过分别在 Heatmap()/HeamtapAnnotation() 函数中的 heatmap_legend_param/annotation_legend_param 中设置 atlabels 参数来微调顺序:

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、添加自定义注释

自定义图例(由Legend()构建)可以通过 draw() 中的 heatmap_legend_list 参数添加到热图图例列表中,注释的图例可以通过 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:1010: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)

6、图例位置

默认情况下,热图图例和注释图例放在 图的右侧。两种图例相对于热图的边可以通过 draw() 函数中的 heatmap_legend_sideannotation_legend_side 参数来控制。可以为两个参数设置的值是左、右、下和上:

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_paramannotation_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")


收官!


代码 我上传到 QQ 群 老俊俊生信交流群 文件夹里。欢迎加入。加我微信我也拉你进 微信群聊 老俊俊生信交流群 哦。

群二维码:


老俊俊微信:




知识星球:



所以今天你学习了吗?

欢迎小伙伴留言评论!

今天的分享就到这里了,敬请期待下一篇!

最后欢迎大家分享转发,您的点赞是对我的鼓励肯定

如果觉得对您帮助很大,赏杯快乐水喝喝吧!



 往期回顾 




ComplexHeatmap 之 Legends

ComplexHeatmap 之 Heatmap List 续(二)

ComplexHeatmap 之 Heatmap List 续(一)

ComplexHeatmap 之 Heatmap List

ComplexHeatmap 之 Heatmap Annotations 续(三)

ComplexHeatmap 之 Heatmap Annotations 续(二)

ComplexHeatmap 之 Heatmap Annotations 续(一)

ComplexHeatmap 之 Heatmap Annotations

ComplexHeatmap 之 A Single Heatmap 续(二)

ComplexHeatmap 之 A Single Heatmap 续(一)

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存