legend函数_ComplexHeatmap中legend位置的处理

本文详细介绍了在ComplexHeatmap包的最新版本中,如何自动优化legend的位置,使其适应不同大小和布局的热图。从2.5.4版开始,新增参数和用于控制legend对齐方式,包括在热图中居中、顶部对齐或整图居中。自动调整规则基于legend与其他元素的高度比较。文章通过实例展示了legend如何根据热图、列名和annotation的大小自动排列,甚至在交互式设备中动态调整。
摘要由CSDN通过智能技术生成

在这篇文章中,我将介绍在ComplexHeatmap中legend的位置是如何自动调整的。注意这些新的特性只有在版本2.5.4之后才有。

Legend在热图中看起来好像是很简单的一个部分,只要放在热图的一边就行了。其实在ComplexHeatmap中,legend的处理用了很多代码,也是最麻烦的一个部分。为了让legend的位置看起来更自然,我花了很多时间和精力在它上面。

这篇文章只介绍legend在热图中的位置,关于legend本身的设置,请见ComplexHeatmap的手册。

本文所有的关于legend位置的设置,用户都无需操作。ComplexHeatmap基本上会自动选择合适的位置放置legend。本文的主旨是向大家介绍legend的位置是如何优化的。

在下面的例子中,我使用了一个10x10的随机矩阵。

library(ComplexHeatmap)
set.seed(123)
m = matrix(rnorm(100), 10)

在旧版本中(<= 2.5.3),所有的legend放置在整张图的中间,如下图所示。如果热图下方没有列名的话,整体看起来还不错。下图中,左侧是Heatmap()绘制的结果,右侧加上了各个viewport的位置,这样可以方便观察legend是如何放置在相应的viewport中的。

2800010ca044b34de5f12911f4b80367.png

当我们用热图对特别大的矩阵进行可视化,我们会选择不显示矩阵的列名,那么legend的位置看起来还可以。但是,对于只有少数列的矩阵并且需要将列名显示出来的时候,legend的位置就会很奇怪了。比如在下面的例子中,矩阵包含很长的列名:

colnames(m) = strrep(letters[1:10], 20)

legend看起来远离了热图本身,看起来很糟糕!

e9b6d0d3e745dd2012a4f714b920b720.png

从版本2.5.4开始,在draw()函数中,我新加入了两个参数align_heatmap_legendalign_annotation_legend用来控制legend的位置。其中提供了三个选择:

  • global_center:这和旧版本中保持一致,legend在整张图片中居中对齐。
  • heatmap_center:legend在热图(heatmap body)中居中对齐。
  • heatmap_top:legend对热图(heatmap body)的顶部对齐。

三种不同选择请见如下例子,例如设定align_heatmap_legend

ht = Heatmap(m, name = "mat", 
    column_title = "'global_center'")
draw(ht, align_heatmap_legend = "global_center")

ht = Heatmap(m, name = "mat", 
    column_title = "'heatmap_center'")
draw(ht, align_heatmap_legend = "heatmap_center")

ht = Heatmap(m, name = "mat", 
    column_title = "'heatmap_top'")
draw(ht, align_heatmap_legend = "heatmap_top")
174165274d0fc6dabdc79824dbf9386e.png

尽管你可以手动设置align_heatmap_legendalign_annotation_legend参数,从版本2.5.4开始,其实ComplexHeatmap会根据热图的大小和图片的大小自动选择合适的方法去放置legend。自动选择的规则为(以align_heatmap_legend为例):

  1. 如果legend的高度(如果有多个legend,那么此处为多个legend高度之和)小于热图(heatmap body)的高度,align_heatmap_legend会被设定为"heatmap_center"
  2. 如果legend的高度大于热图的高度,但是小于热图加上其他所有放置在热图下方的元件(例如,dendrogram,annotation, 列名)的高度之和,align_heatmap_legend会被设定为 "heatmap_top"
  3. 其他情形下,align_heatmap_legend被设定为"global_center"

我下面通过一些例子来展示这个自动放置legend是如何进行的。

在第一个例子中,其中包含了两个热图,两个legend的高度之和小于热图的高度,因此legend对于热图居中对齐:

Heatmap(m, name = "mat1") + 
  Heatmap(m, name = "mat2")
1e1738ea3a761c9d0187a150fd10b9ae.png

