【R画图学习24.5】ComplexHeatmap缩放和链接注释

我们今天学习如何利用complexheatmap添加缩放和链接注释,以及如何加入词云图等。

前面我们测试过,热图中有很多行或列,但是我们只想标记其中的一些情况,用的是anno_mark。anno_mark()用于标记行或列的子集并用线连接到标签。anno_mark()至少需要两个参数:at、labels,其中at是原始矩阵的索引和labels相应的文本。

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()将热图上的单行或单列连接到标签,如果我们想多行或者多列链接到标签怎么办? 注释功能anno_link()将行或列的子集连接到可以添加更全面图形的绘图区域。

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()的重要参数是:

align_to:它定义了绘图区域(或框)如何对应于热图中的行或列。如果该值是一个索引列表,则每个框对应于列表中一个向量中带有索引的行或列。如果该值是与热图中的行或列具有相同长度的分类变量(例如因子或字符向量),则每个框对应于分类变量中每个级别的行/列。

panel_fun: 自定义函数,定义如何在框中绘制图形。该函数必须有一个index参数,它是框对应的行/列的索引。它可以有第二个参数nm,即热图中所选部分的“名称”。如果将其指定为分类变量或带有名称的列表,则对应的值nm来自align_to。

size: 盒子的大小。它们可以是纯数字,它们被视为热图总高度/宽度的相对分数。size的值也可以是绝对单位。

gap: 盒子之间的间隙。它应该是一个unit对象。

=======词云图======

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))

#上面是个最基本的词云图。单词按字体的大小排序,随机分配颜色。这里的max_width参数控制框的“最大宽度”。

#可以通过col来改变颜色

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)

    ))

=========实例测试=========

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]

#先做一个基本的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

#获得每个组的注释信息

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

#获得每个组的宽度和高度信息

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"))

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容