complexheatmap繪制熱圖

學(xué)習(xí)一下complexheatmap包繪制熱圖

總體設(shè)計(jì)

  • 繪制熱圖的包有很多。其實(shí)比較好用是的包有pheatmap包。一般的熱圖繪制只能只能繪制熱圖本身。并不能在熱圖旁邊繪制別的圖。為了能夠添加其他的圖,因此開(kāi)發(fā)了complexheatmap包。

  • complexheatmap包主要是可以通過(guò)不同的對(duì)于熱圖各個(gè)部分(上下左右)的注釋來(lái)擴(kuò)展熱圖的功能。

    image
  • 該包主要可以使用到函數(shù)包括

  1. Heatmap: 繪制單個(gè)的熱圖。這個(gè)圖本身就包括所有的組成

  2. HeatmapList:繪制一系列的熱圖和注釋

  3. HeatmapAnnotation:對(duì)熱圖進(jìn)行注釋?zhuān)梢院蜔釄D一起時(shí)候,也可以單獨(dú)的使用

單個(gè)熱圖

通過(guò)Heatmap我們就可以形成單個(gè)熱圖。

產(chǎn)生隨機(jī)數(shù)據(jù)

library(ComplexHeatmap)
## Loading required package: grid
## ========================================
## ComplexHeatmap version 2.0.0
## Bioconductor page: http://bioconductor.org/packages/ComplexHeatmap/
## Github page: https://github.com/jokergoo/ComplexHeatmap
## Documentation: http://jokergoo.github.io/ComplexHeatmap-reference
## 
## If you use it in published research, please cite:
## Gu, Z. Complex heatmaps reveal patterns and correlations in multidimensional 
##   genomic data. Bioinformatics 2016.
## ========================================
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))
mat[1:5,1:5]
##          column1     column2   column3     column4    column5
## row1  0.90474160 -0.35229823 0.5016096  1.26769942  0.8251229
## row2  0.90882972  0.79157121 1.0726316  0.01299521  0.1391978
## row3  0.28074668  0.02987497 0.7052595  1.21514235  0.1747267
## row4  0.02729558  0.75810969 0.5333504 -0.49637424 -0.5261114
## row5 -0.32552445  1.03264652 1.1249573  0.66695147  0.4490584

最基本的顯示

通過(guò)Heatmap函數(shù)我們可以對(duì)矩陣進(jìn)行可視化。最基本的熱圖和其他熱圖繪制工具繪制出來(lái)的是一樣的。 PS:如果我們把繪圖結(jié)果放到了一個(gè)變量里面,我們可以通過(guò)draw函數(shù)來(lái)把結(jié)果繪制出來(lái)
ht <- Heatmap(mat)
draw(ht)
圖片.png

顏色的改變

連續(xù)性變量的顏色注釋

  • 在熱圖當(dāng)中如果需要改變顏色的話(huà),一定要使用circlize::colorRamp2()來(lái)對(duì)顏色進(jìn)行賦值。這個(gè)函數(shù)接受兩個(gè)參數(shù):顏色分割的位置以及相應(yīng)分割點(diǎn)上的顏色。最后我們的Heatmap當(dāng)中通過(guò)col來(lái)制定顏色

PS:colorRamp2默認(rèn)的使用的配色方案是LAB的。如果想使用RGB的則可以通過(guò)其中的space參數(shù)進(jìn)行修改。

library(circlize)
## ========================================
## circlize version 0.4.6
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: http://jokergoo.github.io/circlize_book/book/
## 
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization 
##   in R. Bioinformatics 2014.
## ========================================
col_fun <- colorRamp2(c(-2, 0, 2), c("navy", "white", "firebrick3"))
Heatmap(mat, col = col_fun)
圖片.png
這樣設(shè)定的好處在于:

*1、 即使出現(xiàn)了異常值,在制定的顏色當(dāng)中,異常值也只是顯示最大值而不是說(shuō)是把整體的顏色分布給破壞了。我們可以比較一下pheatmap和Heatmap的結(jié)果

mat2 = mat
mat2[1, 1] = 100000
Heatmap(mat2, name = "mat", col = col_fun)
圖片.png
pheatmap::pheatmap(mat2)
圖片.png
  • 2、 另外一個(gè)好處是,如果我們要比較不同組數(shù)據(jù)的熱圖,這樣設(shè)置后,他們的數(shù)值對(duì)應(yīng)的顏色不會(huì)因?yàn)檎w分布的原因發(fā)生改變
