ComplexHeatmap复杂热图绘制学习——9.其它软件包

与其他软件包集成

9.1 pheatmap热图

pheatmap用于制作热图是一个很不错的 R 包,启发了许多其他热图包,例如ComplexHeatmap。从ComplexHeatmap 的2.5.2 版本 开始,有一个新ComplexHeatmap::pheatmap()函数,它实际上将所有pheatmap::pheatmap()参数映射到ComplexHeatmap::Heatmap()中,这意味着,它将 pheatmap 转换为复杂热图。通过这样做,最显着的改进是现在您可以添加多个 pheatmap 和注释(由ComplexHeatmap::rowAnnotation()定义)。

ComplexHeatmap::pheatmap()包含所有pheatmap::pheatmap()参数,这意味着,您不需要对 pheatmap 代码进行任何修改,只需重新运行 pheatmap代码,它就会自动并且很好地转换为复杂的热图。

pheatmap::pheatmap()在这个转换中,一些参数被禁用和忽略,列出如下:

  • kmeans_k
  • filename
  • width
  • height
  • silent

剩余参数的用法是完全一样的,如pheatmap::pheatmap()

pheatmap::pheatmap()中,color参数指定颜色向量,例如:

pheatmap::pheatmap(mat, 
    color = colorRampPalette(rev(brewer.pal(n = 7, name = "RdYlBu")))(100)
)

您可以在ComplexHeatmap::pheatmap()中使用color相同的设置,但您也可以将其简化为:

ComplexHeatmap::pheatmap(mat, 
    color = rev(brewer.pal(n = 7, name = "RdYlBu"))
)

各个值的颜色会自动内插。

9.1.1 示例

首先,我们加载一个示例数据集,该数据集来自函数文档的“示例”部分pheatmap::pheatmap()

library(ComplexHeatmap)
test = matrix(rnorm(200), 20, 10)
test[1:10, seq(1, 10, 2)] = test[1:10, seq(1, 10, 2)] + 3
test[11:20, seq(2, 10, 2)] = test[11:20, seq(2, 10, 2)] + 2
test[15:20, seq(2, 10, 2)] = test[15:20, seq(2, 10, 2)] + 4
colnames(test) = paste("Test", 1:10, sep = "")
rownames(test) = paste("Gene", 1:20, sep = "")

调用pheatmap()(现在实际上是ComplexHeatmap::pheatmap())生成与pheatmap::pheatmap()类似的热图。

pheatmap(test)  # this is ComplexHeatmap::pheatmap
image

除了热图图例的样式外,一切看起来都一样。您还可以在本文的“比较”部分中找到其他一些视觉差异。

下一个是设置注释的例子(如果你是pheatmap用户,应该熟悉如何设置这些数据框和颜色列表)。

annotation_col = data.frame(
    CellType = factor(rep(c("CT1", "CT2"), 5)), 
    Time = 1:5
)
rownames(annotation_col) = paste("Test", 1:10, sep = "")

annotation_row = data.frame(
    GeneClass = factor(rep(c("Path1", "Path2", "Path3"), c(10, 4, 6)))
)
rownames(annotation_row) = paste("Gene", 1:20, sep = "")

ann_colors = list(
    Time = c("white", "firebrick"),
    CellType = c(CT1 = "#1B9E77", CT2 = "#D95F02"),
    GeneClass = c(Path1 = "#7570B3", Path2 = "#E7298A", Path3 = "#66A61E")
)
pheatmap(test, annotation_col = annotation_col, annotation_row = annotation_row, 
    annotation_colors = ann_colors)
image

ComplexHeatmap::pheatmap()返回一个Heatmap对象,因此可以将其与其他热图和注释一起添加。或者换句话说,您可以添加多个 pheatmap 和注释。舒服吧!

p1 = pheatmap(test, name = "mat1")
p2 = rowAnnotation(foo = anno_barplot(1:nrow(test)))
p3 = pheatmap(test, name = "mat2", 
    col = colorRampPalette(c("navy", "white", "firebrick3"))(50))
# or you can simply specify as
# p3 = pheatmap(test, name = "mat2", col = c("navy", "white", "firebrick3"))
p1 + p2 + p3
image

尽管如此,如果你真的想添加多个pheatmap,我仍然建议你直接使用该Heatmap()功能。您可以在下一节中找到如何从pheatmap::pheatmap()迁移到ComplexHeatmap::Heatmap()

在前面的示例中,行注释的图例与热图图例的分组。这可以通过legend_groupingdraw()函数中设置参数来修改:

p = pheatmap(test, annotation_col = annotation_col, annotation_row = annotation_row, 
    annotation_colors = ann_colors)
draw(p, legend_grouping = "original")
image

