ComplexHeatmap复杂热图绘制学习——2.单个热图(一)

单个热图

单个热图是最常用的数据可视化方法。虽然ComplexHeatmap包的“亮点”在于它可以同时高效可视化一个热图列表,作为热图列表的基本单元,配置好单个热图是很重要的。

首先生成一个3行3列的随机矩阵:

set.seed(123)
nr1 = 4; nr2 = 8; nr3 = 6; nr = nr1 + nr2 + nr3
nc1 = 6; nc2 = 8; nc3 = 10; nc = nc1 + nc2 + nc3
mat = cbind(rbind(matrix(rnorm(nr1*nc1, mean = 1,   sd = 0.5), nr = nr1),
          matrix(rnorm(nr2*nc1, mean = 0,   sd = 0.5), nr = nr2),
          matrix(rnorm(nr3*nc1, mean = 0,   sd = 0.5), nr = nr3)),
    rbind(matrix(rnorm(nr1*nc2, mean = 0,   sd = 0.5), nr = nr1),
          matrix(rnorm(nr2*nc2, mean = 1,   sd = 0.5), nr = nr2),
          matrix(rnorm(nr3*nc2, mean = 0,   sd = 0.5), nr = nr3)),
    rbind(matrix(rnorm(nr1*nc3, mean = 0.5, sd = 0.5), nr = nr1),
          matrix(rnorm(nr2*nc3, mean = 0.5, sd = 0.5), nr = nr2),
          matrix(rnorm(nr3*nc3, mean = 1,   sd = 0.5), nr = nr3))
   )
mat = mat[sample(nr, nr), sample(nc, nc)] # random shuffle rows and columns
rownames(mat) = paste0("row", seq_len(nr))
colnames(mat) = paste0("column", seq_len(nc))

以下命令包含Heatmap()函数的默认参数,可视化得到的热图。与其他热图工具非常相似,它绘制树状图、行/列名称和热图图例。默认颜色模式是“蓝白红”,它映射到矩阵中的最小值到最大值。图例的标题默认分配有内部索引号。

Heatmap(mat)
image.png

默认情况下,图例的标题根据热图的“名称”命名。每个热图都有一个名称,就像热图的唯一标识符一样,在制作热图列表时非常有用。(热图名称用于设置“主要热图”,用于热图的装饰。)如果未指定名称,则会以matrix_%d.

2.1 颜色

对于热图可视化,颜色是数据矩阵的主要展现形式。在大多数情况下,热图将具有连续数值的矩阵可视化。在该情况下,用户也可以自行提供颜色映射函数。颜色映射函数应该接受一个值向量并返回一个相应颜色的向量。Heatmap()中,Heatmap可以使用circlize::colorRamp2() 函数生成的颜色映射函数colorRamp2()的两个参数是一个中断值向量和一个相应颜色的向量。colorRamp2()通过 LAB 颜色空间在每个间隔中线性插入颜色。还使用colorRamp2()帮助生成带有适当刻度线的图例。

在下面的示例中,-2 和 2 之间的值被线性插值以获得相应的颜色,大于 2 的值都映射到红色,小于 -2 的值都映射到绿色(在对数据标准化处理时非常有用,比如RNA-seq的counts数据)。

library(circlize)
col_fun = colorRamp2(c(-2, 0, 2), c("green", "white", "red"))
col_fun(seq(-3, 3))
## [1] "#00FF00FF" "#00FF00FF" "#B1FF9AFF" "#FFFFFFFF" "#FF9E81FF" "#FF0000FF"
## [7] "#FF0000FF"
Heatmap(mat, name = "mat", col = col_fun)
image

如上图可见,虽然正负值的分布不以零为中心,但是颜色映射函数精确地将负值映射到绿色,将正值映射到红色。此外,此颜色映射功能不受异常值的影响。在下图中,聚类异常值(参见树状图)受到严重的影响,但颜色映射不受影响。

mat2 = mat
mat2[1, 1] = 100000   #修改第一个行第一列的数值为100000
Heatmap(mat2, name = "mat", col = col_fun, 
    column_title = "a matrix with outliers")
image