p1 <- Heatmap(mat, name = "mat", col = col_fun, column_title = "mat")
p2 <- Heatmap(mat/4, name = "mat", col = col_fun, column_title = "mat/4")
p3 <- Heatmap(abs(mat), name = "mat", col = col_fun, column_title = "abs(mat)")
p1 + p2 + p3
## Warning: Heatmap/annotation names are duplicated: mat
## Warning: Heatmap/annotation names are duplicated: mat, mat
圖片.png

分類(lèi)變量的顏色注釋

  • 如果要繪制分類(lèi)變量的熱圖的話(huà),則需要把每個(gè)分類(lèi)的數(shù)字進(jìn)行一定的賦值。
discrete_mat = matrix(sample(1:4, 100, replace = TRUE), 10, 10)
col1 = structure(1:4, names = c("1", "2", "3", "4")) # black, red, green, blue
mycol <- colorRamp2(breaks = col1, colors = c("red", "blue", "green", "black"))
h1 <- Heatmap(discrete_mat, col = col1)
h2 <- Heatmap(discrete_mat, name = "mat", col = mycol)
h1 + h2
圖片.png

缺失值的可視化

如果數(shù)據(jù)當(dāng)中含有缺失值,如果我們不想去掉想要可視化的話(huà),可以通過(guò)na_col來(lái)指定顏色

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")
圖片.png

邊框的變化

  • 通過(guò)border,來(lái)對(duì)整個(gè)熱圖添加邊框。這個(gè)參數(shù)可以接受邏輯值或者具體的顏色
  • 每個(gè)格子的邊框的變化,我們可以通過(guò)rect_gp來(lái)進(jìn)行設(shè)置。這個(gè)參數(shù)可以通過(guò)gpar來(lái)設(shè)置其顏色以及線(xiàn)條寬度的變化。同樣可以把這個(gè)熱圖到去掉
h1 <- Heatmap(mat, border = T)
h2 <- Heatmap(mat, border = "red")
h3 <- Heatmap(mat, rect_gp = gpar(col = "white", lwd = 2))
h4 <- Heatmap(mat, rect_gp = gpar(type = "none"))
h1 + h2 + h3 + h4
圖片.png

標(biāo)題

通過(guò)上圖,我們可以使用對(duì)熱圖的四周都可以進(jìn)行標(biāo)題注釋。

  • 通過(guò)column_title以及row_title來(lái)設(shè)置標(biāo)題

  • 通過(guò)column_title_side以及row_title_side來(lái)設(shè)置標(biāo)題位置

  • 通過(guò)column_title_gp以及row_title_gp設(shè)置標(biāo)題的格式。通過(guò)gpar函數(shù)來(lái)進(jìn)行設(shè)置。

  • 通過(guò)row_title_rot以及column_title_rot設(shè)置標(biāo)題的旋轉(zhuǎn)角度

Heatmap(mat, column_title = "column title", column_title_side = "bottom", column_title_gp = gpar(fontsize = 20, fontface = "bold"), row_title_rot = 0, row_title = "row title", row_title_gp = gpar(col = "red"))
圖片.png

聚類(lèi)

基本設(shè)置

無(wú)監(jiān)督的聚類(lèi)屬于熱圖的可視化的一個(gè)重要組成部分。

  • 1、 cluster_rows/columns來(lái)設(shè)置是否進(jìn)行聚類(lèi)

  • 2、 show_column/row_dend設(shè)置是否顯示聚類(lèi)樹(shù)(會(huì)發(fā)生聚類(lèi))

  • 3 、 column/row_dend_side設(shè)置聚類(lèi)圖繪制的位置

  • 4、 column/row_dend_height設(shè)置聚類(lèi)樹(shù)的高度

Heatmap(mat, cluster_rows = F, show_column_dend = T,
        column_dend_side = "bottom",  column_dend_height = unit(2, "cm"))
圖片.png

聚類(lèi)的方法選擇

分類(lèi)聚類(lèi)只要包括兩步:計(jì)算距離矩陣以及應(yīng)用聚類(lèi)。一般來(lái)說(shuō)計(jì)算距離的方式包括pearson, spearman以及kendall。這個(gè)計(jì)算方式是通過(guò)1 - - cor(x, y, method)來(lái)實(shí)現(xiàn)的。在函數(shù)當(dāng)中則是通過(guò)clustering_distance_rows/columns來(lái)進(jìn)行實(shí)現(xiàn)的。