由于ComplexHeatmap::pheatmap()返回一个Heatmap对象,如果pheatmap()不是在交互式环境中调用,例如在 R 脚本中,在函数内或在for循环中,您需要显式使用draw()函数:

for(...) {
    p = pheatmap(...)
    draw(p)
}

9.1.2 转换

下表列出了如何将参数pheatmap::pheatmap()映射到ComplexHeatmap::Heatmap().

pheatmap::pheatmap()参数 ComplexHeatmap::Heatmap() 参数
mat matrix
color 用户可以通过circlize::colorRamp2()指定颜色映射函数,或者提供一个颜色向量,在这些向量上对各个值的颜色进行线性插值。
kmeans_k 没有相应的参数,因为它改变了热图的矩阵。
breaks 它应该在颜色映射函数中指定。
border_color rect_gp = gpar(col = border_color). 在注释中,它是HeatmapAnnotation(..., gp = gpar(col = border_color))
cellwidth width = ncol(mat)*unit(cellwidth, "pt")
cellheight height = nrow(mat)*unit(cellheight, "pt")
scale 在发送到Heatmap()之前,用户应该scale().
cluster_rows cluster_rows
cluster_cols cluster_columns
clustering_distance_rows clustering_distance_rows. 该值correlation应更改为pearson
clustering_distance_cols clustering_distance_columns, 该值correlation应更改为pearson
clustering_method clustering_method_rows/clustering_method_columns
clustering_callback 在发送到Heatmap().
cutree_rows row_split 应该应用于行聚类。
cutree_cols column_split 应该应用于列聚类。
treeheight_row row_dend_width = unit(treeheight_row, "pt")
treeheight_col column_dend_height = unit(treeheight_col, "pt")
legend show_heatmap_legend
legend_breaks heatmap_legend_param = list(at = legend_breaks)
legend_labels heatmap_legend_param = list(labels = legend_labels)
annotation_row left_annotatioin = rowAnnotation(df = annotation_row)
annotation_col top_annotation = HeatmapAnnotation(df = annotation_col)
annotation 不支持。
annotation_colors col参数在HeatmapAnnotation()/ rowAnnotation()中。
annotation_legend show_legend参数在HeatmapAnnotation()/ rowAnnotation()中。
annotation_names_row show_annotation_namerowAnnotation()中。
annotation_names_col show_annotation_nameHeatmaoAnnotation()中。
drop_levels 未使用的级别全部删除。
show_rownames show_row_names
show_colnames show_column_names
main column_title
fontsize gpar(fontsize = fontsize) 在相应的热图组件中。
fontsize_row row_names_gp = gpar(fontsize = fontsize_row)
fontsize_col column_names_gp = gpar(fontsize = fontsize_col)
angle_col column_names_rot. 不支持行注释名称的旋转。
display_numbers 用户应该设置一个适当的cell_fun或者layer_fun(矢量化和更快的版本cell_fun)。例如:如果display_numbersTRUElayer_fun可以设置为function(j, i, x, y, w, h, fill) { grid.text(sprintf(number_format, pindex(mat, i, j)), x = x, y = y, gp = gpar(col = number_color, fontsize = fontsize_number)) }。如果display_numbers是一个矩阵,在layer_fundisplay_numbers取代mat
number_format 看上面。
number_color 看上面。
fontsize_number 看上面。
gaps_row 用户应该构造一个“拆分变量”并发送到row_split. 例如slices = diff(c(0, gaps_row, nrow(mat))); rep(seq_along(slices), times = slices)
gaps_col 用户应该构造一个“拆分变量”并发送到column_split.
labels_row row_labels
labels_col column_labels
filename 中没有相应的设置Heatmap()。用户需要明确使用eg pdf()。
width 中没有相应的设置Heatmap()
height 中没有相应的设置Heatmap()
silent 中没有相应的设置Heatmap()
na_col na_col

9.1.3 比较

我运行了pheatmap::pheatmap()函数文档的“示例”部分 中的所有示例代码。作为比较包装函数ComplexHeatmap::compare_pheatmap(),它们基本上使用pheatmap::pheatmap()ComplexHeatmap::pheatmap()绘制热图时相同的参数集,以便直接看到两个热图实现的异同。

compare_pheatmap(test)
image
compare_pheatmap(test, scale = "row", clustering_distance_rows = "correlation")
image
compare_pheatmap(test, 
    color = colorRampPalette(c("navy", "white", "firebrick3"))(50))
image
compare_pheatmap(test, cluster_row = FALSE)
image
compare_pheatmap(test, legend = FALSE)
image
compare_pheatmap(test, display_numbers = TRUE)
image
compare_pheatmap(test, display_numbers = TRUE, number_format = "%.1e")
image
compare_pheatmap(test, 
    display_numbers = matrix(ifelse(test > 5, "*", ""), nrow(test)))