更重要的是,如果使用相同的颜色映射函数colorRamp2()设置多个热图中的颜色,则它们具有可比性。在以下三个热图中,相同的颜色对应相同的数值。

Heatmap(mat, name = "mat", col = col_fun, column_title = "mat")
Heatmap(mat/4, name = "mat", col = col_fun, column_title = "mat/4")
Heatmap(abs(mat), name = "mat", col = col_fun, column_title = "abs(mat)")
image

如果矩阵是连续的,您也可以简单地提供一个颜色向量,颜色将被线性映射插值。但这种方法对异常值并不稳健,因为映射从矩阵中的最小值开始,以最大值结束。以下颜色映射rev(rainbow(10)colorRamp2(seq(min(mat), max(mat), length = 10), rev(rainbow(10)))结果相同。

Heatmap(mat, name = "mat", col = rev(rainbow(10)), 
    column_title = "set a color vector for a continuous matrix")
image

如果矩阵包含离散值(数字或字符),则应将颜色指定向量名称,以便从离散值映射到颜色。如果颜色没有名称,则颜色的顺序对应于unique(mat)的顺序。以下图例是从颜色映射向量生成的。

以下为离散数字矩阵设置颜色(您不需要将其转换为字符矩阵)。

discrete_mat = matrix(sample(1:4, 100, replace = TRUE), 10, 10)
colors = structure(1:4, names = c("1", "2", "3", "4")) # black, red, green, blue
Heatmap(discrete_mat, name = "mat", col = colors,
    column_title = "a discrete numeric matrix")
image

字符型矩阵:

discrete_mat = matrix(sample(letters[1:4], 100, replace = TRUE), 10, 10)
colors = structure(1:4, names = letters[1:4])
Heatmap(discrete_mat, name = "mat", col = colors,
    column_title = "a discrete character matrix")
image

正如你在上面的两个例子中看到的,对于数字矩阵(无论颜色是连续映射还是离散映射),默认情况下在两个维度上都进行了聚类,而对于字符矩阵,聚类是关闭的(但你仍然可以聚类一个字符矩阵,但是您应该为两个字符向量提供了适当的距离度量,后面2.3.1章节中会提到 )。

NA矩阵中允许。您可以NA通过na_col 参数控制颜色(默认情况下它是灰色的NA)。只要任何行或列之间没有距离NA就可以对包含的矩阵进行聚类Heatmap()NA。通常这些情况对应于稀疏矩阵(填充了很多NA值),并表明应首先通过其他方法预测未知值。

请注意NA,图例中未显示该值。

mat_with_na = mat
na_index = sample(c(TRUE, FALSE), nrow(mat)*ncol(mat), replace = TRUE, prob = c(1, 9))
mat_with_na[na_index] = NA
Heatmap(mat_with_na, name = "mat", na_col = "black",
    column_title = "a matrix with NA values")
image

颜色空间对于内插颜色很重要。默认情况下,颜色在LAB 颜色空间中线性插值,但您可以在colorRamp2()函数中选择颜色空间。比较以下两个图。你能看到差别吗?

f1 = colorRamp2(seq(min(mat), max(mat), length = 3), c("blue", "#EEEEEE", "red"))
f2 = colorRamp2(seq(min(mat), max(mat), length = 3), c("blue", "#EEEEEE", "red"), space = "RGB")
Heatmap(mat, name = "mat1", col = f1, column_title = "LAB color space")
Heatmap(mat, name = "mat2", col = f2, column_title = "RGB color space")
image

在下面的图中,折叠线上的对应值均匀变化,您可以看到颜色在不同颜色空间下的变化情况(上图:绿-黑-红,下图:蓝-白-红。该图由 HilbertCurve包制作) .

image
image

热图边框的颜色可以通过 border/border_gprect_gp参数设置。border/border_gp控制热图外部轮廓边界,rect_gp控制热图中每个网格/单元格的边界。

border的值可以是逻辑值(TRUE对应于black)或颜色字符(例如 red)。用于border参数只是出于历史版本原因,在这里您也可以设置border_gpgpar对象作为其参数)。

rect_gp也是一个gpar对象,这意味着您只能通过 grid::gpar(). 由于填充颜色已经由热图颜色映射控制,因此您只能设置col参数gpar()来控制热图网格的边框。

