Author: Zuguang Gu ( z.gu@dkfz.de )
翻譯:詩翔
Date: 2018-10-30
一個簡單的熱圖通常用戶快速瀏覽數據。一個熱圖列表的特殊例子就是只包含一個熱圖。相比于已經存在的工具, ComplexHeatmap包提供了一種更靈活的方式支持單個熱圖的可視化。在下面的例子中,我們會說明如何設置參數以顯示一個簡單的熱圖。
首先讓我們載入包并生成一個隨機矩陣。
library(ComplexHeatmap)
library(circlize)
set.seed(123)
mat = cbind(rbind(matrix(rnorm(16, -1), 4), matrix(rnorm(32, 1), 8)),
rbind(matrix(rnorm(24, 1), 4), matrix(rnorm(48, -1), 8)))
# 置換行列
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)
顏色
大多數情況下,熱圖可視化含連續值得矩陣。在這種情況下,用戶需要提供一個顏色映射函數。一個顏色映射函數需要接收一個數值向量并返回對應的顏色。circlize包提供的colorRamp2()
對于生成這樣的函數很有用。當前該函數通過LAB顏色空間線性地在每個區間插入顏色。
在下面的例子中,-3到3的區間被線性插入值用于獲取對應的顏色,值大于3的被映射為紅色,小于-3的被映射為綠色(因此這里的顏色對于異常值具有魯棒性)。
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)
的順序。
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
值。你可以通過na_col
參數控制NA
值的顏色。包含NA
值矩陣也可以使用Heatmap()
函數聚類(因為dist()
函數接收NA
值),使用“pearson”、 “spearman” 或 “kendall” 方法會給出警告信息。
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.
對顏色插值來說顏色空間非常重要。默認情況下,顏色都是在LAB color space中線性插值,但你可以使用,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, col = f1, column_title = "LAB color space") +
Heatmap(mat, col = f2, column_title = "RGB color space")
下面圖形顯示了不同顏色空間的差別(使用HilbertCurve
包繪制)。
標題
熱圖的名字默認用作熱圖圖例的標題。如果你將多個熱圖放到一起,名字可以作為唯一的標識符。
Heatmap(mat, name = "foo")
熱圖圖例的標題可以通過參數heatmap_legend_param
進行更改。
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 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)
聚類
聚類是熱圖可視化的關鍵特征之一。該包支持高度靈活的聚類設定。
首先有一些聚類的通用設定,例如是否顯示樹狀圖、其大小。
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"))
有3種方式指定聚類的距離度量:
- 使用提前設定的選項,合法的值包括
dist()
函數支持的方法以及pearson
、spearman
和kendall
。 - 一個從矩陣中計算距離的自定義函數,函數僅包含一個參數
- 一個從兩個向量中計算距離的自定義函數,函數僅包含2個參數
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))
基于這個特征,我們開源使用配對距離應用聚類使得可以魯棒地處理異常值。
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
參數。
比較下面3幅圖:
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
包渲染你的dendrogram
對象,自定義樹狀圖。
library(dendextend)
dend = hclust(dist(mat))
dend = color_branches(dend, k = 2)
Heatmap(mat, name = "foo", cluster_rows = dend)
更通用地,cluster_rows
和cluster_columns
可以提供計算聚類的函數。自定義函數的輸入需要是一個矩陣,返回值需要時一個hclust
或者dendrogram
對象。
Heatmap(mat, name = "foo", cluster_rows = function(m) as.dendrogram(diana(m)),
cluster_columns = function(m) as.dendrogram(agnes(m)))
fastcluster::hclust
實現了更快版本的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
來設定順序。注意這個時候你需要將聚類給關掉,另外如果矩陣有行名和列名也可以直接通過名字調整順序。
Heatmap(mat, name = "foo", cluster_rows = FALSE, cluster_columns = FALSE,
row_order = 12:1, column_order = 10:1)
注意row_dend_reorder
和row_order
是不同的。前者應用于樹狀圖。因為對于樹狀圖的任何結點,旋轉兩個葉子都會給出唯一的樹狀圖。當row_order
設置時,樹狀圖會被抑制。
維度名字
維度名字的側邊、可視度和圖形參數可以進行如下設置。
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))))
當前行名和列名不支持旋轉。文字旋轉可以通過熱圖注釋實現(這在熱圖注釋手冊中將會看到)。
按行切分熱圖
熱圖可以按行切分。這可以增加熱圖中的分組可視化。參數km
設置大于1的值意味著對行實施K-means聚類并在每個子類中實施聚類。
Heatmap(mat, name = "foo", km = 2)
更通用地,split
可以傳入一個分割熱圖行不同組合水平的向量或是數據框。實際上k-means聚類也是先聚類得到行的分類然后使用split
實現切分。每一個行切片的標題可以通過combined_name_fun
參數設定。每個切片的順序通過split
中每個變量的水平控制。
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分類方法,你可以通過將分類向量傳入split
的方式使用其他方法。
pa = pam(mat, k = 3)
Heatmap(mat, name = "foo", split = paste0("pam", pa$clustering))
如果row_order
設置了,在每個切片里面,行依然是按順序排列的。
Heatmap(mat, name = "foo", row_order = 12:1, cluster_rows = FALSE, km = 2)
gap的高度可以通過gap
參數控制(單個unit或者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))
當按行切分的時候,也可以通過圖形參數自定義行標題和行名。
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
可以指定一個數。
dend = hclust(dist(mat))
dend = color_branches(dend, k = 2)
Heatmap(mat, name = "foo", cluster_rows = dend, split = 2)
或者可以直接指定split
一個整數。注意這跟km
不同。如果km
設置了,首先是要k-means聚類,然后對每個子類進行聚類。當split
是一個整數的時候,直接對整個矩陣進行聚類,然后根據cutree()
切分。
Heatmap(mat, name = "foo", split = 2)
自定義熱圖主體
rect_gp
參數提供了熱圖主體的基本圖形設置(注意fill
參數已經被禁用了)。
Heatmap(mat, name = "foo", rect_gp = gpar(col = "green", lty = 2, lwd = 2))
熱圖主體可以自定義。默認熱圖主體由帶不同填充色的矩形數組組成(這里稱為cell)。如果rect_gp
中的type
設置為none
,整個cell數組被初始化但沒有圖形,然后用戶可以通過cell_fun
自定義他們自己的圖形函數。cell_fun
應用于熱圖的每一個cell,它需要為每一個cell提供下面的信息:
-
j
- 矩陣中的列索引。 -
i
- 矩陣中的行索引 -
x
- cell中心點的x坐標 -
y
- cell中心點的y坐標 -
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))
})
下面的例子中,我們創建一個類似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)
最后一個例子是可視化圍棋,輸入數據記錄在游戲中的形勢。
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
基于矩陣的值我們放上黑子和白子。
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")
)
將熱圖主體設置為光柵圖像
將圖形以PDF格式保存時保存質量的最好方式。然而,如果行數太多(> 10000),輸出的PDF文件將非常之大。將熱圖渲染為光柵圖像可以減少文件大小。Heatmap()
函數中有4個選項控制如何生成光柵圖像:use_raster
、raster_device
、raster_quality
和raster_device_param
。
你可以通過raster_device
選擇圖像設備(png
、jpeg
和tiff
),使用raster_quality
控制圖像質量,raster_device_param
可以傳入更多參數。
會話信息
sessionInfo()
## R version 3.5.1 Patched (2018-07-12 r74967)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.8-bioc/R/lib/libRblas.so
## LAPACK: /home/biocbuild/bbs-3.8-bioc/R/lib/libRlapack.so
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
## [4] LC_COLLATE=C LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## 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