Heatmap(mat, name = "mat", clustering_distance_rows = "pearson",
    column_title = "pre-defined distance method (1 - pearson)")
圖片.png

聚類(lèi)樹(shù)的自定義

我們可以對(duì)聚類(lèi)樹(shù)進(jìn)行自定義,主要是可以

  • 1、 column/row_dend_gp設(shè)置聚類(lèi)圖的自定義

*2、 cluster_rows 分開(kāi)設(shè)置不同的顏色

library(dendextend)
## 
## ---------------------
## Welcome to dendextend version 1.12.0
## Type citation('dendextend') for how to cite the package.
## 
## Type browseVignettes(package = 'dendextend') for the package vignette.
## The github page is: https://github.com/talgalili/dendextend/
## 
## Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
## Or contact: <tal.galili@gmail.com>
## 
##  To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
## ---------------------
## 
## Attaching package: 'dendextend'
## The following object is masked from 'package:stats':
## 
##     cutree
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.png
Heatmap(mat, name = "mat", cluster_rows = row_dend, row_dend_gp = gpar(col = "red"))
圖片.png

基于聚類(lèi)結(jié)果進(jìn)行排序

我們可以通過(guò)column/row_dend_reorder來(lái)對(duì)聚類(lèi)的結(jié)果進(jìn)行重新排序

m2 = matrix(1:100, nr = 10, byrow = TRUE)
h1 <- Heatmap(m2, name = "mat", row_dend_reorder = FALSE, column_title = "no reordering")
h2 <- Heatmap(m2, name = "mat", row_dend_reorder = TRUE, column_title = "apply reordering")
h1 + h2
## Warning: Heatmap/annotation names are duplicated: mat
圖片.png

設(shè)置熱圖的觀(guān)測(cè)值的順序

一般情況下,熱圖當(dāng)中各個(gè)觀(guān)測(cè)值的順序是基于聚類(lèi)的分組來(lái)進(jìn)行排列的。有時(shí)候我們想要自己排序順序。這個(gè)時(shí)候就可以自定義去順序。通過(guò)row_order/column_order可以來(lái)定義其排序。 PS:當(dāng)我們自定義順序之后,聚類(lèi)的順序就隨之關(guān)閉了。

Heatmap(mat, name = "mat", row_order = sort(rownames(mat)), 
    column_order = sort(colnames(mat)))
圖片.png

觀(guān)測(cè)值的自定義

默認(rèn)情況下對(duì)于列名和行名都是顯示的。我們可以對(duì)其進(jìn)行自定義

  • 1、 show_row/colums_names設(shè)置是否顯示列名和行名

  • 2、 column/row_names_side設(shè)置列名和行名的位置

  • 3、 column/row_names_gp設(shè)置列名和行名的自定義

  • 4、 column/row_names_centered設(shè)置名稱(chēng)是否中心化

  • 5、 column/row_names_rot設(shè)置名稱(chēng)的角度

  • 6、 column/row_labels設(shè)置重新定義名稱(chēng)

  • 7、 column_names_max_height和row_names_max_width設(shè)置列名和行名的最大空間。默認(rèn)的都是6cm。如果名稱(chēng)太長(zhǎng)可以通過(guò)這個(gè)來(lái)設(shè)置。

row_labels = structure(paste0(letters[1:24], 1:24), names = paste0("row", 1:24))
Heatmap(mat, show_row_names = T, column_names_side = "top",
        row_names_gp = gpar(fontsize = 20, col = c(rep("red", 10), rep("blue", 8))), column_names_centered = TRUE, column_names_rot = 45, row_labels = row_labels[rownames(mat)])
圖片.png

熱圖的分割

熱圖的分割主要包括多種方式

  • 1、 按照k-means方法來(lái)分割??梢酝ㄟ^(guò)column/row_km參數(shù)進(jìn)行實(shí)現(xiàn)。

  • 2、 按照固定的分類(lèi)來(lái)進(jìn)行分割,可以通過(guò)row/column_split參數(shù)來(lái)實(shí)現(xiàn) 另外可以通過(guò)row_gap來(lái)設(shè)置分割的距離。