Heatmap(mat, name = "mat", border_gp = gpar(col = "black", lty = 2),
    column_title = "set heatmap borders")
image
Heatmap(mat, name = "mat", rect_gp = gpar(col = "white", lwd = 2),
    column_title = "set cell borders")
image

如果col未设置,则Heatmap()默认颜色映射的设计为了更加方便和有意义。以下是默认颜色映射的规则(通过ComplexHeatmap:::default_col()):

  • 如果值是字符,则颜色由 circlize::rand_color()生成 。
  • 如果值来自热图注释并且是数字,则通过线性插值到最小值和最大值,颜色会映射到白色和一种随机颜色之间。
  • 如果值来自矩阵(M)对应于热图主题颜色:
    a. 如果值在M的25%-75%之间,颜色则通过插值(-q,0,q)映射到蓝色、白色和红色。如果|M|中的不重复值的数量少于100,则|M|中的最大值作为q,或者|M|的第99百分位数作为q值,此时颜色映射以零为中心。
    b. 通过线性插值(q1(q1+q2)q2)将颜色映射到蓝色、白色和红色。如果|M|中的不重复值的数量少于100,则q1q2分别代表|M|中的最小值和最大值,或者q1M的第1百分位数,q2M的第99百分位数。

rect_gp允许使用非标准参数type。如果设置为"none",则仍会应用聚类,但不会在热图主体上绘制任何内容。热图主体上的自定义图形可以通过cell_funlayer_fun自行添加。

Heatmap(mat, name = "mat", rect_gp = gpar(type = "none"),
    column_title = "nothing is drawn in the heatmap body")
image

2.2标题

热图的标题基本上说明了该热图是什么。在 ComplexHeatmap包中,您可以按行或者按列设置热图标题。但是只能将列标题放在热图的顶部或底部。

图形参数由row_title_gpcolumn_title_gp设置。使用gpar()来指定图形参数。

Heatmap(mat, name = "mat", column_title = "I am a column title", 
    row_title = "I am a row title")
image
Heatmap(mat, name = "mat", column_title = "I am a column title at the bottom", 
    column_title_side = "bottom")
image
Heatmap(mat, name = "mat", column_title = "I am a big column title", 
    column_title_gp = gpar(fontsize = 20, fontface = "bold"))
image

标题的旋转可以通过row_title_rot和设置column_title_rot,但只允许水平和垂直旋转。

Heatmap(mat, name = "mat", row_title = "row title", row_title_rot = 0)
image

在热图中分割行或列时使用行或列标题作为模板(因为会有多个行/列标题)。一个简单的例子是:

# code only for demonstration
# row title would be cluster_1 and cluster_2
Heatmap(mat, name = "mat", row_km = 2, row_title = "cluster_%s")

您可以在row_title_gpcolumn_title_gp中设置fill参数来设置标题的背景颜色。由于colrow_title_gp中控制文本的颜色,border用于控制背景边框的颜色。

Heatmap(mat, name = "mat", column_title = "I am a column title", 
    column_title_gp = gpar(fill = "red", col = "white", border = "blue"))
image

您可能已经发现,当背景为彩色时,列标题顶部没有多余的空间。这可以通过设置全局参数来解决ht_opt$TITLE_PADDING

ht_opt$TITLE_PADDING = unit(c(8.5, 8.5), "points")
Heatmap(mat, name = "mat", column_title = "I am a column title", 
    column_title_gp = gpar(fill = "red", col = "white", border = "blue"))
image
ht_opt(RESET = TRUE)  #恢复默认

如果图形元素是文本,也可以将它们设置为数学公式

Heatmap(mat, name = "mat", 
    column_title = expression(hat(beta) == (X^t * X)^{-1} * X^t * y)) 
image

使用gridtext包可以绘制更复杂的文本作为热图标题。

2.3 聚类

聚类也许是热图可视化的关键组成部分。在 ComplexHeatmap包中,可以非常灵活地支持层次聚类。通过以下方式指定聚类:

  • 预定义的距离方法(例如 "euclidean""pearson"),
  • 距离函数,
  • 已经聚类的对象(一个hclustdendrogram可被强制转换为对象或对象dendrogram类别),
  • 聚类函数。

