R使用筆記: heatmap.2繪制熱圖

筆記內(nèi)容:

  • 熱圖的應(yīng)用意義
  • 包的安裝
  • scale的作用
  • 作圖細節(jié):系統(tǒng)發(fā)生樹,label, color key的問題等
  • 補充:添加多行ColSideColors
  • 補充:heatmap.3示例
  • 補充:ComplexHeatmap::Heatmap

熱圖的應(yīng)用意義

在paper中常常能看到熱圖(heatmap):“形式為功能服務(wù)”。在我們常見的,使用矩陣作為Input的二維熱圖中,多為基因表達差異,16s分析中不同分組的物種豐度/相對豐度差異提供線索及可視化效果。

使用熱圖可以直觀通過顏色的深淺和差異判斷樣本/組別之間的差異。結(jié)合統(tǒng)計檢驗的顯著性結(jié)果,可以評估出顯著性的方向。熱圖可以通過算法生成系統(tǒng)樹,表現(xiàn)各個subject及feature的聚類關(guān)系。

在R中可以使用gplots包中的heatmap.2輕松畫出熱圖。但對于其scale, 系統(tǒng)樹的建立,以及很細節(jié)的字體大小,圖片大小,color key的數(shù)值范圍設(shè)置,對應(yīng)的顏色設(shè)置等,均需要通過參數(shù)的調(diào)整實現(xiàn)。雖然比起其他編程工具,R是個封裝很嚴實的軟件,這意味著許多參數(shù)不能很靈活的去修改。但這不妨礙我們充分使用它帶來的便利。

包的安裝
install.packages("gplots")
install.packages("RColorBrewer")

install.packages("devtools")
library(devtools)
install.github("stanstrup/massageR")

安裝massageR包是為了對熱圖的input矩陣做一些處理,這個包的安裝有些曲折,在win10系統(tǒng)上按照以下兩步先安裝devtools再通過github裝massageR沒問題,但是在linux系統(tǒng)上不能在R sutdio里直接這么安裝,詳見 R使用筆記第11條
在本筆記中不使用massageR包也可以,heatmap.2可以搞定。

scale的作用
plot_color = c('orange','green')[treatment]
# treatment為meta data中提取出的分組信息,必須為一個factor
# 如果在input data中把sampleID整理為分組的順序,那么會在colsidecolors這里顯示為整齊的分為兩組。

heatmap.2(x,               #Input必須是matrix
          trace="none",    # trace可以給每個色塊中添加一條線,與行平行或者與列平行。其與色塊中心的距離代表了這個值被顯示的比例。
          scale="none",    # scale在這里
          ColSideColors = plot_color,   # 按照treatment組別給每個subject一個顏色
          dendrogram = "row",   # 生成row的系統(tǒng)發(fā)生樹
          symbreaks = TRUE,
          col=rev(colorRampPalette(brewer.pal(10, "RdBu"))(20)),  # color key, 后面詳敘
          breaks = seq(-0.5,0.5,0.05),   # 還是color key
          density.info=c("none"),  # 還是color key
          margins=c(8,16),  # 調(diào)整熱圖大小比例
          cexRow = 0.8, cexCol = 1.0,   # 行列名字體大小
          srtCol = 45, offsetCol = -0.5 # 調(diào)整列名的字體傾斜45度,距離熱圖的距離縮小。
)

會出現(xiàn)這樣的圖。很丑,看不出規(guī)律。這是因為我們input的矩陣還沒有經(jīng)過標準化(normalized/scaling)。許多值集中在一個很小的范圍,突然出現(xiàn)幾個很大的值,大得不成比例。導(dǎo)致這種情況:為了照顧那幾個極端值,大部分值之間的差異被掩蓋掉了,所以留下大片幾乎一樣的顏色。標準化即經(jīng)過一定比例控制,將數(shù)據(jù)的規(guī)律保留,并將數(shù)值標化在一個相對穩(wěn)定的范圍內(nèi),更加便于作圖。

但是如果把scale的參數(shù)調(diào)整為scale="row"
scale = "row" 即針對行進行標化,

