与其他软件包集成
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
除了热图图例的样式外,一切看起来都一样。您还可以在本文的“比较”部分中找到其他一些视觉差异。
下一个是设置注释的例子(如果你是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)
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
尽管如此,如果你真的想添加多个pheatmap,我仍然建议你直接使用该Heatmap()
功能。您可以在下一节中找到如何从pheatmap::pheatmap()
迁移到ComplexHeatmap::Heatmap()
。
在前面的示例中,行注释的图例与热图图例的分组。这可以通过legend_grouping
在draw()
函数中设置参数来修改:
p = pheatmap(test, annotation_col = annotation_col, annotation_row = annotation_row,
annotation_colors = ann_colors)
draw(p, legend_grouping = "original")
由于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_name 在rowAnnotation() 中。 |
annotation_names_col |
show_annotation_name 在HeatmaoAnnotation() 中。 |
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_numbers 是TRUE ,layer_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_fun 以display_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)
compare_pheatmap(test, scale = "row", clustering_distance_rows = "correlation")
compare_pheatmap(test,
color = colorRampPalette(c("navy", "white", "firebrick3"))(50))
compare_pheatmap(test, cluster_row = FALSE)
compare_pheatmap(test, legend = FALSE)
compare_pheatmap(test, display_numbers = TRUE)
compare_pheatmap(test, display_numbers = TRUE, number_format = "%.1e")
compare_pheatmap(test,
display_numbers = matrix(ifelse(test > 5, "*", ""), nrow(test)))
compare_pheatmap(test, cluster_row = FALSE, legend_breaks = -1:4,
legend_labels = c("0", "1e-4", "1e-3", "1e-2", "1e-1", "1"))
compare_pheatmap(test, cellwidth = 15, cellheight = 12, main = "Example heatmap")
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)
compare_pheatmap(test, annotation_col = annotation_col, annotation_legend = FALSE)
compare_pheatmap(test, annotation_col = annotation_col,
annotation_row = annotation_row)
compare_pheatmap(test, annotation_col = annotation_col,
annotation_row = annotation_row, angle_col = "45")
compare_pheatmap(test, annotation_col = annotation_col, angle_col = "0")
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")
compare_pheatmap(test, annotation_col = annotation_col,
annotation_row = annotation_row, annotation_colors = ann_colors)
compare_pheatmap(test, annotation_col = annotation_col,
annotation_colors = ann_colors[2])
compare_pheatmap(test, annotation_col = annotation_col, cluster_rows = FALSE,
gaps_row = c(10, 14))
compare_pheatmap(test, annotation_col = annotation_col, cluster_rows = FALSE,
gaps_row = c(10, 14), cutree_col = 2)
labels_row = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "Il10", "Il15", "Il1b")
compare_pheatmap(test, annotation_col = annotation_col, labels_row = labels_row)
drows = dist(test, method = "minkowski")
dcols = dist(t(test), method = "minkowski")
compare_pheatmap(test, clustering_distance_rows = drows,
clustering_distance_cols = dcols)
library(dendsort)
callback = function(hc, ...){dendsort(hc)}
compare_pheatmap(test, clustering_callback = callback)
9.2 cowplot
cowplot包被用于多条曲线结合成一个单一的数字。在大多数情况下, ComplexHeatmap可以与cowplot完美配合,但有些情况需要特别注意。
还有一些其他包组合了多个图,例如multipanelfigure,运行的机制是相同的。
ComplexHeatmap中的以下功能会导致使用cowplot时出现问题。
-
anno_zoom()
/anno_link()
: 这两个函数调整的位置依赖于图形设备的大小。 -
anno_mark()
:anno_zoom()
。调整后的位置还取决于设备尺寸。 - 当图例过多时,图例会被包装成多列。图例位置的计算依赖于设备尺寸。
下面将演示一个使用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)
接下来我们把这个热图作为一个带有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)
)
注意!词云注释未对齐。对于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 高度。因此,热图空间的宽度和高度计算如下,并分配给 中的width
和 height
参数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)
)
现在一切都恢复正常了!
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"))
如果热图被分割:
Heatmap(mat,
row_km = 2,
row_title = gt_render(c("**title1**", "_title2_")),
row_title_gp = gpar(box_fill = c("yellow", "blue")))
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)))
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)
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)
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"))
))