image
compare_pheatmap(test, cluster_row = FALSE, legend_breaks = -1:4, 
    legend_labels = c("0", "1e-4", "1e-3", "1e-2", "1e-1", "1"))
image
compare_pheatmap(test, cellwidth = 15, cellheight = 12, main = "Example heatmap")
image
annotation_col = data.frame(
    CellType = factor(rep(c("CT1", "CT2"), 5)), 
    Time = 1:5
)
rownames(annotation_col) = paste("Test", 1:10, sep = "")

annotation_row = data.frame(
    GeneClass = factor(rep(c("Path1", "Path2", "Path3"), c(10, 4, 6)))
)
rownames(annotation_row) = paste("Gene", 1:20, sep = "")

compare_pheatmap(test, annotation_col = annotation_col)
image
compare_pheatmap(test, annotation_col = annotation_col, annotation_legend = FALSE)
image
compare_pheatmap(test, annotation_col = annotation_col, 
    annotation_row = annotation_row)
image
compare_pheatmap(test, annotation_col = annotation_col, 
    annotation_row = annotation_row, angle_col = "45")
image
compare_pheatmap(test, annotation_col = annotation_col, angle_col = "0")
image
ann_colors = list(
    Time = c("white", "firebrick"),
    CellType = c(CT1 = "#1B9E77", CT2 = "#D95F02"),
    GeneClass = c(Path1 = "#7570B3", Path2 = "#E7298A", Path3 = "#66A61E")
)

compare_pheatmap(test, annotation_col = annotation_col, 
    annotation_colors = ann_colors, main = "Title")
image
compare_pheatmap(test, annotation_col = annotation_col, 
    annotation_row = annotation_row, annotation_colors = ann_colors)
image
compare_pheatmap(test, annotation_col = annotation_col, 
    annotation_colors = ann_colors[2]) 
image
compare_pheatmap(test, annotation_col = annotation_col, cluster_rows = FALSE, 
    gaps_row = c(10, 14))
image
compare_pheatmap(test, annotation_col = annotation_col, cluster_rows = FALSE, 
    gaps_row = c(10, 14), cutree_col = 2)
image
labels_row = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 
    "", "", "Il10", "Il15", "Il1b")
compare_pheatmap(test, annotation_col = annotation_col, labels_row = labels_row)
image
drows = dist(test, method = "minkowski")
dcols = dist(t(test), method = "minkowski")
compare_pheatmap(test, clustering_distance_rows = drows, 
    clustering_distance_cols = dcols)
image
library(dendsort)
callback = function(hc, ...){dendsort(hc)}
compare_pheatmap(test, clustering_callback = callback)
image

9.2 cowplot

cowplot包被用于多条曲线结合成一个单一的数字。在大多数情况下, ComplexHeatmap可以与cowplot完美配合,但有些情况需要特别注意。

还有一些其他包组合了多个图,例如multipanelfigure,运行的机制是相同的。

ComplexHeatmap中的以下功能会导致使用cowplot时出现问题。

  1. anno_zoom()/ anno_link(): 这两个函数调整的位置依赖于图形设备的大小。
  2. anno_mark(): anno_zoom()。调整后的位置还取决于设备尺寸。
  3. 当图例过多时,图例会被包装成多列。图例位置的计算依赖于设备尺寸。

下面将演示一个使用anno_zoom()的例子。这里的示例来自simplifyEnrichment包,plot显示了GO相似性热图,单词云注释显示了每个组的主要生物功能。

您不需要真正理解以下代码。该ht_clusters() 函数基本上绘制了一个热图,Heatmap()并添加了词云注释anno_zoom()

library(simplifyEnrichment)
set.seed(1234)
go_id = random_GO(500)
mat = GO_similarity(go_id)
cl = binary_cut(mat)
ht_clusters(mat, cl)
image

接下来我们把这个热图作为一个带有cowplot的子图。要与cowplot集成,将热图grid::grid.grabExpr()作为复杂 grob对象捕获。注意这里你需要使用draw()函数来显式地绘制热图。

library(cowplot)
library(grid)
p1 = rectGrob(width = 0.9, height = 0.9)
p2 = grid.grabExpr(ht_clusters(mat, cl))
p3 = rectGrob(width = 0.9, height = 0.9)

plot_grid(p1, 
    plot_grid(p2, p3, nrow = 2, rel_heights = c(4, 1)), 
    nrow = 1, rel_widths = c(1, 9)
)
image

注意!词云注释未对齐。对于grid.grabExpr()函数,应该注意一些细节。它实际上打开了一个默认尺寸为7x7英寸的不可见图形设备(pdf(NULL))。因此,对于这一行:

p2 = grid.grabExpr(ht_clusters(mat, cl))