我加入一个新的热图,现在有三个legend,它们的高度大于热图的高度,因此它们对热图的顶部对齐:

Heatmap(m, name = "mat1") + 
  Heatmap(m, name = "mat2") + 
  Heatmap(m, name = "mat3")
dc606daf393ad0d667a26efdfe6a3562.png

现在我加入第四个热图,四个legned的高度之和大于热图高度加列名高度,因此它们对整张图居中对齐。

Heatmap(m, name = "mat1") + 
  Heatmap(m, name = "mat2") + 
  Heatmap(m, name = "mat3") + 
  Heatmap(m, name = "mat4")
1179ae8d840c5237c086f86f66bc1cae.png

当我们继续添加热图和legend,并且如果legend的高度之和超过整张图片的高度了怎么办?这些legend自动被放到了两列中:

Heatmap(m, name = "mat1") + 
  Heatmap(m, name = "mat2") + 
  Heatmap(m, name = "mat3") + 
  Heatmap(m, name = "mat4") + 
  Heatmap(m, name = "mat5")
7933fa33ab6d40f95b4ecc0094ba3629.png

当有更多更多的legend时,它们会被自动放到多个列中,这样所有的legend都可以被看到:

Heatmap(m, name = "mat1") + 
  Heatmap(m, name = "mat2") + 
  Heatmap(m, name = "mat3") + 
  Heatmap(m, name = "mat4") + 
  Heatmap(m, name = "mat5") + 
  Heatmap(m, name = "mat6") + 
  Heatmap(m, name = "mat7") + 
  Heatmap(m, name = "mat8") + 
  Heatmap(m, name = "mat9") + 
  Heatmap(m, name = "mat10")
ace2d052d935be662757a09ae4d80c63.png

让我们试试同时加入annotation的legend:

ha = HeatmapAnnotation(foo1 = 1:10)
Heatmap(m, name = "mat", top_annotation = ha)
c911d2f328e9d628de4a567adb69dae5.png

在下面例子中,legend被放置在了annotation name下面。

be0c270e1a2f116d6ba22bfde037085a.png
ha = HeatmapAnnotation(foo1 = 1:10, foo2 = 1:10)
Heatmap(m, name = "mat", top_annotation = ha)

但是如果legend太多的话,legend可能会和annotation的name重合,例如:

ha = HeatmapAnnotation(foo1 = 1:10, 
foo2 = 1:10, foo3 = 1:10)
Heatmap(m, name = "mat", top_annotation = ha)
7146ab99a2a9c7ea3c04564ccbe41bda.png

这个不是很好优化,因为如果将legend向右移动,让它们不和annotation name重合的话,那么annotation name下方或者legend的左方会有很大的空白区域,会显得整张图片非常不自然(或者很丑!)。一个解决办法是将annotation name移动到左侧:

ha = HeatmapAnnotation(foo1 = 1:10, 
    foo2 = 1:10, foo3 = 1:10, 
    annotation_name_side = "left")
Heatmap(m, name = "mat", top_annotation = ha)
c1c5b74169556b10f821a77a848acbb5.png

注意这个新的功能也同样适用于放置在热图底部的水平方向的legend。

最后展示一个炫酷的功能。回想一下如果你有很多legend的话,它们的位置会根据图片的大小自动放到多个列中。那么,如果当你直接把热图生成在interactive device中,并且调整窗口大小时,legend的放置也会自动调整!见下面的动图:

8728817e07ca02dfadd0e0a7a0d9c632.gif

可惜的是这个在interactive device中自动调整的功能在Rstudio中并不支持。你只会在Rstudio右下方的figure panel中看到正确的图(可惜那个panel太小),而当你点击“Zoom”或者“Export”时可能会见到legend在不正确的位置,我建议你直接把图片保存到文件中。当然了,如果你没有太多的legend时,你无需担心这些。

既往专辑

30c2c01b8a1cf990d428803188a8b4ae.png

7a623ade53e37fb3279b774301f89b4b.png

1d06f974e4359638ff04d3afe9276e4e.png

03e6375927aa25343f11d4e4d861b0ea.png

e3c08faa2e3dd770952350a6503bcf2d.png

c4091bf77cf103a486ab9e8e79411fde.png

35a48637b56f95d72498ad2c0f5cf018.png

5659252810f0267b70d236d017eb1105.png

147895b23cca18c6c868e7080937f6ee.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值