作圖細節(jié):系統(tǒng)發(fā)生樹,label,color key的問題等
heatmap.2(x,            
          trace="none",
          scale="none",    # scale在這里
          ColSideColors = plot_color,   # 按照treatment組別給每個subject一個顏色

          Rowv = TRUE,   # 決定是否要將row按照系統(tǒng)發(fā)生樹cluster的結(jié)果重新排序,注意要和dendrogram一致。同理還有Colv =  
          dendrogram = "row",   # 生成row的系統(tǒng)發(fā)生樹
          symbreaks = TRUE,
          col=rev(colorRampPalette(brewer.pal(10, "RdBu"))(20)),  
          # color key在左上角,本圖中為row-scale過,所以為row Z-score
          # 設(shè)置color key的顏色,這里為20個色塊構(gòu)成,從藍色到紅色

          breaks = seq(-0.5,0.5,0.05),   
          # 設(shè)置color key的范圍,這里必須和上面col = 的20個色塊對應(yīng)起來。
          # 從-0.5到0.5,以0.05為一個step,一共20個step, 對應(yīng)20個色塊。
          
          density.info=c("none"),  
          # 設(shè)置color key中是否需要顯示各個范圍的count數(shù)目及其比例。none就不設(shè)置。
          
          margins=c(8,16),  
          # 調(diào)整熱圖大小比例,在label的名字特別長的時候可以嘗試調(diào)整,讓Label顯示完全
          cexRow = 0.8, cexCol = 0.8,   # 行/列名字體大小
          keysize = 0.8  # 可以配合margins = 調(diào)節(jié)圖例的大小及整個圖的比例
         
          colsep = c(15, 54) 
          #在熱圖中加入白色豎線,從而將其分成不同的部分。這個表示在第15個及第54個column的位置加上豎線。同理還有rowsep = 
)

如果想把生成系統(tǒng)發(fā)生樹聚類后的數(shù)據(jù)拿出來(即獲得聚類后重新排列后的數(shù)據(jù)):

map <- heatmap.2(as.matrix(x), ...)
x_reorder <- x[rev(map$rowInd), map$colInd]
# x_reorder 為重新排序后的數(shù)據(jù)

heatmap.2的文件非常詳細,見這個鏈接

添加多行ColSideColors

需要用到heatmap.plus包,其各種參數(shù)和heatmap.2差不多,但是heatmap.2只能為ColSideColors設(shè)置與column長度相當?shù)腸haracter, heatmap.plus可以設(shè)置為matrix: 其實只用把兩個(或者多個)含有顏色分配信息的vectorcbind到一起就可以了。
調(diào)整參數(shù)為ColSideColors = color # 注意使用heatmap.plus

另外有個升級版heatmap.3,參數(shù)基于heatmap.2,同樣可以添加多行ColSideColors:

#通過devtools把heatmap.3的代碼導(dǎo)入本地:
library(devtools)
source_url("https://raw.githubusercontent.com/obigriffith/biostar-tutorials/master/Heatmaps/heatmap.3.R")
heatmap.3(...)
### 2019.7.9 notes: 這個好像不是GMD包里的heatmap.3...???但是仍然可以用...???


# 以下是GMD包里的heatmap.3,注意和上面的不一樣?。?!
# 安裝:
# (建議最好還是用上面那個heatmap.3,下面那篇帖子很全,GMD沒有多少demo,color也不知道怎么設(shè)置=_=)
packageurl <- "https://cran.r-project.org/src/contrib/Archive/GMD/GMD_0.3.3.tar.gz"
install.packages(packageurl, repos=NULL, type="source")
library(GMD)
heatmap.3(...)

參考這篇BioStars上的帖子
參考heatmap.3的文檔

heatmap.3示例
library(devtools)
source_url("https://raw.githubusercontent.com/obigriffith/biostar-tutorials/master/Heatmaps/heatmap.3.R")

install.packages("mlbench")  # 只是用里面的示例數(shù)據(jù)Glass
library(mlbench)
data(Glass)
# Glass如下所示
         RI    Na   Mg   Al    Si    K    Ca   Ba   Fe Type
1   1.52101 13.64 4.49 1.10 71.78 0.06  8.75 0.00 0.00 1
2   1.51761 13.89 3.60 1.36 72.73 0.48  7.83 0.00 0.00 1
3   1.51618 13.53 3.55 1.54 72.99 0.39  7.78 0.00 0.00 1
4   1.51766 13.21 3.69 1.29 72.61 0.57  8.22 0.00 0.00 1
5   1.51742 13.27 3.62 1.24 73.08 0.55  8.07 0.00 0.00 1

Glass$fake_gp = c(rep('g1',107),rep('g2',107))  # 加一個fake_gp的分組
Glass$fake_gp = factor(Glass$fake_gp,levels = c('g1','g2'))
# 注意一定要轉(zhuǎn)成factor
color_matrix = cbind(brewer.pal(7,"Set1")[Glass$Type],
                     c('black','grey50')[Glass$fake_gp])