还可以为不同的节点、分支用不同的颜色和样式渲染树状图,从而更好地揭示树状图的结构(例如 dendextend::color_branches())。

首先,有聚类的一般设置,例如是应用聚类还是显示树状图、树状图的边和树状图的高度。

Heatmap(mat, name = "mat", cluster_rows = FALSE) # 关闭行聚类
image
Heatmap(mat, name = "mat", show_column_dend = FALSE) # 隐藏列树状图
image
Heatmap(mat, name = "mat", row_dend_side = "right", column_dend_side = "bottom")
image
Heatmap(mat, name = "mat", column_dend_height = unit(4, "cm"), 
    row_dend_width = unit(4, "cm"))
image

2.3.1 距离法

分层聚类分两步执行:计算距离矩阵和应用聚类。可以通过三种方式为聚类指定距离度量:

  • 将距离指定为预定义选项。有效值是dist()函数支持 "pearson""spearman"``"kendall"的内置方法。相关距离定义为1 - cor(x, y, method)。所有这些内置的距离方法都允许NA值。
  • 自定义函数,用于计算与矩阵的距离。该函数应该只包含一个参数。请注意对列进行聚类,矩阵将自动转置。
  • 自定义函数,用于计算两个向量的距离。该函数应该只包含两个参数。请注意,这个运行可能很慢,因为它是由两个嵌套for循环实现的。
Heatmap(mat, name = "mat", clustering_distance_rows = "pearson",
    column_title = "pre-defined distance method (1 - pearson)")
image
Heatmap(mat, name = "mat", clustering_distance_rows = function(m) dist(m),
    column_title = "a function that calculates distance matrix")
image
Heatmap(mat, name = "mat", clustering_distance_rows = function(x, y) 1 - cor(x, y),
    column_title = "a function that calculates pairwise distance")
image

对于这些特征,我们可以应用于成对距离的异常值具有鲁棒性的聚类。注意这里我们设置了颜色映射函数,因为我们不希望异常值影响颜色。

mat_with_outliers = mat
for(i in  1:10) mat_with_outliers[i, i] = 1000
robust_dist = function(x, y) {
    qx = quantile(x, c(0.1, 0.9))
    qy = quantile(y, c(0.1, 0.9))
    l = x > qx[1] & x < qx[2] & y > qy[1] & y < qy[2]
    x = x[l]
    y = y[l]
    sqrt(sum((x - y)^2))
}

我们可以在使用或不使用鲁棒距离方法的情况下比较两个热图:

Heatmap(mat_with_outliers, name = "mat", 
    col = colorRamp2(c(-2, 0, 2), c("green", "white", "red")),
    column_title = "dist")
Heatmap(mat_with_outliers, name = "mat", 
    col = colorRamp2(c(-2, 0, 2), c("green", "white", "red")),
    clustering_distance_rows = robust_dist,
    clustering_distance_columns = robust_dist,
    column_title = "robust_dist")
image

如果有适当的距离方法(如stringdist 包中的方法),您还可以对字符矩阵进行聚类。

mat_letters = matrix(sample(letters[1:4], 100, replace = TRUE), 10)
# distance in the ASCII table
dist_letters = function(x, y) {
    x = strtoi(charToRaw(paste(x, collapse = "")), base = 16)
    y = strtoi(charToRaw(paste(y, collapse = "")), base = 16)
    sqrt(sum((x - y)^2))
}
Heatmap(mat_letters, name = "letters", col = structure(2:5, names = letters[1:4]),
    clustering_distance_rows = dist_letters, clustering_distance_columns = dist_letters,
    cell_fun = function(j, i, x, y, w, h, col) { # add text to each grid
        grid.text(mat_letters[i, j], x, y)
    })
image

2.3.2 聚类方法

可以通过clustering_method_rowsclustering_method_columns指定执行层次聚类的方法。支持hclust()函数的方法:"ward.D", "ward.D2", "single", "complete", "average" (= UPGMA), "mcquitty" (= WPGMA), "median" (= WPGMC) or "centroid" (= UPGMC)。

Heatmap(mat, name = "mat", clustering_method_rows = "single")
image