p2中的词云注释实际上是在7x7英寸的区域内计算的,当它被plot_grid()写回图形时,p2的空间发生了变化,这就是词云注释对齐错误的原因。
另一方面,如果“一个简单的热图”被grid.grabExpr()捕获,例如:

p2 = grid.grabExpr(draw(Heatmap(mat)))

p2放回去时,一切都会正常工作,因为现在所有的热图元素都不依赖于设备大小,并且位置将自动调整到新空间。

这种效果也可以通过在交互式图形设备中绘制热图并通过拖动来调整窗口大小来观察。

解决方法相当简单。由于捕获位置和绘制位置之间的空间不同这种不一致的原因,因此我们只需要捕获要放置的位置相同大小的设备下方的热图。

我们在plot_grid()函数中设置的布局一样,热图占据图形的 9/10 宽度和 4/5 高度。因此,热图空间的宽度和高度计算如下,并分配给 中的widthheight参数grid.grabExpr()

w = convertWidth(unit(1, "npc")*(9/10), "inch", valueOnly = TRUE)
h = convertHeight(unit(1, "npc")*(4/5), "inch", valueOnly = TRUE)
p2 = grid.grabExpr(ht_clusters(mat, cl), width = w, height = h)

plot_grid(p1, 
    plot_grid(p2, p3, nrow = 2, rel_heights = c(4, 1)), 
    nrow = 1, rel_widths = c(1, 9)
)
image

现在一切都恢复正常了!

9.3 网格文本

gridtext包是呈现文本一个很好的和简单的方式电网系统。从ComplexHeatmap 2.3.3 版本开始,与文本相关的元素可以由gridtext呈现。

对于所有与文本相关的元素,文本都需要通过gt_render()函数进行包裹,函数标记文本并添加相关参数,这些参数将被gridtext处理。

目前ComplexHeatmap支持gridtext::richtext_grob(),因此 richtext_grob()可以通过gt_render().

gt_render("foo", r = unit(2, "pt"), padding = unit(c(2, 2, 2, 2), "pt"))
## [1] "foo"
## attr(,"class")
## [1] "gridtext"
## attr(,"param")
## attr(,"param")$r
## [1] 2points
## 
## attr(,"param")$padding
## [1] 2points 2points 2points 2points

对于每个热图元素,例如列标题,图形参数可以通过伴随参数设置,例如 column_title_gp。为了简单起见, 通过添加前缀box_gp来合并所有由box_设置的图形参数,例如:*_gp

..., column_title = gt_render("foo"), column_title_gp = gpar(col = "red", box_fill = "blue"), ...

也可以在里面指定图形参数gt_render()。以下与上述相同:

..., column_title = gt_render("foo", gp = gpar(col = "red", box_fill = "blue")), ...

9.3.1 标题

set.seed(123)
mat = matrix(rnorm(100), 10)
rownames(mat) = letters[1:10]
Heatmap(mat, 
    column_title = gt_render("Some blue text **in bold.**
And *italics text.*
And some large text.", r = unit(2, "pt"), padding = unit(c(2, 2, 2, 2), "pt")), column_title_gp = gpar(box_fill = "orange"))
image

如果热图被分割:

Heatmap(mat, 
    row_km = 2, 
    row_title = gt_render(c("**title1**", "_title2_")), 
    row_title_gp = gpar(box_fill = c("yellow", "blue")))
image

9.3.2 行/列名称

呈现的行/列名称应由row_labels/column_labels指定。

Heatmap(mat, 
    row_labels = gt_render(letters[1:10], padding = unit(c(2, 10, 2, 10), "pt")),
    row_names_gp = gpar(box_col = rep(c("red", "green"), times = 5)))
image

9.3.3 注释标签

annotation_label 参数应该作为呈现的文本。

ha = HeatmapAnnotation(foo = letters[1:10],
    annotation_label = gt_render("**Annotation** _one_",
        gp = gpar(box_col = "black")),
    show_legend = FALSE)
Heatmap(mat, top_annotation = ha)
image

9.3.4 文本标注

rowAnnotation(
    foo = anno_text(gt_render(sapply(LETTERS[1:10], strrep, 10), align_widths = TRUE), 
                    gp = gpar(box_col = "blue", box_lwd = 2), 
                    just = "right", 
                    location = unit(1, "npc")
    )) + Heatmap(mat)
image

9.3.5 图例

Heatmap(mat, 
    heatmap_legend_param = list(
        title = gt_render("**Legend title**"), 
        title_gp = gpar(box_fill = "grey"),
        at = c(-3, 0, 3), 
        labels = gt_render(c("*negative* three", "zero", "*positive* three"))
    ))
image

你可能感兴趣的:(ComplexHeatmap复杂热图绘制学习——9.其它软件包)