###k-means方式
Heatmap(mat, name = "mat", row_km = 2, column_km = 3)
圖片.png
### 特定的分組
Heatmap(mat, name = "mat", row_split = data.frame(rep(c("A", "B"), 9), rep(c("C", "D"), each = 9)), column_split = factor(rep(c("C", "D"), 12)))
圖片.png
Heatmap(mat, name = "mat", row_km = 3, row_gap = unit(5, "mm"))
圖片.png

熱圖本身的自定義

一般的熱圖上都是方塊形的顏色的變化。我們可以通過(guò)cell_fun參數(shù)來(lái)對(duì)熱圖本身進(jìn)行自定義。這個(gè)參數(shù)本質(zhì)是一個(gè)for循環(huán)的函數(shù)。這個(gè)接受7個(gè)參數(shù)分別是: - j矩陣當(dāng)中行的索引。 - i矩陣當(dāng)中的列的索引。 - x在熱圖當(dāng)中測(cè)量點(diǎn)的X坐標(biāo) - y在熱圖當(dāng)中測(cè)量點(diǎn)單元格Y的坐標(biāo) - width 單元格的寬度。默認(rèn)值是unit(1/nrow(sub_mat), "npc") - height單元格的高度。默認(rèn)值是unit(1/nrow(sub_mat), "npc") - fill單元格的顏色。 通過(guò)一個(gè)簡(jiǎn)單的例子我們來(lái)詳細(xì)說(shuō)一下具體的含義

small_mat = mat[1:9, 1:9]
small_mat1 = cut(small_mat, breaks = c(-Inf, 0.5,1,Inf), 
                labels = c("**","*","."))
small_mat1 = matrix(small_mat1, ncol = 9)
col_fun = colorRamp2(c(-2, 0, 2), c("green", "white", "red"))
p1 <- Heatmap(small_mat)
p2 <- Heatmap(small_mat, name = "mat", col = col_fun, 
    cell_fun = function(j, i, x, y, width, height, fill) {
        grid.text(small_mat1[i, j], x, y, gp = gpar(fontsize = 10))
})
p1 + p2
圖片.png

上述兩個(gè)熱圖的區(qū)別就在于增加了一個(gè)cell_fun參數(shù)。通過(guò)比較兩個(gè)熱圖可以明白cell_fun本質(zhì)上就是給單元格自定義。這個(gè)例子當(dāng)中,通過(guò)自定義函數(shù),我們?nèi)mall_mat1的數(shù)據(jù)放到熱圖上。放的位置及基于i,j,x,y來(lái)決定的。這個(gè)例子當(dāng)中四個(gè)參數(shù)都沒(méi)有變化。所以默認(rèn)熱圖的數(shù)據(jù)集和自定義的數(shù)據(jù)集和變化是一樣的。即:在small_data[1,1]的位置放置small_data1[1,1]的內(nèi)容。以此類(lèi)推。
由于是函數(shù)嘛,所以可以更加的自定義數(shù)據(jù)了。比如加入if來(lái)篩選數(shù)據(jù)

Heatmap(small_mat, name = "mat",  col = col_fun,
    cell_fun = function(j, i, x, y, width, height, fill) {
        if(small_mat[i, j] > 0)
            grid.text(sprintf("%.1f", small_mat[i, j]), x, y, gp = gpar(fontsize = 10))
})
圖片.png

同樣的由于自定義繪圖也是基于grid系統(tǒng)的。所以grid系統(tǒng)另外一些繪圖參數(shù)也是可以使用的。所以我們可以隱藏默認(rèn)的熱圖顯示來(lái)定義不同的圖形。

cor_mat = cor(small_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 = 10))
        }
    }, cluster_rows = FALSE, cluster_columns = FALSE,
    show_row_names = FALSE, show_column_names = FALSE)
圖片.png

熱圖的大小

我們可以通過(guò)width和height來(lái)調(diào)整整體圖片的大小。通過(guò)heatmap_width以及heatmap_height來(lái)調(diào)整熱圖部分的大小。

p1 <- Heatmap(mat, name = "mat1", width = unit(8, "cm"), height = unit(8, "cm"))
p2 <- Heatmap(mat, name = "mat2", heatmap_width = unit(8, "cm"), heatmap_height = unit(8, "cm"))
p1 + p2
圖片.png

生活很好,等你超越

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容