如果你已经有一个聚类对象或一个直接返回一个聚类对象的函数,你可以忽略距离设置并将cluster_rowscluster_columns设置为聚类对象或聚类函数。如果它是一个聚类函数,唯一的参数应该是矩阵,它应该返回一个hclustdendrogram对象或一个可以转换为dendrogram类的对象。

在以下示例中,通过预先计算的聚类对象或聚类函数使用cluster包中的方法执行聚类:

library(cluster)
Heatmap(mat, name = "mat", cluster_rows = diana(mat),
   cluster_columns = agnes(t(mat)), column_title = "clustering objects")
image
# if cluster_columns is set as a function, you don't need to transpose the matrix
Heatmap(mat, name = "mat", cluster_rows = diana,
   cluster_columns = agnes, column_title = "clustering functions")
image

最后一条命令:

# code only for demonstration
Heatmap(mat, name = "mat", cluster_rows = function(m) as.dendrogram(diana(m)),
    cluster_columns = function(m) as.dendrogram(agnes(m)), 
    column_title = "clutering functions")

请注意,当cluster_rows设置为一个函数,参数m是输入mat本身,而对cluster_columnsm是的转置 mat

fastcluster::hclust实现了更快的hclust(). 您可以将cluster_rowscluster_columns使用 hclust().

# code only for demonstration
fh = function(x) fastcluster::hclust(dist(x))
Heatmap(mat, name = "mat", cluster_rows = fh, cluster_columns = fh)

为了更方便地使用更快的版本hclust()(假设您要构建许多热图),可以将ht_opt设置为全局选项。

# code only for demonstration
ht_opt$fast_hclust = TRUE
# now fastcluster::hclust is used in all heatmaps

这是一种特殊情况,您可能已经对矩阵行或列进行了子组分类,而您只想对同一子组中的要素执行聚类。则通过子组变量拆分热图(后面介绍),也可以使用cluster_within_group()聚类函数生成特殊的树状图。

group = kmeans(t(mat), centers = 3)$cluster
Heatmap(mat, name = "mat", cluster_columns = cluster_within_group(mat, group))
image

在上面的例子中,同一组中的列仍然是聚类的,但是树状图变成了一条扁平线。列上的树状图显示了组的层次结构。

2.3.3 渲染树状图

如果要渲染树状图,通常需要生成一个 dendrogram对象,通过设置nodeParedgePar参数来渲染,然后将其发送到cluster_rowscluster_columns参数。
您可以通过dendexend包渲染您的dendrogram对象,以对树状图进行更加"自定义"的可视化。

library(dendextend)
row_dend = as.dendrogram(hclust(dist(mat)))
row_dend = color_branches(row_dend, k = 2) # `color_branches()` returns a dendrogram object
Heatmap(mat, name = "mat", cluster_rows = row_dend)
image

row_dend_gpcolumn_dend_gp控制树状图的全局图形设置。请注意,图形设置的row_dend将被 row_dend_gp覆盖。

Heatmap(mat, name = "mat", cluster_rows = row_dend, row_dend_gp = gpar(col = "red"))
image

从 2.5.6 版本开始,您还可以通过设置适当的nodePar.

row_dend = dendrapply(row_dend, function(d) {
    attr(d, "nodePar") = list(cex = 0.8, pch = sample(20, 1), col = rand_color(1))
    return(d)
})
Heatmap(mat, name = "mat", cluster_rows = row_dend, row_dend_width = unit(2, "cm"))
image

目前只能在节点上添加点,但是,如果您需要添加更多类型的图形,尤其是自定义图形,则需要联系ComplexHeatmap的开发作者。

2.3.4 树状图重新排序

Heatmap()函数中,树状图被重新排序,使差异较大的特征彼此之间更加分离(请参阅reorder.dendrogram()的文档)。这里的差异(或称为权重),如果是行树状图,则由行均值测量,如果是列树状图,则由列均值测量。row_dend_reordercolumn_dend_reorder如果该值被设置为逻辑控制则表示是否应用树状重新排序。如果这两个参数设置为数字向量(它将被发送到 的wts 参数reorder.dendrogram()),则它们还控制重新排序的权重。可以通过设置例如关闭重新排序 row_dend_reorder = FALSE

