【R畫(huà)圖學(xué)習(xí)24.5】ComplexHeatmap縮放和鏈接注釋

我們今天學(xué)習(xí)如何利用complexheatmap添加縮放和鏈接注釋服鹅,以及如何加入詞云圖等逻卖。

前面我們測(cè)試過(guò)粘捎,熱圖中有很多行或列形纺,但是我們只想標(biāo)記其中的一些情況丘侠,用的是anno_mark。anno_mark()用于標(biāo)記行或列的子集并用線連接到標(biāo)簽挡篓。anno_mark()至少需要兩個(gè)參數(shù):at、labels帚称,其中at是原始矩陣的索引和labels相應(yīng)的文本官研。

library(ComplexHeatmap)

library(circlize)

library(dendextend)

library(patchwork)

library(wordcloud)

library(simplifyEnrichment)


m = matrix(rnorm(1000), nrow = 100)

rownames(m) = 1:100

ha = rowAnnotation(foo = anno_mark(at = c(1:4, 20, 60, 97:100), labels = month.name[1:10]))

Heatmap(m, name = "mat", cluster_rows = FALSE, right_annotation = ha,

? ? row_names_side = "left", row_nam


但是,anno_mark()將熱圖上的單行或單列連接到標(biāo)簽闯睹,如果我們想多行或者多列鏈接到標(biāo)簽怎么辦戏羽? 注釋功能anno_link()將行或列的子集連接到可以添加更全面圖形的繪圖區(qū)域。

set.seed(123)

m = matrix(rnorm(100*10), nrow = 100)

subgroup = sample(letters[1:3], 100, replace = TRUE, prob = c(1, 5, 10))

rg = range(m)

panel_fun = function(index, nm) {

? ? pushViewport(viewport(xscale = rg, yscale = c(0, 2)))

? ? grid.rect()

? ? grid.xaxis(gp = gpar(fontsize = 8))

? ? grid.boxplot(m[index, ], pos = 1, direction = "horizontal")

? ? popViewport()

}

anno = anno_link(align_to = subgroup, which = "row", panel_fun = panel_fun,

? ? size = unit(2, "cm"), gap = unit(1, "cm"), width = unit(4, "cm"))

Heatmap(m, name = "mat", right_annotation = rowAnnotation(foo = anno), row_split = subgroup)

anno_link()的重要參數(shù)是:

align_to:它定義了繪圖區(qū)域(或框)如何對(duì)應(yīng)于熱圖中的行或列楼吃。如果該值是一個(gè)索引列表始花,則每個(gè)框?qū)?yīng)于列表中一個(gè)向量中帶有索引的行或列妄讯。如果該值是與熱圖中的行或列具有相同長(zhǎng)度的分類變量(例如因子或字符向量),則每個(gè)框?qū)?yīng)于分類變量中每個(gè)級(jí)別的行/列酷宵。

panel_fun: 自定義函數(shù)亥贸,定義如何在框中繪制圖形。該函數(shù)必須有一個(gè)index參數(shù)浇垦,它是框?qū)?yīng)的行/列的索引炕置。它可以有第二個(gè)參數(shù)nm,即熱圖中所選部分的“名稱”男韧。如果將其指定為分類變量或帶有名稱的列表朴摊,則對(duì)應(yīng)的值nm來(lái)自align_to。

size: 盒子的大小此虑。它們可以是純數(shù)字甚纲,它們被視為熱圖總高度/寬度的相對(duì)分?jǐn)?shù)。size的值也可以是絕對(duì)單位朦前。

gap: 盒子之間的間隙介杆。它應(yīng)該是一個(gè)unit對(duì)象。

=======詞云圖======

set.seed(123)

words = sapply(1:30, function(x) strrep(sample(letters, 1), sample(3:10, 1)))

fontsize = runif(30, min = 5, max = 30)

library(grid)

gb = word_cloud_grob(words, fontsize = fontsize, max_width = unit(100, "mm"))

grid.newpage()

grid.draw(gb)

grid.rect(width = grobWidth(gb), height = grobHeight(gb), gp = gpar(fill = NA))

#上面是個(gè)最基本的詞云圖况既。單詞按字體的大小排序这溅,隨機(jī)分配顏色。這里的max_width參數(shù)控制框的“最大寬度”棒仍。

#可以通過(guò)col來(lái)改變顏色

gb = word_cloud_grob(words, fontsize = fontsize, max_width = unit(100, "mm"), col = 1:30)

grid.newpage()

grid.draw(gb)

grid.rect(width = grobWidth(gb), height = grobHeight(gb), gp = gpar(fill = NA))

#可以自己制定任何形式的col

library(circlize)

col_fun = colorRamp2(c(5, 17, 30), c("blue", "black", "red"))

gb = word_cloud_grob(words, fontsize = fontsize, max_width = unit(100, "mm"),

? ? col = col_fun)

grid.newpage()

grid.draw(gb)

grid.rect(width = grobWidth(gb), height = grobHeight(gb), gp = gpar(fill = NA))

=====詞云圖作為heatmap注釋======

gb = word_cloud_grob(words, fontsize = fontsize, max_width = unit(100, "mm"))

gb_h = grobHeight(gb)? ?#獲得詞云圖的高度

gb_w = grobWidth(gb)? #獲得詞云圖的寬度


m = matrix(rnorm(100), 10)

ht = Heatmap(m, cluster_rows = FALSE)

ht


panel_fun = function(index, nm) {

? ? grid.rect(gp = gpar(fill = "#EEEEEE", col = NA))

? ? grid.draw(gb)

}


