Making A Single Heatmap
单热图(A single heatmap):主要用于快速查看数据。这是heatmap list的一个特例,它只包含一个热图。与现有工具相比,ComplexHeatmap包提供了更灵活的方法来支持单个heatmap的可视化。在下面的示例中,我们将演示如何设置参数来可视化单个热图。
加载包,生成一个随机矩阵--(用于测试):
library(ComplexHeatmap)
library(circlize)
set.seed(123) #郑宝童简书上,提供了一个关于set.seed()函数的解析
mat = cbind(rbind(matrix(rnorm(16, -1), 4), matrix(rnorm(32, 1), 8)),
rbind(matrix(rnorm(24, 1), 4), matrix(rnorm(48, -1), 8)))
# permute the rows and columns 排列行和列
mat = mat[sample(nrow(mat), nrow(mat)), sample(ncol(mat), ncol(mat))]
rownames(mat) = paste0("R", 1:12)
colnames(mat) = paste0("C", 1:10)
用默认设置绘制热图。热图的默认样式与其他相似的热图函数生成的样式非常相似。
Heatmap(mat)
Colors颜色
colorRamp2()
的两个参数分别是截断值和相对应的颜色. 当前colorRamp2()
通过LAB color space在每个间隔中线性插入颜色。
在大多数情况下,热图可视化的是具有连续值的矩阵。 在这种情况下,用户应提供颜色映射功能。 颜色映射函数是输入值向量返回颜色向量的函数。 ** circlize **包中的colorRamp2()
有助于生成这些函数。colorRamp2()
有两个参数是:包含截断值和相应颜色的向量。
下方例子中, -3到3之间的值通过线性分布以获得相应的颜色, > 3:red ;< -3:green (所以这里演示的颜色映射函数对异常值也是稳定可用的).--colorRamp2设置颜色
mat2 = mat
mat2[1, 1] = 100000
Heatmap(mat2, col = colorRamp2(c(-3, 0, 3), c("green", "white", "red")),
cluster_rows = FALSE, cluster_columns = FALSE)
如果矩阵是连续的,您还可以提供颜色向量,颜色将根据'k'分位数进行插值。 但请记住,这种方法对异常值并不稳健。
Heatmap(mat, col = rev(rainbow(10)))
如果矩阵包含离散值(数字或字符),则应将颜色指定给命名向量,以使从离散值映射到颜色成为可能。如果没为颜色指定命名向量, 颜色顺序对应于unique(mat)
的顺序一致.(如下图第二行,四种颜色分别给了1 2 3 4)
discrete_mat = matrix(sample(1:4, 100, replace = TRUE), 10, 10)
colors = structure(circlize::rand_color(4), names = c("1", "2", "3", "4"))
Heatmap(discrete_mat, col = colors)
字符矩阵:
discrete_mat = matrix(sample(letters[1:4], 100, replace = TRUE), 10, 10)
colors = structure(circlize::rand_color(4), names = letters[1:4])
Heatmap(discrete_mat, col = colors)
如您所见,对于数值矩阵(无论是连续映射还是离散映射),默认情况下在两个维度上都使用聚类,而对于字符矩阵,则不使用聚类。
NA
值允许出现在heatmap中.你可以通过na_col
参数为NA
设定颜色. 包含 NA
的矩阵也可以被 Heatmap()
聚类 (因为 dist()
支持 NA
值) and 使用 “pearson”, “spearman” or “kendall” 方法聚类带有NA值的矩阵将引出warning messages.
mat_with_na = mat
mat_with_na[sample(c(TRUE, FALSE), nrow(mat)*ncol(mat), replace = TRUE, prob = c(1, 9))] = NA
Heatmap(mat_with_na, na_col = "orange", clustering_distance_rows = "pearson")
## Warning in get_dist(submat, distance): NA exists in the matrix, calculating distance by removing NA
## values.
颜色空间对于插入颜色是很重要的.默认情况下, colors 是在LAB color space线性分布的, 但是你也可以通过colorRamp2()
函数选择color space. 对比下方两图 (两张图的+
操作会在[Making a list of heatmaps]中被介绍)
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, col = f1, column_title = "LAB color space") +
Heatmap(mat, col = f2, column_title = "RGB color space")
下图中,可以看到不同颜色空间下的颜色变化 (这些图是 HilbertCurve 包画的)对应的值在折叠轴上均匀变化. 选择一个合适的颜色空间是有点主观的,这取决于具体的数据和颜色主题,有时候你需要尝试多种颜色空间,来最终选的一种可以最好展示数据结构的颜色空间
Titles 标题
热图的name默认情况下被用作热图图例的标题。如果你同时绘制多个热图,这名字也可以作为唯一的id。稍后,我们可以使用这个名称到相应的热图中添加更多的图形 (具体看[Heatmap Decoration]vignette).
Heatmap(mat, name = "foo")
你可以使用heatmap_legend_param
修改热图图例的标题(具体见 [Heatmap and Annotation Legends]vignette 获得更多对图库的控制).
Heatmap(mat, heatmap_legend_param = list(title = "legend"))
您可以将热图标题设置为按行或按列放置。同时注意,你只能把列标题放在热图的顶部或底部。图形参数可以分别由' row_title_gp '和' column_title_gp '设置。请记住您应该使用"gpar()"来指定图形参数。
Heatmap(mat, name = "foo", column_title = "I am a column title",
row_title = "I am a row title")
Heatmap(mat, name = "foo", column_title = "I am a column title at the bottom",
column_title_side = "bottom")
Heatmap(mat, name = "foo", column_title = "I am a big column title",
column_title_gp = gpar(fontsize = 20, fontface = "bold"))
标题的旋转可以通过' row_title_rot '和' column_title_rot '设置,但只允许水平和垂直旋转。
Heatmap(mat, name = "foo", row_title = "row title", row_title_rot = 0)
Clustering 聚类
You can specify the clustering either by a pre-defined method (e.g. “eulidean” or “pearson”), or by a distance function, or by a object that already contains clustering, or directly by a clustering function. It is also possible to render your dendrograms with different colors and styles for different branches for better revealing structures of your data.
First there are general settings for the clustering, e.g. whether do or show dendrograms, side of the dendrograms and size of the dendrograms.
聚类是热图可视化的关键特性。在ComplexHeatmap包中, 聚类有很高的灵活性. 你可以通过预定的方法来指定聚类方法如(e.g. “eulidean” or “pearson”), 或者使用距离函数, or by a object that already contains clustering,or directly by a clustering function. 还可以为不同的分支呈现不同颜色和样式的树状图,以便更好地显示数据结构。
首先是聚类的的一般设置,例如是否做或显示树状图、树状图的边和树状图的大小。
Heatmap(mat, name = "foo", cluster_rows = FALSE)
Heatmap(mat, name = "foo", show_column_dend = FALSE)
Heatmap(mat, name = "foo", row_dend_side = "right")
Heatmap(mat, name = "foo", column_dend_height = unit(2, "cm"))
这里提供三种方法指定聚类的距离度量:
- 将距离指定为预定义选项(specify distance as a pre-defined option). 预定义选项可用的值是
dist()
函数中支持的方法和pearson
,spearman
andkendall
.NA
值在预定义选项的聚类中是被忽略的但会抛出 warnings (see example in Colors section). - 一个自定义函数,从矩阵计算距离。函数应该只包含一个参数。请注意,对于列的聚类,矩阵将自动transposed 。
- 一个自定义函数,计算两个向量之间的距离。函数应该只包含两个参数.
Heatmap(mat, name = "foo", clustering_distance_rows = "pearson")
Heatmap(mat, name = "foo", clustering_distance_rows = function(m) dist(m))
Heatmap(mat, name = "foo", clustering_distance_rows = function(x, y) 1 - cor(x, y))
基于该特征,我们可以利用对异常值鲁棒性强的聚类方法应用于配对距离(the pair-wise distance.)
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 = "foo",
col = colorRamp2(c(-3, 0, 3), c("green", "white", "red")),
clustering_distance_rows = robust_dist,
clustering_distance_columns = robust_dist)
如果提供了可用的距离方法,还可以对字符矩阵进行聚类。“cell_fun”参数将在后面的小节中解释。
mat_letters = matrix(sample(letters[1:4], 100, replace = TRUE), 10)
# distance in th 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 = "foo", 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) {
grid.text(mat_letters[i, j], x, y)
})
可以通过' clustering_method_rows '和' clustering_method_columns '指定实现分层聚类的方法。可用的方法是' hclust() '函数中支持的方法。
Heatmap(mat, name = "foo", clustering_method_rows = "single")
默认情况下,聚类由' hclust() '执行。但是您也可以通过将“cluster_rows”或“cluster_columns”指定为“hclust”或“dendrogram”对象来利用其他方法生成的聚类结果。在下面的示例中,我们使用来自cluster包的' diana() '和' agnes() '方法来执行聚类。
library(cluster)
Heatmap(mat, name = "foo", cluster_rows = as.dendrogram(diana(mat)),
cluster_columns = as.dendrogram(agnes(t(mat))))
在原生的“heatmap()”函数中,行和列上的树状图被重新排序,以便将差异较大的特性彼此分隔开来,默认情况下,对树木图的重新排序也可由“heatmap()”打开。
除了默认的重新排序方法之外,您还可以先生成一个树形图并应用其他重新排序方法,然后将重新排序的树形图发送给' cluster_rows '参数.
对比以下三个图:
pushViewport(viewport(layout = grid.layout(nr = 1, nc = 3)))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1))
draw(Heatmap(mat, name = "foo", row_dend_reorder = FALSE, column_title = "no reordering"), newpage = FALSE)
upViewport()
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 2))
draw(Heatmap(mat, name = "foo", row_dend_reorder = TRUE, column_title = "applied reordering"), newpage = FALSE)
upViewport()
library(dendsort)
dend = dendsort(hclust(dist(mat)))
pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 3))
draw(Heatmap(mat, name = "foo", cluster_rows = dend, row_dend_reorder = FALSE,
column_title = "reordering by dendsort"), newpage = FALSE)
upViewport(2)
您可以通过dendextend包来呈现您的“树状图”对象,并对树状图进行更自定义的可视化。
library(dendextend)
dend = hclust(dist(mat))
dend = color_branches(dend, k = 2)
Heatmap(mat, name = "foo", cluster_rows = dend)
通常cluster_rows
和 cluster_columns
can be 聚类的函数. 自定义函数的输入参数应该是一个矩阵,返回值应该是hclust
or dendrogram
对象. 请注意当 cluster_rows
在内部被执行时 参数 m
就是你的输入 mat
而在执行cluster_columns
时m
是mat
的转置 .
Heatmap(mat, name = "foo", cluster_rows = function(m) as.dendrogram(diana(m)),
cluster_columns = function(m) as.dendrogram(agnes(m)))
' fastcluster::hclust '是' hclust '的更快版本。我们可以重新定义' cluster_rows '和' cluster_columns '来使用' hclust '的更快版本。但是请注意“fastcluster::hclust”只加快了聚类的计算,而没有加快距离矩阵的计算。
# code not run when building the vignette
Heatmap(mat, name = "foo", cluster_rows = function(m) fastcluster::hclust(dist(m)),
cluster_columns = function(m) fastcluster::hclust(dist(m))) # for column cluster, m will be automatically transposed
为了更方便地使用快版本的“hclust”(假设您有许多热图要连接),你可以将设置为一个全局选项:
# code not run when building the vignette
ht_global_opt(fast_hclust = TRUE)
# now hclust from fastcluster package is used in all heatmaps
Heatmap(mat, name = "foo")
聚类可以帮助调整行和列中的顺序。但您仍然可以通过' row_order '和' column_order '手动设置顺序。注意,如果想手动设置顺序,需要 turn off clustering。“row_order”和“column_order”也可以根据存在的矩阵行名和列名设置。
Heatmap(mat, name = "foo", cluster_rows = FALSE, cluster_columns = FALSE,
row_order = 12:1, column_order = 10:1)
注意“row_dend_reorder”和“row_order”是不同的。' row_dend_reorder '应用于树状图。因为对于树形图中的任何节点,旋转两片叶子会得到相同的树形图。因此,通过在每个节点上自动旋转子树状图来重新排序树状图,将有助于将差异较大的元素分离开来,使它们之间的距离更远。当' row_order '应用于矩阵时和树状图的该功能会被抑制。
Dimension names 维度名称
维度名称的边、可见性和图形参数可以设置如下。
Heatmap(mat, name = "foo", row_names_side = "left", row_dend_side = "right",
column_names_side = "top", column_dend_side = "bottom")
Heatmap(mat, name = "foo", show_row_names = FALSE)
Heatmap(mat, name = "foo", row_names_gp = gpar(fontsize = 20))
Heatmap(mat, name = "foo", row_names_gp = gpar(col = c(rep("red", 4), rep("blue", 8))))
目前,不支持对列名和行名进行旋转(或者可能在将来的版本中实现该功能)。因为在文本旋转之后,维度名称将进入其他热图组件,这将打乱热图布局。但是,正如将在[Heatmap Annotation] vignette中介绍的,在Heatmap注释中允许文本旋转。因此,用户可以提供一个只包含旋转文本的行注释或列注释来模拟旋转的行/列名称 (Y你可以看 [Heatmap Annotation]中的例子).
Split heatmap by rows 按行分割热图
热图可以按行分割。这将增强热图中组分离的可视化。值大于1的“km”参数表示对行进行k-means聚类,并且集群应用于每个k-means集群. clustering is applied on every k-means cluster.--设置km值,按行分割
Heatmap(mat, name = "foo", km = 2)
通常,split
可以设置为向量或数据框(dataframe),它们被用于不同程度的组合分割heatmap的行。实际上,k-means聚类只是生成一个行类的向量,并给split
附加一个额外的列。每个行slice的组合行标题可以由combined_name_fun
参数控制。每个slice的顺序可以由split
中每个变量的levels
控制。--"其实就是按行分割,并给分割的组命名"
Heatmap(mat, name = "foo", split = rep(c("A", "B"), 6))
Heatmap(mat, name = "foo", split = data.frame(rep(c("A", "B"), 6), rep(c("C", "D"), each = 6)))
Heatmap(mat, name = "foo", split = data.frame(rep(c("A", "B"), 6), rep(c("C", "D"), each = 6)),
combined_name_fun = function(x) paste(x, collapse = "\n"))
Heatmap(mat, name = "foo", km = 2, split = factor(rep(c("A", "B"), 6), levels = c("B", "A")),
combined_name_fun = function(x) paste(x, collapse = "\n"))
Heatmap(mat, name = "foo", km = 2, split = rep(c("A", "B"), 6), combined_name_fun = NULL)
如果您对默认的k-means partitioning method不满意,那么只需将分区向量(partitioning vector)分配给"split",就可以轻松地使用其他partitioning methods.
pa = pam(mat, k = 3)
Heatmap(mat, name = "foo", split = paste0("pam", pa$clustering))
如果设置了row_order
, 在每个slice中,行仍然是有序的。--就是分片完,每片片内的顺序和row_order一致
Heatmap(mat, name = "foo", row_order = 12:1, cluster_rows = FALSE, km = 2)
row slices之间间隙的高度可以由gap
控制。 (a single unit or a vector of units).--设置间隔高度
Heatmap(mat, name = "foo", split = paste0("pam", pa$clustering), gap = unit(5, "mm"))
字符矩阵只能被"split"参数分割.
Heatmap(discrete_mat, name = "foo", col = 1:4,
split = rep(letters[1:2], each = 5))
当split 应用于行时,row title and row names的graphic parameters可以指定为与row slices数量相同的长度.
Heatmap(mat, name = "foo", km = 2, row_title_gp = gpar(col = c("red", "blue"), font = 1:2),
row_names_gp = gpar(col = c("green", "orange"), fontsize = c(10, 14)))
用户可能已经有了行的树状图,他们希望通过将树状图分割成k个子树来分割行。 在这种情况下,split
可以指定为a single number:
dend = hclust(dist(mat))
dend = color_branches(dend, k = 2)
Heatmap(mat, name = "foo", cluster_rows = dend, split = 2)
或者他们只是通过为split
指定整数来拆分行。 注意它与km
不同。 如果设置了“km”,则首先应用k均值聚类,并将聚类应用于每个k均值簇; 而如果split
是一个整数,则将聚类应用于整个矩阵,然后通过cutree()
进行分割。
Heatmap(mat, name = "foo", split = 2)
Self define the heatmap body自定义热图主体部分
参数"rect_gp"为热图主体提供了基本的图形设置(注意,"fill"参数是不可用的)。
Heatmap(mat, name = "foo", rect_gp = gpar(col = "green", lty = 2, lwd = 2))
默认情况下,热图主体是可被自定义的。热图主体由一组具有不同的填充颜色的rectangles(it is called cells here)组成。如果rect_gp
中的type
设置为none
,则会初始化单元格数组,但不会放入任何图形。然后,用户可以通过cell_fun
定义自己的图形函数。 cell_fun
应用于热图中的每个单元格,并提供有关'current'单元格的以下信息:
-
j
: 列号. 列索引对应于视图中的x方向,这就是为什么将“j”作为第一个参数. -
i
: 行号. -
x
: x coordinate of middle point of the cell which is measured in the viewport of the heatmap body.在heatmap主题体的视区中测量的单元中点的X坐标。 -
y
: y coordinate of middle point of the cell which is measured in the viewport of the heatmap body. -
width
: cell的宽度. -
height
: cell的高度. -
fill
: cell的颜色.
最常见的用法是向热图添加数值:
Heatmap(mat, name = "foo", cell_fun = function(j, i, x, y, width, height, fill) {
grid.text(sprintf("%.1f", mat[i, j]), x, y, gp = gpar(fontsize = 10))
})
在下面的例子中,我们制作了一个heatmap,它展示了相关性矩阵(类似于corrplot包):
cor_mat = cor(mat)
od = hclust(dist(cor_mat))$order
cor_mat = cor_mat[od, od]
nm = rownames(cor_mat)
col_fun = circlize::colorRamp2(c(-1, 0, 1), c("green", "white", "red"))
# `col = col_fun` here is used to generate the legend
Heatmap(cor_mat, name = "correlation", col = col_fun, rect_gp = gpar(type = "none"),
cell_fun = function(j, i, x, y, width, height, fill) {
grid.rect(x = x, y = y, width = width, height = height, gp = gpar(col = "grey", fill = NA))
if(i == j) {
grid.text(nm[i], x = x, y = y)
} else if(i > j) {
grid.circle(x = x, y = y, r = abs(cor_mat[i, j])/2 * min(unit.c(width, height)),
gp = gpar(fill = col_fun(cor_mat[i, j]), col = NA))
} else {
grid.text(sprintf("%.1f", cor_mat[i, j]), x, y, gp = gpar(fontsize = 8))
}
}, cluster_rows = FALSE, cluster_columns = FALSE,
show_row_names = FALSE, show_column_names = FALSE)
注cell_fun
是通过for
循环应用于每个单元格,因此大型矩阵的速度会慢一点.
最后一个例子是可视化一个GO game。输入数据是记录的游戏中的动作。
str = "B[cp];W[pq];B[dc];W[qd];B[eq];W[od];B[de];W[jc];B[qk];W[qn]
;B[qh];W[ck];B[ci];W[cn];B[hc];W[je];B[jq];W[df];B[ee];W[cf]
;B[ei];W[bc];B[ce];W[be];B[bd];W[cd];B[bf];W[ad];B[bg];W[cc]
;B[eb];W[db];B[ec];W[lq];B[nq];W[jp];B[iq];W[kq];B[pp];W[op]
;B[po];W[oq];B[rp];W[ql];B[oo];W[no];B[pl];W[pm];B[np];W[qq]
;B[om];W[ol];B[pk];W[qp];B[on];W[rm];B[mo];W[nr];B[rl];W[rk]
;B[qm];W[dp];B[dq];W[ql];B[or];W[mp];B[nn];W[mq];B[qm];W[bp]
;B[co];W[ql];B[no];W[pr];B[qm];W[dd];B[pn];W[ed];B[bo];W[eg]
;B[ef];W[dg];B[ge];W[gh];B[gf];W[gg];B[ek];W[ig];B[fd];W[en]
;B[bn];W[ip];B[dm];W[ff];B[cb];W[fe];B[hp];W[ho];B[hq];W[el]
;B[dl];W[fk];B[ej];W[fp];B[go];W[hn];B[fo];W[em];B[dn];W[eo]
;B[gp];W[ib];B[gc];W[pg];B[qg];W[ng];B[qc];W[re];B[pf];W[of]
;B[rc];W[ob];B[ph];W[qo];B[rn];W[mi];B[og];W[oe];B[qe];W[rd]
;B[rf];W[pd];B[gm];W[gl];B[fm];W[fl];B[lj];W[mj];B[lk];W[ro]
;B[hl];W[hk];B[ik];W[dk];B[bi];W[di];B[dj];W[dh];B[hj];W[gj]
;B[li];W[lh];B[kh];W[lg];B[jn];W[do];B[cl];W[ij];B[gk];W[bl]
;B[cm];W[hk];B[jk];W[lo];B[hi];W[hm];B[gk];W[bm];B[cn];W[hk]
;B[il];W[cq];B[bq];W[ii];B[sm];W[jo];B[kn];W[fq];B[ep];W[cj]
;B[bk];W[er];B[cr];W[gr];B[gk];W[fj];B[ko];W[kp];B[hr];W[jr]
;B[nh];W[mh];B[mk];W[bb];B[da];W[jh];B[ic];W[id];B[hb];W[jb]
;B[oj];W[fn];B[fs];W[fr];B[gs];W[es];B[hs];W[gn];B[kr];W[is]
;B[dr];W[fi];B[bj];W[hd];B[gd];W[ln];B[lm];W[oi];B[oh];W[ni]
;B[pi];W[ki];B[kj];W[ji];B[so];W[rq];B[if];W[jf];B[hh];W[hf]
;B[he];W[ie];B[hg];W[ba];B[ca];W[sp];B[im];W[sn];B[rm];W[pe]
;B[qf];W[if];B[hk];W[nj];B[nk];W[lr];B[mn];W[af];B[ag];W[ch]
;B[bh];W[lp];B[ia];W[ja];B[ha];W[sf];B[sg];W[se];B[eh];W[fh]
;B[in];W[ih];B[ae];W[so];B[af]"
然后我们把它转换成一个矩阵:
str = gsub("\\n", "", str)
step = strsplit(str, ";")[[1]]
type = gsub("(B|W).*", "\\1", step)
row = gsub("(B|W)\\[(.).\\]", "\\2", step)
column = gsub("(B|W)\\[.(.)\\]", "\\2", step)
mat = matrix(nrow = 19, ncol = 19)
rownames(mat) = letters[1:19]
colnames(mat) = letters[1:19]
for(i in seq_along(row)) {
mat[row[i], column[i]] = type[i]
}
mat
## a b c d e f g h i j k l m n o p q r s
## a NA NA NA "W" "B" "B" "B" NA NA NA NA NA NA NA NA NA NA NA NA
## b "W" "W" "W" "B" "W" "B" "B" "B" "B" "B" "B" "W" "W" "B" "B" "W" "B" NA NA
## c "B" "B" "W" "W" "B" "W" NA "W" "B" "W" "W" "B" "B" "B" "B" "B" "W" "B" NA
## d "B" "W" "B" "W" "B" "W" "W" "W" "W" "B" "W" "B" "B" "B" "W" "W" "B" "B" NA
## e NA "B" "B" "W" "B" "B" "W" "B" "B" "B" "B" "W" "W" "W" "W" "B" "B" "W" "W"
## f NA NA NA "B" "W" "W" NA "W" "W" "W" "W" "W" "B" "W" "B" "W" "W" "W" "B"
## g NA NA "B" "B" "B" "B" "W" "W" NA "W" "B" "W" "B" "W" "B" "B" NA "W" "B"
## h "B" "B" "B" "W" "B" "W" "B" "B" "B" "B" "B" "B" "W" "W" "W" "B" "B" "B" "B"
## i "B" "W" "B" "W" "W" "W" "W" "W" "W" "W" "B" "B" "B" "B" NA "W" "B" NA "W"
## j "W" "W" "W" NA "W" "W" NA "W" "W" NA "B" NA NA "B" "W" "W" "B" "W" NA
## k NA NA NA NA NA NA NA "B" "W" "B" NA NA NA "B" "B" "W" "W" "B" NA
## l NA NA NA NA NA NA "W" "W" "B" "B" "B" NA "B" "W" "W" "W" "W" "W" NA
## m NA NA NA NA NA NA NA "W" "W" "W" "B" NA NA "B" "B" "W" "W" NA NA
## n NA NA NA NA NA NA "W" "B" "W" "W" "B" NA NA "B" "B" "B" "B" "W" NA
## o NA "W" NA "W" "W" "W" "B" "B" "W" "B" NA "W" "B" "B" "B" "W" "W" "B" NA
## p NA NA NA "W" "W" "B" "W" "B" "B" NA "B" "B" "W" "B" "B" "B" "W" "W" NA
## q NA NA "B" "W" "B" "B" "B" "B" NA NA "B" "W" "B" "W" "W" "W" "W" NA NA
## r NA NA "B" "W" "W" "B" NA NA NA NA "W" "B" "B" "B" "W" "B" "W" NA NA
## s NA NA NA NA "W" "W" "B" NA NA NA NA NA "B" "W" "W" "W" NA NA NA
黑色和白色的stones是根据矩阵中的值放置的:
Heatmap(mat, name = "go", rect_gp = gpar(type = "none"),
cell_fun = function(j, i, x, y, w, h, col) {
grid.rect(x, y, w, h, gp = gpar(fill = "#dcb35c", col = NA))
if(i == 1) {
grid.segments(x, y-h*0.5, x, y)
} else if(i == nrow(mat)) {
grid.segments(x, y, x, y+h*0.5)
} else {
grid.segments(x, y-h*0.5, x, y+h*0.5)
}
if(j == 1) {
grid.segments(x, y, x+w*0.5, y)
} else if(j == ncol(mat)) {
grid.segments(x-w*0.5, y, x, y)
} else {
grid.segments(x-w*0.5, y, x+w*0.5, y)
}
if(i %in% c(4, 10, 16) & j %in% c(4, 10, 16)) {
grid.points(x, y, pch = 16, size = unit(2, "mm"))
}
r = min(unit.c(w, h))*0.45
if(is.na(mat[i, j])) {
} else if(mat[i, j] == "W") {
grid.circle(x, y, r, gp = gpar(fill = "white", col = "white"))
} else if(mat[i, j] == "B") {
grid.circle(x, y, r, gp = gpar(fill = "black", col = "black"))
}
},
col = c("B" = "black", "W" = "white"),
show_row_names = FALSE, show_column_names = FALSE,
column_title = "One famous GO game",
heatmap_legend_param = list(title = "Player", at = c("B", "W"),
labels = c("player1", "player2"), grid_border = "black")
)
Set heatmap body as raster image 将heatmap主体设置为raster image
以PDF格式保存绘图是保持质量的最佳方法。但是,当行太多(例如,大于10000行)时,输出的PDF文件大小将非常大,读取绘图需要时间和内存。 另一方面,在有限大小的PDF文件中看不到巨大矩阵的细节。将heatmap渲染为raster images将有效地减小文件大小。在heatmap()
函数中,有四个选项控制如何生成raster images: use_raster
, raster_device
, raster_quality
, raster_device_param
.
您可以通过raster_device
选择graphic device(png
、jpeg
和tiff
),并通过raster_quality
参数控制raster image的质量,并通过' raster_device_param '为特定的device传递参数。 Check this web page for better demonstrations.
Session info
sessionInfo()
## R version 3.5.1 Patched (2018-07-24 r75008)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows Server 2012 R2 x64 (build 9600)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=C LC_CTYPE=English_United States.1252
## [3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
## [5] LC_TIME=English_United States.1252
##
## attached base packages:
## [1] stats4 parallel grid stats graphics grDevices utils datasets methods
## [10] base
##
## other attached packages:
## [1] dendextend_1.9.0 dendsort_0.3.3 cluster_2.0.7-1 IRanges_2.16.0
## [5] S4Vectors_0.20.0 BiocGenerics_0.28.0 HilbertCurve_1.12.0 circlize_0.4.4
## [9] ComplexHeatmap_1.20.0 knitr_1.20 markdown_0.8
##
## loaded via a namespace (and not attached):
## [1] mclust_5.4.1 Rcpp_0.12.19 mvtnorm_1.0-8 lattice_0.20-35
## [5] png_0.1-7 class_7.3-14 assertthat_0.2.0 mime_0.6
## [9] R6_2.3.0 GenomeInfoDb_1.18.0 plyr_1.8.4 evaluate_0.12
## [13] ggplot2_3.1.0 highr_0.7 pillar_1.3.0 GlobalOptions_0.1.0
## [17] zlibbioc_1.28.0 rlang_0.3.0.1 lazyeval_0.2.1 diptest_0.75-7
## [21] kernlab_0.9-27 whisker_0.3-2 GetoptLong_0.1.7 stringr_1.3.1
## [25] RCurl_1.95-4.11 munsell_0.5.0 compiler_3.5.1 pkgconfig_2.0.2
## [29] shape_1.4.4 nnet_7.3-12 tidyselect_0.2.5 gridExtra_2.3
## [33] tibble_1.4.2 GenomeInfoDbData_1.2.0 viridisLite_0.3.0 crayon_1.3.4
## [37] dplyr_0.7.7 MASS_7.3-51 bitops_1.0-6 gtable_0.2.0
## [41] magrittr_1.5 scales_1.0.0 stringi_1.2.4 XVector_0.22.0
## [45] viridis_0.5.1 flexmix_2.3-14 bindrcpp_0.2.2 robustbase_0.93-3
## [49] fastcluster_1.1.25 HilbertVis_1.40.0 rjson_0.2.20 RColorBrewer_1.1-2
## [53] tools_3.5.1 fpc_2.1-11.1 glue_1.3.0 trimcluster_0.1-2.1
## [57] DEoptimR_1.0-8 purrr_0.2.5 colorspace_1.3-2 GenomicRanges_1.34.0
## [61] prabclus_2.2-6 bindr_0.1.1 modeltools_0.2-22