默认情况下,如果cluster_rows/cluster_columns设置为逻辑值或聚类函数,则。树状图排序处于打开状态,如果cluster_rows/cluster_columns设置为聚类对象,则排序关闭。

比较以下两个热图:

m2 = matrix(1:100, nr = 10, byrow = TRUE)
Heatmap(m2, name = "mat", row_dend_reorder = FALSE, column_title = "no reordering")
Heatmap(m2, name = "mat", row_dend_reorder = TRUE, column_title = "apply reordering")
image

还有许多其他方法可以重新排序树状图,例如dendsort 包。基本上,所有这些方法仍然返回一个经过重新排序的树状图,因此,我们可以首先根据数据矩阵生成行或列树状图,通过某种方法对其重新排序,并将其分配回 cluster_rowsor cluster_columns

在两个维度上比较以下两个重新排序。你能说出哪个更好吗?

Heatmap(mat, name = "mat", column_title = "default reordering")

library(dendsort)
row_dend = dendsort(hclust(dist(mat)))
col_dend = dendsort(hclust(dist(t(mat))))
Heatmap(mat, name = "mat", cluster_rows = row_dend, cluster_columns = col_dend,
    column_title = "reorder by dendsort")
image

2.4 设置行列顺序

聚类用于调整热图的行序和列序,但您仍然可以通过row_ordercolumn_order手动设置顺序。如果设置了row_order ,则默认情况下关闭行聚类。

Heatmap(mat, name = "mat", row_order = order(as.numeric(gsub("row", "", rownames(mat)))), 
    column_order = order(as.numeric(gsub("column", "", colnames(mat)))),
    column_title = "reorder matrix")
image

如果只是变换矩阵的行、列名,则将它们当做字符向量。

Heatmap(mat, name = "mat", row_order = sort(rownames(mat)), 
    column_order = sort(colnames(mat)),
    column_title = "reorder matrix by row/column names")
image

注意row_dend_reorderrow_order是两个不同的东西。 row_dend_reorder应用于树状图。对于树状图中的任何节点,旋转其两个分支实际上会给出相同的树状图,因此,通过在每个节点自动旋转子树状图来重新排序树状图可以帮助将显示出更多差异的特征彼此分离得更远。作为比较,row_order它只是应用于矩阵,通常应该关闭树状图。

2.5 序列