ht + rowAnnotation(word_cloud = anno_link(align_to = 1:3, which = "row",

? ? ? ? panel_fun = panel_fun, size = gb_h,

? ? ? ? width = gb_w + unit(5, "mm"), # the link is 5mm

? ? ? ? link_gp = gpar(fill = "#EEEEEE", col = NA)

? ? ))

=========實(shí)例測(cè)試=========

tmp_file = tempfile()

download.file("https://jokergoo.github.io/word_cloud_annotation_example.RData", destfile = tmp_file, quiet = TRUE)

load(tmp_file)

mat[1:6, 1:6]

#先做一個(gè)基本的heatmap

Heatmap(mat, col = colorRamp2(c(0, 1), c("white", "red")),

? ? name = "Similarity",

? ? show_row_names = FALSE, show_column_names = FALSE,

? ? show_row_dend = FALSE, show_column_dend = FALSE,

? ? row_split = cl, column_split = cl,

? ? border = "#404040", row_title = NULL, column_title = NULL,

? ? row_gap = unit(0, "mm"), column_gap = unit(0, "mm"))

ht = Heatmap(mat, col = colorRamp2(c(0, 1), c("white", "red")),

? ? name = "Similarity",

? ? show_row_names = FALSE, show_column_names = FALSE,

? ? show_row_dend = FALSE, show_column_dend = FALSE,

? ? row_split = cl, column_split = cl,

? ? border = "#404040", row_title = NULL, column_title = NULL,

? ? row_gap = unit(0, "mm"), column_gap = unit(0, "mm"))


#首先獲得分組信息

align_to = split(seq_len(nrow(mat)), cl)

align_to = align_to[names(align_to) != "0"]

align_to = align_to[names(align_to) %in% names(keywords)]

align_to

#獲得每個(gè)組的注釋信息

fontsize_range = c(4, 16)

gbl = lapply(names(align_to), function(nm) {

? ? kw = keywords[[nm]][, 1]

? ? freq = keywords[[nm]][, 2]

? ? fontsize = scale_fontsize(freq, rg = c(1, max(10, freq)), fs = fontsize_range)

? ? word_cloud_grob(text = kw, fontsize = fontsize)

})

names(gbl) = names(align_to)

gbl

#獲得每個(gè)組的寬度和高度信息

margin = unit(8, "pt")

gbl_h = lapply(gbl, function(x) convertHeight(grobHeight(x), "cm") + margin)

gbl_h = do.call(unit.c, gbl_h)

gbl_w = lapply(gbl, function(x) convertWidth(grobWidth(x), "cm"))

gbl_w = do.call(unit.c, gbl_w)

gbl_w = max(gbl_w) + margin


panel_fun = function(index, nm) {

? ? # background

? ? grid.rect(gp = gpar(fill = "#DDDDDD", col = NA))

? ? # border

? ? grid.lines(c(0, 1, 1, 0), c(0, 0, 1, 1), gp = gpar(col = "#AAAAAA"),

? ? ? ? default.units = "npc")

? ? gb = gbl[[nm]]

? ? # a viewport within the margins

? ? pushViewport(viewport(x = margin/2, y = margin/2,

? ? ? ? width = grobWidth(gb), height = grobHeight(gb),

? ? ? ? just = c("left", "bottom")))

? ? grid.draw(gb)

? ? popViewport()

}

ht = ht + rowAnnotation(keywords = anno_link(align_to = align_to,

? ? which = "row", panel_fun = panel_fun,

? ? size = gbl_h, gap = unit(2, "mm"),

? ? width = gbl_w + unit(5, "mm"), # 5mm for the link

? ? link_gp = gpar(fill = "#DDDDDD", col = "#AAAAAA"),

? ? internal_line = FALSE)) # you can set it to TRUE to see what happens

draw(ht, ht_gap = unit(2, "pt"))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末悲靴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子莫其,更是在濱河造成了極大的恐慌癞尚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乱陡,死亡現(xiàn)場(chǎng)離奇詭異浇揩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)憨颠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)胳徽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人爽彤,你說(shuō)我怎么就攤上這事养盗。” “怎么了适篙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵往核,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我嚷节,道長(zhǎng)聂儒,這世上最難降的妖魔是什么虎锚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮衩婚,結(jié)果婚禮上窜护,老公的妹妹穿的比我還像新娘。我一直安慰自己谅猾,他們只是感情好柄慰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著税娜,像睡著了一般坐搔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敬矩,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天概行,我揣著相機(jī)與錄音,去河邊找鬼弧岳。 笑死凳忙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的禽炬。 我是一名探鬼主播涧卵,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼腹尖!你這毒婦竟也來(lái)了柳恐?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤热幔,失蹤者是張志新(化名)和其女友劉穎乐设,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绎巨,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡近尚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了场勤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戈锻。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖和媳,靈堂內(nèi)的尸體忽然破棺而出格遭,到底是詐尸還是另有隱情,我是刑警寧澤窗价,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布如庭,位于F島的核電站叹卷,受9級(jí)特大地震影響撼港,放射性物質(zhì)發(fā)生泄漏坪它。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一帝牡、第九天 我趴在偏房一處隱蔽的房頂上張望往毡。 院中可真熱鬧,春花似錦靶溜、人聲如沸开瞭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嗤详。三九已至,卻和暖如春瓷炮,著一層夾襖步出監(jiān)牢的瞬間葱色,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工娘香, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苍狰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓烘绽,卻偏偏與公主長(zhǎng)得像淋昭,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子安接,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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