我以為熱圖只能畫數(shù)值型數(shù)據(jù)婚脱,沒想到離散型的也行啊

離散熱圖

0.需求

今天在群里看到一個非常漂亮的熱圖,我以為是什么奇怪的新R包畫的重付,轉(zhuǎn)了一圈發(fā)現(xiàn)原來還是大名鼎鼎的ComplexHeatmap丫。今天的代碼都是在作者寫的書基礎(chǔ)上探索學習的凫乖,書在:https://jokergoo.github.io/ComplexHeatmap-reference/book/

這種圖和普通熱圖的不同點:

  • 數(shù)據(jù)是離散型的确垫,與常規(guī)的數(shù)值型熱圖不同。
  • 每行單獨配色帽芽,顏色逐行變化
  • 左右兩邊都有文字
  • 劃分的不同板塊有格子

1.學習普通的離散型熱圖

以前畫的熱圖無一例外都是連續(xù)型數(shù)值删掀,這次是離散型數(shù)據(jù)咯,矩陣里面只有四個取值导街,所以就只有四個顏色披泪。如果不指定的話,顏色就是隨機的:

rm(list = ls())
library(ComplexHeatmap)
library(RColorBrewer)
library(circlize)
discrete_mat = matrix(sample(letters[1:4], 100, replace = TRUE), 10, 10)
Heatmap(t(discrete_mat), 
        column_split = discrete_mat[, 1],
        top_annotation = HeatmapAnnotation(group = discrete_mat[, 1]),
        border = T)
請忽略配色

切割搬瑰、加邊框款票、加注釋這樣的操作,參數(shù)還是蠻好找的泽论。

編一個類似于上面那張圖的輸入數(shù)據(jù)艾少,畫畫看。每一行都是有重復(fù)值的不同向量翼悴,并且向量的取值數(shù)量都是有限的缚够。

sl = function(letter,n = sample(2:4,1),ncol = 100){
  sample(paste0(letter,1:n),ncol,replace = T)
}
table(sl("a"))
## 
## a1 a2 a3 a4 
## 21 31 25 23
dat = t(sapply(letters[1:10], sl))
rownames(dat) = LETTERS[1:10]
colnames(dat) = paste0("M",1:ncol(dat))
dat[1:4,1:4]
##   M1   M2   M3   M4  
## A "a1" "a2" "a1" "a2"
## B "b2" "b2" "b2" "b2"
## C "c1" "c1" "c1" "c2"
## D "d2" "d1" "d2" "d3"
col_group = rep(c("C1","C2","C3"),times = c(30,40,30))
row_group = rep(c("x","y"),times = c(6,4))

Heatmap(dat, name = "mat", 
        top_annotation = HeatmapAnnotation(cluster = col_group),
        left_annotation = rowAnnotation(foo1 = row_group),
        column_split = col_group,
        row_split = row_group,
        border = T,show_column_names = F)
請忽略配色

2.自定義顏色

ComplexHeatmap有一個特點,如果你不指定配色的話,每次運行相同代碼出來的圖配色都不一樣哦谍椅,所以接下來自己定義顏色误堡。

這里用到一個函數(shù):colorRamp2,出自circlize包雏吭,可以根據(jù)你指定的幾個顏色锁施,生成一組漸變色。

# 主體熱圖的顏色
m = apply(dat,1,function(x){length(unique(x))})

col_fun = colorRamp2(breaks = seq(0, 1, length.out = 12),
                     colors = brewer.pal(12,"Set3"))
qz = sort(unique(as.character(dat)));length(qz)
## [1] 28
colors = col_fun(seq(0, 1, length.out = length(qz)))
names(colors) = qz
head(colors)
##          a1          a2          b1          b2          b3          c1 
## "#8DD3C7FF" "#BFE5BFFF" "#ECF7B7FF" "#F2EFBDFF" "#D8D3CDFF" "#C2B8D6FF"
# 注釋條的顏色
color_an = brewer.pal(length(unique(col_group)),"Dark2")
names(color_an) = unique(col_group)
color_an
##        C1        C2        C3 
## "#1B9E77" "#D95F02" "#7570B3"
#頂部注釋
top_annotation = HeatmapAnnotation(cluster = col_group,col = list(cluster = color_an),show_legend = F,show_annotation_name = F)

f = Heatmap(dat, col = colors,
        top_annotation = top_annotation,
        row_split = ifelse(row_group=="x",""," "), #這一句是為了隱藏行分組的名字
        column_split = col_group,
        show_heatmap_legend = F,
        border = T,show_column_names = F,row_names_side = "left",
        right_annotation = rowAnnotation(score = anno_text(1:nrow(dat)))
        )
f
隱藏圖例了

3.自定義圖例

前面有個參數(shù)是show_heatmap_legend = F思恐,show_legend = F,是不顯示主體與注釋圖例的意思沾谜。這里之所以不顯示是為了自定義圖例。否則呢胀莹,主體熱圖的圖例就會全部放在一起基跑,不能按行來顯示哦。

# 主體熱圖的圖例
k = 1
lgd = list()
for(i in 1:10){
  un = sort(unique(dat[i,]))
  ti = rownames(dat)[i]
  lgd[[i]] = Legend(seq(0, 1, length.out = length(un)), labels = un,
               title = ti, legend_gp = gpar(fill =colors[k:(k+length(un)-1)]))
  k = k + length(un)
}
# 注釋的圖例
cld = Legend(labels = c("a1","a2","a3"), title = "cluster", 
        legend_gp = gpar(fill = color_an))

# 把各個圖例合并在一起
p = packLegend(list = c(cld,lgd),
               direction = "horizontal",gap = unit(0.6, "cm"))

draw(p)
全部的圖例哦
# 主體和圖例畫到一起
draw(f,heatmap_legend_list = p,heatmap_legend_side = "bottom")
收工
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末描焰,一起剝皮案震驚了整個濱河市媳否,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌荆秦,老刑警劉巖篱竭,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異步绸,居然都是意外死亡掺逼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門瓤介,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吕喘,“玉大人,你說我怎么就攤上這事刑桑÷戎剩” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵祠斧,是天一觀的道長闻察。 經(jīng)常有香客問我,道長琢锋,這世上最難降的妖魔是什么辕漂? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮吴超,結(jié)果婚禮上钮热,老公的妹妹穿的比我還像新娘。我一直安慰自己烛芬,他們只是感情好隧期,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布飒责。 她就那樣靜靜地躺著,像睡著了一般仆潮。 火紅的嫁衣襯著肌膚如雪宏蛉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天性置,我揣著相機與錄音拾并,去河邊找鬼。 笑死鹏浅,一個胖子當著我的面吹牛嗅义,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播隐砸,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼之碗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了季希?” 一聲冷哼從身側(cè)響起褪那,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎式塌,沒想到半個月后博敬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡峰尝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年偏窝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片武学。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡祭往,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劳淆,到底是詐尸還是另有隱情,我是刑警寧澤默赂,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布沛鸵,位于F島的核電站,受9級特大地震影響缆八,放射性物質(zhì)發(fā)生泄漏曲掰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一奈辰、第九天 我趴在偏房一處隱蔽的房頂上張望栏妖。 院中可真熱鬧,春花似錦奖恰、人聲如沸吊趾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽论泛。三九已至揩尸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屁奏,已是汗流浹背岩榆。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坟瓢,地道東北人勇边。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像折联,于是被迫代替她去往敵國和親粒褒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容