序列化是一种有趣的矩阵排序技术(参见这篇文章:http : //nicolas.kruchten.com/content/2018/02/seriation/)。强大的seriation 实现了相当多的序列化方法。由于seriate()seriation包的核心函数返回的对象中很容易提取行序和列序 ,因此可以直接赋值给热图row_ordercolumn_order制作热图。

第一个示例演示如何直接应用于seriate()矩阵。由于该"BEA_TSP"方法只允许非负矩阵,我们将矩阵修改为max(mat) - mat

library(seriation)
o = seriate(max(mat) - mat, method = "BEA_TSP")
Heatmap(max(mat) - mat, name = "mat", 
    row_order = get_order(o, 1), column_order = get_order(o, 2),
    column_title = "seriation by BEA_TSP method")
image

或者您可以应用于seriate()距离矩阵。现在需要分别计算行和列的顺序,因为需要分别计算列和行的距离矩阵。

o1 = seriate(dist(mat), method = "TSP")
o2 = seriate(dist(t(mat)), method = "TSP")
Heatmap(mat, name = "mat", row_order = get_order(o1), column_order = get_order(o2),
    column_title = "seriation from the distance matrix")
image

一些序列化方法还包含层次聚类信息。

o1 = seriate(dist(mat), method = "GW")
o2 = seriate(dist(t(mat)), method = "GW")

o1o2实际上主要由hclust对象组成:

class(o1[[1]])
## [1] "ser_permutation_vector" "hclust"

使用hclust$order或者get_order()的顺序是一样的。

o1[[1]]$order
##  [1]  5  2 10 17  4 16 18  7 15 14 11  8  1  3 12  6 13  9
# should be the same as the previous one
get_order(o1)
##  [1]  5  2 10 17  4 16 18  7 15 14 11  8  1  3 12  6 13  9

我们可以将树状图添加到热图中。

Heatmap(mat, name = "mat", cluster_rows = as.dendrogram(o1[[1]]), 
    cluster_columns = as.dendrogram(o2[[1]]))
image

更多seriate()功能使用请参考序列化

2.6 维度名称

默认情况下,行名称和列名称绘制在热图的右侧和底部。设置位置、可见性和图形参数如下:

Heatmap(mat, name = "mat", row_names_side = "left", row_dend_side = "right", 
    column_names_side = "top", column_dend_side = "bottom")
image
Heatmap(mat, name = "mat", show_row_names = FALSE)
image
Heatmap(mat, name = "mat", row_names_gp = gpar(fontsize = 20))
image
Heatmap(mat, name = "mat", row_names_gp = gpar(col = c(rep("red", 10), rep("blue", 8))))
image
Heatmap(mat, name = "mat", row_names_centered = TRUE, column_names_centered = TRUE)
image

列名的旋转可以通过以下方式设置column_names_rot

Heatmap(mat, name = "mat", column_names_rot = 45)
Heatmap(mat, name = "mat", column_names_rot = 45, column_names_side = "top",
    column_dend_side = "bottom")
image

如果您的行名或列名太长, row_names_max_width或者column_names_max_height可以为其设置最大空间。行名和列名的默认最大空间均为 6 cm。在以下代码中,max_text_width()是一个辅助函数,用于从文本向量快速计算最大宽度。

mat2 = mat
rownames(mat2)[1] = paste(c(letters, LETTERS), collapse = "")
Heatmap(mat2, name = "mat", row_title = "default row_names_max_width")
Heatmap(mat2, name = "mat", row_title = "row_names_max_width as length of a*",
    row_names_max_width = max_text_width(
        rownames(mat2), 
        gp = gpar(fontsize = 12)
    ))
image

除了直接使用矩阵中的行/列名称之外,您还可以提供另一个对应于行或列的字符向量,并通过row_labelscolumn_labels进行设置。这非常有用,因为您无需更改矩阵的维度名称即可更改热图上的标签,而您可以直接提供新标签。

有一个典型的场景,row_labelscolumn_labels是有用的。对于基因表达分析,我们可能使用 Ensembl ID 作为基因 ID,用作基因表达矩阵的行名称。但是,Ensembl ID 是用于 Ensembl 数据库的索引,而不适合用于人们阅读。相反,我们更愿意将基因符号放在热图上作为更易于阅读的行名称。为此,我们只需要将相应的基因符号分配给,row_labels而无需修改原始矩阵。

第二个优点是row_labelscolumn_labels允许重复的标签,而矩阵中不允许重复的行名或列名。

下面给出一个简单的例子,我们把字母作为行标签和列标签:

# use a named vector to make sure the correspondance between 
# row names and row labels is correct
row_labels = structure(paste0(letters[1:24], 1:24), names = paste0("row", 1:24))
column_labels = structure(paste0(LETTERS[1:24], 1:24), names = paste0("column", 1:24))
row_labels
##  row1  row2  row3  row4  row5  row6  row7  row8  row9 row10 row11 row12 row13 
##  "a1"  "b2"  "c3"  "d4"  "e5"  "f6"  "g7"  "h8"  "i9" "j10" "k11" "l12" "m13" 
## row14 row15 row16 row17 row18 row19 row20 row21 row22 row23 row24 
## "n14" "o15" "p16" "q17" "r18" "s19" "t20" "u21" "v22" "w23" "x24"
Heatmap(mat, name = "mat", row_labels = row_labels[rownames(mat)], 
    column_labels = column_labels[colnames(mat)])
image

第三个优点是数学表达式可以用作热图中的行名称。

Heatmap(mat, name = "mat", row_labels = expression(alpha, beta, gamma, delta, epsilon, 
    zeta, eta, theta, iota, kappa, lambda, mu, nu, xi, omicron, pi, rho, sigma))
image

在内部,行名和列名实际上是由anno_text()函数实现的 ,换句话说,它们被视为文本注释的特殊情况。

复杂的行/列名称样式可以通过集成gridtext包来实现 。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容