colnames(color_matrix) = c('Type','fake_gp')
# 給color_matrix加上colname, 會當作colorbar名稱在圖中顯示
df = Glass[1:9]
heatmap.3(df,
          scale="col",
          dendrogram = "row",
          distfun = function(x){as.dist(1-cor(t(x)))},  # 不設(shè)置的話會用默認的
          hclustfun = function(x){hclust(x, method = 'average')},  # 不設(shè)置的話會用默認的
          Rowv = TRUE, Colv = FALSE,
          symbreaks = FALSE,
          col=rev(brewer.pal(10, "RdBu")),
          RowSideColors = t(color_matrix),  # 注意用t()轉(zhuǎn)換,因為這里是rowside, colside則不用
          breaks = seq(-1,1,0.2),
          density.info=c("none"),
          margins=c(10,10),  # 設(shè)置熱圖橫縱兩個方向的留白
          cexRow = 1, cexCol = 1,
          # colsep = c(24,48,72),
          # sepwidth = c(0.2,0.2),  # 如果需要熱圖從中間分開,則設(shè)置這兩個參數(shù)
          keysize = 0.8,
          key = TRUE,
          symkey = FALSE
          # KeyValueName = ...  # 設(shè)置這個參數(shù)則替換“Column Z-Score”文本
)


這個post很有參考價值,包括了symkey調(diào)整color的用途,不同包默認的建樹設(shè)置等。

ComplexHeatmap::Heatmap

ComplexHeatmap是一個bioconductor的包,需要這樣安裝:參考
BiocManager::install("ComplexHeatmap")

官方的Documentation, 是非常詳細的使用指南:https://jokergoo.github.io/ComplexHeatmap-reference/book/introduction.html

優(yōu)點在于自動附上了圖例;可以添加多個row或者column的annotation;在annotation是連續(xù)型變量是不用手動設(shè)置intervel??梢园裩eatmap.2中構(gòu)建的樹完整移植過來。

一個示例,使用瞎掰的數(shù)據(jù)集mat

library(ComplexHeatmap)
library(circlize)
library(dendextend)
library(RColorBrewer)

# 瞎掰數(shù)據(jù)集mat
set.seed(123)
mat = matrix(rnorm(100),10)
rownames(mat) = paste0("R",1:10)
colnames(mat) = paste0("c",1:10)

# 再掰一個meta data,用于做heatmap的annotation
meta_mat = data.frame(ind=1:10)
meta_mat$m1 = c(rep('a',5),rep('b',5))
meta_mat$m2 = c(rep('c',2),rep('d',3),rep('e',5))
meta_mat$m3 = rnorm(10)

數(shù)據(jù)集一覽:

mat
meta_mat
# 給heatmap的行做annotation, 注意對應(yīng)每個變量,指定顏色
row_ha = rowAnnotation(df=meta_mat[,c('m1','m2','m3')],
                       col=list(m1=c('a' = 'blue','b'='red'),
                                m2=c('c'='pink','d'='darkgreen','e'='grey50'),
                                m3=circlize::colorRamp2(c(-1,0,1), c("blue", "white", "red"))))

ComplexHeatmap::Heatmap(mat,name='mat',
                        column_title = 'test_mat',  
                        right_annotation = row_ha, 
                        col = rev(brewer.pal(10,"RdBu")), # 熱圖的顏色
                        column_dend_height = unit(3,"cm"),  # 設(shè)置樹的大小
                        # 這里設(shè)置了一個對聚類樹的分割及上色,在h=2.5處分簇并著色: 
                        cluster_columns = dendextend::color_branches(as.dendrogram(hclust(dist(mat))),
                                                                     h = 2.5),
                        show_column_names = F  # 不顯示column name
                        )

如果用heatmap.3來做:

meta_mat$m1 = factor(meta_mat$m1,levels = c('a','b'))
meta_mat$m2 = factor(meta_mat$m2,levels = c('c','d','e'))
# 設(shè)置intervel
meta_mat$inter = findInterval(meta_mat$m3,
                              sort(meta_mat$m3,decreasing = F))
pal = colorRampPalette(c('white','red'))

color_matrix = data.frame(
  m1=c('blue','red')[meta_mat$m1],
  m2=c('pink','darkgreen','grey50')[meta_mat$m2],
  m3=pal(nrow(meta_mat))[meta_mat$inter]
)

hh = heatmap.3(as.matrix(mat),
               dendrogram = 'both',
               distfun = function(x){as.dist(1-cor(t(x)))},
               hclustfun = function(x){hclust(x,method = 'ward.D2')},
               col = rev(brewer.pal(10,'RdBu')),
               Rowv = TRUE, Colv = TRUE,
               ColSideColors = as.matrix(color_matrix)
               )
...不好看

把heatmap.3中的樹移植到ComplexHeatmap::Heatmap中去:

ComplexHeatmap::Heatmap(mat,name='mat',
                        column_title = 'test_mat',  
                        right_annotation = row_ha, 
                        col = rev(brewer.pal(10,"RdBu")), # 熱圖的顏色
                        column_dend_height = unit(3,"cm"),  # 設(shè)置樹的大小
                        # 換成hh的術(shù),并且設(shè)置一個對聚類樹的分割及上色,在h=2.5處分簇并著色: 
                        cluster_columns = dendextend::color_branches(hh$colDendrogram,
                                                                     h = 2.5),
                        show_column_names = F  # 不顯示column name
                        )
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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