ComplexHeatmap復(fù)雜熱圖繪制學(xué)習(xí)——5.圖例

圖例

默認(rèn)情況下滔灶,熱圖和簡(jiǎn)單注釋會(huì)自動(dòng)生成圖例若贮,生成的圖例放在熱圖的右側(cè)作箍。復(fù)雜注釋沒(méi)有圖例,但可以手動(dòng)構(gòu)建和添加它們妈经。所有圖例都是由構(gòu)造函數(shù)Legend()內(nèi)部構(gòu)造的 。在后面的部分中捧书,我們首先介紹了連續(xù)圖例和離散圖例的設(shè)置吹泡,然后我們將討論如何配置與熱圖和注釋關(guān)聯(lián)的圖例,以及如何將新圖例添加到圖中经瓷。

所有的圖例(無(wú)論是單個(gè)圖例還是一組圖例)都屬于Legends類爆哑。該類只有一個(gè)槽位grob,它是真實(shí) grid::grob對(duì)象或grid::gTree記錄如何繪制圖形的對(duì)象舆吮。Legends類的包裝和類設(shè)計(jì)的方法使圖例成為單個(gè)對(duì)象揭朝,并且可以像點(diǎn)一樣繪制在指定視圖上的一個(gè)位置。

熱圖和注釋的圖例可以由 Heatmap()中的heatmap_legend_param參數(shù)或HeatmapAnnotation()中的annotation_legend_param 參數(shù)控制歪泳。函數(shù)Legend()中的大部分參數(shù)都可以直接設(shè)置在參數(shù)名稱相同的兩個(gè)參數(shù)中萝勤。設(shè)置熱圖圖例和注釋圖例參數(shù)的詳細(xì)信息在第5.4節(jié)中介紹。

5.1連續(xù)圖例

由于大多數(shù)熱圖包含連續(xù)值呐伞,我們首先介紹連續(xù)圖例的設(shè)置敌卓。

連續(xù)圖例需要一個(gè)顏色映射函數(shù),它應(yīng)該由 circlize::colorRamp2(). 在自動(dòng)生成的熱圖圖例和注釋圖例中伶氢, 從Heatmap()HeatmapAnnotation()函數(shù)通過(guò)col參數(shù)傳遞顏色映射函數(shù) 趟径,而如果您構(gòu)建自定義圖例瘪吏,則需要提供顏色映射函數(shù)。

顏色映射函數(shù)中提供的中斷值(例如 c(0, 0.5, 1) 在以下示例中)將與圖例中的中斷值不完全相同)蜗巧。圖例中顯示的最終中斷值經(jīng)過(guò)內(nèi)部調(diào)整掌眠,使標(biāo)簽數(shù)量接近 5 或 6。

首先我們展示一個(gè)垂直連續(xù)圖例的默認(rèn)樣式:

library(circlize)
col_fun = colorRamp2(c(0, 0.5, 1), c("blue", "white", "red"))
lgd = Legend(col_fun = col_fun, title = "foo")
image

lgd是一個(gè)Legends類對(duì)象幕屹。圖例的大小可以通過(guò)ComplexHeatmap:::width()ComplexHeatmap:::height()函數(shù)獲得 蓝丙。

ComplexHeatmap:::width(lgd)
## [1] 9.90361111111111mm
ComplexHeatmap:::height(lgd)
## [1] 30.2744052165491mm

圖例實(shí)際上是一個(gè)由矩形、線條和文本組成的圖形對(duì)象望拖。它可以通過(guò)draw()函數(shù)添加到繪圖中渺尘。在 ComplexHeatmap包中,您不需要直接在圖例對(duì)象上使用draw()说敏,但如果您在其他地方使用圖例對(duì)象鸥跟,它可能會(huì)很有用。

pushViewport(viewport(width = 0.9, height = 0.9))
grid.rect()  # border
draw(lgd, x = unit(1, "cm"), y = unit(1, "cm"), just = c("left", "bottom"))
draw(lgd, x = unit(0.5, "npc"), y = unit(0.5, "npc"))
draw(lgd, x = unit(1, "npc"), y = unit(1, "npc"), just = c("right", "top"))
popViewport()
image

如果您只想配置熱圖或注釋生成的圖例盔沫,則無(wú)需Legends自行構(gòu)建對(duì)象医咨。 后面介紹的參數(shù)可以直接通過(guò)Heatmap()中的參數(shù)heatmap_legend_param和 自定義圖例HeatmapAnnotation()中的參數(shù)annotation_legend_param5.4節(jié)介紹 )。在以下示例中看到這些參數(shù)如何改變圖例的樣式后效果依然很好架诞。以下是一個(gè)簡(jiǎn)單的示例拟淮,展示了如何在熱圖和熱圖注釋中配置圖例。

Heatmap(matrix(rnorm(100), 10), 
    heatmap_legend_param = list(
        title = "rnorm", at = c(-2, 0, 2), 
        labels = c("neg_two", "zero", "pos_two")
    ),
    top_annotation = HeatmapAnnotation(
        foo = 1:10,
        annotation_legend_param = list(foo = list(title = "foo_top_anno"))
    ))
image

在下面的例子中谴忧,我們只展示了如何構(gòu)造圖例對(duì)象惩歉,而不展示繪制圖例的代碼。只記得你可以在Legends對(duì)象上使用draw() 函數(shù)在圖上繪制單個(gè)圖例俏蛮。

對(duì)于連續(xù)圖例,您可以通過(guò)設(shè)置手動(dòng)調(diào)整圖例中的中斷值at上遥。注意高度是自動(dòng)調(diào)整的搏屑。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.25, 0.5, 0.75, 1))
image

中斷值對(duì)應(yīng)的標(biāo)簽由labels設(shè)置。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.5, 1), 
    labels = c("low", "median", "high"))
image

垂直連續(xù)圖例的高度由legend_height設(shè)置粉楚。 legend_height只能為垂直連續(xù)圖例設(shè)置辣恋,值為圖例主體的高度(不包括圖例標(biāo)題)。

lgd = Legend(col_fun = col_fun, title = "foo", legend_height = unit(6, "cm"))
image

如果是垂直圖例模软,則grid_width控制圖例主體的寬度伟骨。grid_width最初是為離散圖例設(shè)計(jì)的,其中圖例中的每個(gè)級(jí)別都是一個(gè)網(wǎng)格燃异,但在這里我們對(duì)控制圖例寬度的參數(shù)使用相同的名稱携狭。

lgd = Legend(col_fun = col_fun, title = "foo", grid_width = unit(1, "cm"))
image

標(biāo)簽的圖形參數(shù)由labels_gp控制。

lgd = Legend(col_fun = col_fun, title = "foo", labels_gp = gpar(col = "red", font = 3))
image

圖例的邊框以及中斷值的刻度由border控制回俐。border的值可以是邏輯值或顏色字符串逛腿。

lgd = Legend(col_fun = col_fun, title = "foo", border = "red")
image

title_position控制標(biāo)題的位置稀并。對(duì)于垂直的圖例,這個(gè)值應(yīng)該是一個(gè)topleft单默,topcenter碘举,lefttop-rotleftcenter-rot。以下兩張圖顯示了lefttop-rot標(biāo)題和leftcenter-rot標(biāo)題的效果搁廓。

lgd = Legend(col_fun = col_fun, title = "foooooooo", title_position = "lefttop-rot",
    legend_height = unit(4, "cm"))
image
lgd = Legend(col_fun = col_fun, title = "foooooooo", title_position = "leftcenter-rot",
    legend_height = unit(4, "cm"))
image

圖例標(biāo)題和標(biāo)簽可以設(shè)置為數(shù)學(xué)公式引颈。

lgd = Legend(col_fun = col_fun, title = expression(hat(beta) == (X^t * X)^{-1} * X^t * y), 
    at = c(0, 0.25, 0.5, 0.75, 1), labels = expression(alpha, beta, gamma, delta, epsilon))
image

可以使用gridtext包(gridtext)添加更復(fù)雜的文本。

lgd = Legend(col_fun = col_fun, 
    title = gt_render("<span style='color:orange'>**Legend title**</span>"), 
    title_gp = gpar(box_fill = "grey"),
    at = c(-3, 0, 3), 
    labels = gt_render(c("<span style='color:blue'>*negative*</span> three", "zero", 
                         "<span style='color:red'>*positive*</span> three"))
)
image

用于水平連續(xù)圖例設(shè)置是幾乎相同的垂直圖例境蜕,所不同的是現(xiàn)在控制圖例的寬度蝙场,legend_width和標(biāo)題位置只能topcentertopleft汽摹,lefttopleftcenter之一李丰。

水平圖例的默認(rèn)樣式:

lgd = Legend(col_fun = col_fun, title = "foo", direction = "horizontal")
image

手動(dòng)設(shè)置at

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.25, 0.5, 0.75, 1), 
    direction = "horizontal")
image

手動(dòng)設(shè)置labels

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.5, 1), 
    labels = c("low", "median", "high"), direction = "horizontal")
image

設(shè)置legend_width

lgd = Legend(col_fun = col_fun, title = "foo", legend_width = unit(6, "cm"), 
    direction = "horizontal")
image

設(shè)置標(biāo)簽的圖形參數(shù):

lgd = Legend(col_fun = col_fun, title = "foo", labels_gp = gpar(col = "red", font = 3), 
    direction = "horizontal")
image

設(shè)置標(biāo)簽的旋轉(zhuǎn)。

lgd = Legend(col_fun = col_fun, title = "foo", labels_rot = 45, 
    direction = "horizontal")
image

標(biāo)題可以設(shè)置為topleft,topcenterlefttopleftcenter逼泣。

lgd = Legend(col_fun = col_fun, title = "foooooooo", direction = "horizontal", 
    title_position = "topcenter")
image
lgd = Legend(col_fun = col_fun, title = "foooooooo", direction = "horizontal", 
    title_position = "lefttop")
image

在我們上面展示的例子中趴泌,每?jī)蓚€(gè)中斷值之間的間隔是相等的。實(shí)際上at也可以設(shè)置為間隔不等的中斷值拉庶。在這種情況下嗜憔,圖例上的刻度仍然在原始位置,而相應(yīng)的文本被移動(dòng)以消除重疊氏仗。然后吉捶,有連接刻度線和標(biāo)簽的線。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1))
image

如果標(biāo)簽不需要調(diào)整皆尔,它們?nèi)匀辉谠瓉?lái)的地方呐舔。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.3, 1), 
    legend_height = unit(4, "cm"))
image

水平圖例類似:

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
    direction = "horizontal")
image

將標(biāo)簽的旋轉(zhuǎn)設(shè)置為 90 度。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
    direction = "horizontal", title_position = "lefttop", labels_rot = 90)
image

當(dāng)標(biāo)題位置設(shè)置為lefttop時(shí)慷蠕,在計(jì)算標(biāo)簽調(diào)整位置時(shí)也會(huì)考慮標(biāo)題下方的區(qū)域珊拼。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(0, 0.1, 0.5, 0.75, 1),
    labels = c("mininal", "q10", "median", "q75", "maximal"),
    direction = "horizontal", title_position = "lefttop")
image

如果按降序設(shè)置at,則圖例反轉(zhuǎn)流炕,即 最小值 在圖例的頂部澎现。

lgd = Legend(col_fun = col_fun, title = "foo", at = c(1, 0.8, 0.6, 0.4, 0.2, 0))
image

大多數(shù)連續(xù)的圖例都有等距的圖例中斷, 例如每辟,第一次和第二次中斷之間的距離與第二次和第三次中斷之間的距離相同剑辫。但是,仍然存在一些特殊情況渠欺,如何設(shè)置不等距的圖例中斷呢妹蔽?

在以下示例中,顏色映射函數(shù)col_fun_prop將比例值可視化為c(0, 0.05, 0.1, 0.5, 1)中的中斷。距離不等的圖例中斷可能反映了c(0, 1)中值的不同重要性讹开。例如盅视,也許我們想在c(0, 0.1)中查看更多詳細(xì)信息。

以下是圖例的默認(rèn)樣式旦万,其中從 0 到 1 以相等的距離選擇中斷闹击。

col_fun_prop = colorRamp2(c(0, 0.05, 0.1, 0.5, 1), 
    c("green", "white", "red", "black", "blue"))
lgd = Legend(col_fun = col_fun_prop, title = "Prop")
image

你看不到c(0, 0.1)間隔中的細(xì)節(jié),因?yàn)樵O(shè)置中斷colorRamp2()僅定義了顏色映射成艘,而不能確定圖例中的中斷赏半。

如果我們手動(dòng)選擇中斷值,顏色條保持不變淆两。標(biāo)簽被移動(dòng)断箫,線將它們連接到原始位置。在這種情況下秋冰,顏色條中的距離仍然與中斷值的實(shí)際差異成正比仲义, 0.5-1 之間的距離是 0-0.1 的五倍。

col_fun_prop = colorRamp2(c(0, 0.05, 0.1, 0.5, 1), 
    c("green", "white", "red", "black", "blue"))
lgd = Legend(col_fun = col_fun_prop, title = "Prop",
    at = c(0, 0.05, 0.1, 0.5, 1))
image

從版本 2.7.1 開始剑勾,Legend()函數(shù)有一個(gè)新參數(shù)break_dist埃撵,用于控制圖例中兩個(gè)相鄰中斷值之間的距離。 可能會(huì)令人困惑虽另,但從這里開始暂刘,當(dāng)提到“中斷距離”時(shí),它總是指圖例中的視覺距離捂刺。

break_dist的值的長(zhǎng)度應(yīng)為 1谣拣,這意味著所有中斷值在圖例中的距離相等,或者length(at) - 1.

lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = 1)
image

在下面的示例中族展,頂部的兩個(gè)中斷間隔比底部的兩個(gè)間隔長(zhǎng)三倍森缠。

lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = c(1, 1, 3, 3))
image

如果我們通過(guò)legend_height參數(shù)增加圖例高度,標(biāo)簽將有足夠的空間仪缸,它們的位置不再調(diào)整辅鲸。

lgd = Legend(col_fun = col_fun_prop, title = "Prop", break_dist = c(1, 1, 3, 3),
    legend_height = unit(4, "cm"))
image

想象以下用戶案例,我們想對(duì)c(0, 0.1)中的值使用一種顏色方案腹殿,對(duì)c(0.1, 1)中的值使用第二種顏色方案,進(jìn)而強(qiáng)調(diào)這兩個(gè)區(qū)間非常不同例书。顏色映射可以定義為:

col_fun2 = colorRamp2(c(0, 0.1, 0.1+1e-6, 1), c("white", "red", "yellow", "blue"))

所以在這里我只是在(1e-6)到 0.1 上添加了一個(gè)微小的偏移锣尉,并將其設(shè)置為第二個(gè)配色方案的下限。圖例如下:

lgd = Legend(col_fun = col_fun2, title = "Prop", at = c(0, 0.05, 0.1, 0.5, 1),
    break_dist = c(1, 1, 3, 3), legend_height = unit(4, "cm"))
image

現(xiàn)在您可以看到顏色從 0 到 1 并沒(méi)有平滑地變化决采,并且有兩種不同的配色方案自沧。

5.2 離散圖例

離散圖例用于離散顏色映射。通過(guò)僅提供顏色和中斷值,連續(xù)顏色映射也可以變化為離散顏色映射拇厢。

您可以指定atlabels爱谁,但最有可能指定 labels。顏色應(yīng)由legend_gp指定孝偎。

lgd = Legend(at = 1:6, title = "foo", legend_gp = gpar(fill = 1:6))
image
lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6))
image

連續(xù)顏色映射的離散圖例:

at = seq(0, 1, by = 0.2)
lgd = Legend(at = at, title = "foo", legend_gp = gpar(fill = col_fun(at)))
image

標(biāo)題位置:

lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6),
    title_position = "lefttop")
image
lgd = Legend(labels = month.name[1:6], title = "foo", legend_gp = gpar(fill = 1:6),
    title_position = "leftcenter-rot")
image

網(wǎng)格的大小由grid_widthgrid_height控制访敌。

lgd = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "foo", 
    grid_height = unit(1, "cm"), grid_width = unit(5, "mm"))
image

標(biāo)簽的圖形參數(shù)由labels_gp控制。

lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo", 
    labels_gp = gpar(col = "red", fontsize = 14))
image

標(biāo)題的圖形參數(shù)由title_gp控制衣盾。

lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo", 
    title_gp = gpar(col = "red", fontsize = 14))
image

通過(guò)結(jié)合gridtext包寺旺,標(biāo)題和標(biāo)簽可以是復(fù)雜的文本(拓展知識(shí)):

lgd = Legend(
    title = gt_render("<span style='color:orange'>**Legend title**</span>"), 
    title_gp = gpar(box_fill = "grey"),
    at = c(-3, 0, 3), 
    labels = gt_render(c("**negative** three", "*zero*", "**positive** three")),
    legend_gp = gpar(fill = 1:3)
)
image

網(wǎng)格的邊界由border控制。

lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foo", 
    border = "red")
image

您可以將離散圖例的網(wǎng)格排列成多行或者多列势决。如果ncol設(shè)置為數(shù)字阻塑,則網(wǎng)格按ncol列排列。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), 
    title = "foo", ncol = 3)
image

仍然根據(jù)多列圖例計(jì)算標(biāo)題位置果复。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo", 
    ncol = 3, title_position = "topcenter")
image

您可以通過(guò)設(shè)置by_row = TRUE來(lái)選擇按行列出圖例級(jí)別陈莽。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo", 
    ncol = 3, by_row = TRUE)
image

兩列之間的間隙由gapcolumn_gap控制。這兩個(gè)參數(shù)的處理方式相同虽抄。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo", 
    ncol = 3, gap = unit(1, "cm"))
image

行之間的間隙由row_gap控制走搁。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), title = "foo", 
    ncol = 3, row_gap = unit(5, "mm"))
image

您還可以通過(guò)nrow指定布局代替ncol。但請(qǐng)注意极颓,不能同時(shí)使用ncolnrow朱盐。

lgd = Legend(labels = month.name[1:10], legend_gp = gpar(fill = 1:10), 
    title = "foo", nrow = 3)
image

一種極端情況是所有級(jí)別都放在一排并且標(biāo)題旋轉(zhuǎn) 90 度。圖例的高度將是旋轉(zhuǎn)標(biāo)題的高度菠隆。

lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foooooo", 
    nrow = 1, title_position = "lefttop-rot")
image

很多人可能會(huì)喜歡以下風(fēng)格:

lgd = Legend(labels = month.name[1:6], legend_gp = gpar(fill = 1:6), title = "foooooo", 
    nrow = 1, title_position = "leftcenter")
image

Legend()還支持使用簡(jiǎn)單的圖形(例如點(diǎn)兵琳、線、箱線圖)作為圖例骇径。type參數(shù)可以指定為points或者p躯肌,可以使用數(shù)字或單字母作為pch

lgd = Legend(labels = month.name[1:6], title = "foo", type = "points", 
    pch = 1:6, legend_gp = gpar(col = 1:6), background = "#FF8080")
image
lgd = Legend(labels = month.name[1:6], title = "foo", type = "points", 
    pch = letters[1:6], legend_gp = gpar(col = 1:6), background = "white")
image

設(shè)置type = "lines"/type = "l"使用線條作為圖例:

lgd = Legend(labels = month.name[1:6], title = "foo", type = "lines", 
    legend_gp = gpar(col = 1:6, lty = 1:6), grid_width = unit(1, "cm"))
image

設(shè)置type = "boxplot"/type = "box"使用箱線圖作為圖例:

lgd = Legend(labels = month.name[1:6], title = "foo", type = "boxplot",
    legend_gp = gpar(fill = 1:6))
image

當(dāng)pch是整數(shù)時(shí)破衔,其中的數(shù)字26:28對(duì)應(yīng)以下符號(hào):

lgd = Legend(labels = paste0("pch = ", 26:28), type = "points", pch = 26:28)
image

在上面顯示的所有示例中清女,標(biāo)簽都是單行。還支持多行標(biāo)簽晰筛。如以下示例所示嫡丙,多線標(biāo)簽的圖例網(wǎng)格會(huì)自動(dòng)延長(zhǎng)。

lgd = Legend(labels = c("aaaaa\naaaaa", "bbbbb\nbbbbb", "c", "d"),
    legend_gp = gpar(fill = 1:4))
image

如果圖例排列成多行或多列读第,則圖例網(wǎng)格的大小將調(diào)整為行數(shù)最多的標(biāo)簽曙博。

lgd = Legend(labels = c("aaaaa\naaaaa", "c", "d", "bbbbb\nbbbbb"),
    legend_gp = gpar(fill = 1:4), nrow = 2)
image

最后一個(gè)有用的參數(shù)graphics可用于自定義圖例圖形。graphics的值是一個(gè)帶有四個(gè)參數(shù)的函數(shù)列表:xy:圖例網(wǎng)格的中心怜瞒,wh:圖例網(wǎng)格的寬度和高度父泳。of 的長(zhǎng)度graphics應(yīng)與atlabels相同。如果graphics名稱對(duì)應(yīng)命名列表 labels,則graphics自動(dòng)調(diào)整列表的順序惠窄。

lgd = Legend(labels = letters[1:4],
    graphics = list(
        function(x, y, w, h) grid.rect(x, y, w*0.33, h, gp = gpar(fill = "red")),
        function(x, y, w, h) grid.rect(x, y, w, h*0.33, gp = gpar(fill = "blue")),
        function(x, y, w, h) grid.text("A", x, y, gp = gpar(col = "darkgreen")),
        function(x, y, w, h) grid.points(x, y, gp = gpar(col = "orange"), pch = 16)
    ))
image

5.3 圖例列表

圖例列表可以構(gòu)建或打包為一個(gè)Legends對(duì)象蒸眠,其中各個(gè)圖例在特定布局內(nèi)排列。圖例列表可以單獨(dú)發(fā)送packLegend()或作為列表發(fā)送杆融。圖例可以垂直或水平排列楞卡。在**ComplexHeatmap **內(nèi)部使用packLegend() 來(lái)排列多個(gè)圖例。通常您不需要手動(dòng)控制多個(gè)圖例的排列擒贸,但如果您想手動(dòng)構(gòu)建圖例列表并應(yīng)用于其他圖臀晃,以下部分將非常有用。

lgd1 = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "legend1")
lgd2 = Legend(col_fun = col_fun, title = "legend2", at = c(0, 0.25, 0.5, 0.75, 1))
lgd3 = Legend(labels = month.name[1:3], legend_gp = gpar(fill = 7:9), title = "legend3")

pd = packLegend(lgd1, lgd2, lgd3)
# which is same as 
pd = packLegend(list = list(lgd1, lgd2, lgd3))
image

與單個(gè)圖例類似介劫,您可以按draw() 功能繪制打包圖例徽惋。您還可以獲得pdbyComplexHeatmap:::width()和 的大小ComplexHeatmap:::height()

ComplexHeatmap:::width(pd)
## [1] 19.1675555555556mm
ComplexHeatmap:::height(pd)
## [1] 78.6988333333334mm

通過(guò)設(shè)置水平排列圖例座韵,只需direction = "horizontal"险绘。

pd = packLegend(lgd1, lgd2, lgd3, direction = "horizontal")
image

packLegend()的一個(gè)特點(diǎn)是,例如誉碴,如果包裝是垂直的并且包裝圖例的總和超過(guò)了指定的高度max_height宦棺,它將被重新排列為多列布局。在以下示例中黔帕,最大高度為10cm代咸。

當(dāng)所有圖例放入多列時(shí),column_gap控制兩列之間的空間成黄。

pd = packLegend(lgd1, lgd3, lgd2, lgd3, lgd2, lgd1, max_height = unit(10, "cm"), 
    column_gap = unit(1, "cm"))
image

類似于水平包裝:

lgd1 = Legend(at = 1:6, legend_gp = gpar(fill = 1:6), title = "legend1",
    nr = 1)
lgd2 = Legend(col_fun = col_fun, title = "legend2", at = c(0, 0.25, 0.5, 0.75, 1),
    direction = "horizontal")

pd = packLegend(lgd1, lgd2, lgd3, lgd1, lgd2, lgd3, max_width = unit(10, "cm"), 
    direction = "horizontal", column_gap = unit(5, "mm"), row_gap = unit(1, "cm"))
image

打包的圖例pd也是一個(gè)Legends對(duì)象呐芥,這意味著您可以通過(guò)指定位置來(lái)繪制draw()它。

pd = packLegend(lgd1, lgd2, lgd3, direction = "horizontal")
pushViewport(viewport(width = 0.8, height = 0.8))
grid.rect()
draw(pd, x = unit(1, "cm"), y = unit(1, "cm"), just = c("left", "bottom"))
draw(pd, x = unit(1, "npc"), y = unit(1, "npc"), just = c("right", "top"))
popViewport()
image

再次重申奋岁,packLegend()在內(nèi)部用于管理熱圖和注釋圖例列表思瘟。

5.4 熱圖和注釋圖例

熱圖圖例的設(shè)置由Heatmap()中的heatmap_legend_param參數(shù)控制。Legend()的值是支持的參數(shù)列表heatmap_legend_param闻伶。

m = matrix(rnorm(100), 10)
Heatmap(m, name = "mat", heatmap_legend_param = list(
    at = c(-2, 0, 2),
    labels = c("low", "zero", "high"),
    title = "Some values",
    legend_height = unit(4, "cm"),
    title_position = "lefttop-rot"
))
image

annotation_legend_param控制注釋的圖例滨攻。由于一個(gè) HeatmapAnnotation可能包含多個(gè)注釋,因此annotation_legend_param的值是每個(gè)注釋的配置列表蓝翰。

ha = HeatmapAnnotation(foo = runif(10), bar = sample(c("f", "m"), 10, replace = TRUE),
    annotation_legend_param = list(
        foo = list(
                title = "Fooooooh",
                at = c(0, 0.5, 1),
                labels = c("zero", "median", "one")
            ),
        bar = list(
                title = "Baaaaaaar",
                at = c("f", "m"),
                labels = c("Female", "Male")
            )
))
Heatmap(m, name = "mat", top_annotation = ha)
image

如果熱圖是水平連接的光绕,則所有熱圖和行注釋圖例都被分組,所有列注釋圖例都被分組畜份。我們假設(shè)水平方向作為主要信息奇钞,而垂直方向提供次要信息。

ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
Heatmap(m, name = "mat1", top_annotation = ha1) +
rowAnnotation(sth = runif(10)) +
Heatmap(m, name = "mat2", top_annotation = ha2)
image

類似地漂坏,如果熱圖垂直連接,則所有熱圖的列注釋都被分組,所有行注釋的圖例也被分組顶别。

ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE), 
    annotation_name_side = "left")
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
Heatmap(m, name = "mat1", top_annotation = ha1) %v%
Heatmap(m, name = "mat2", top_annotation = ha2, 
    right_annotation = rowAnnotation(sth = 1:10))
image

show_legendHeatmapAnnotation()中 和show_heatmap_legendHeatmap()中控制是否顯示圖例谷徙。注意:show_legend可以是單個(gè)邏輯值、邏輯向量或控制注釋子集的命名向量驯绎。

ha = HeatmapAnnotation(foo = runif(10), 
    bar = sample(c("f", "m"), 10, replace = TRUE),
    show_legend = c(TRUE, FALSE), # it can also be show_legend = c(bar = FALSE)
    annotation_name_side = "left")
Heatmap(m, name = "mat1", top_annotation = ha) +
Heatmap(m, name = "mat2", show_heatmap_legend = FALSE)
image

draw()中的merge_legend函數(shù)控制是否將所有圖例合并為一個(gè)組完慧。通常,當(dāng)注釋和熱圖很多時(shí)剩失,圖例的數(shù)量總是很大屈尼。在這種情況下,圖例會(huì)自動(dòng)排列成多列(或多行拴孤,如果它們放在熱圖的底部)以擺脫圖形頁(yè)面脾歧。如果熱圖有熱圖注釋,放置圖例的順序是:左注釋的圖例演熟,頂部注釋的圖例鞭执,熱圖的圖例,底部注釋的圖例和右注釋的圖例芒粹。

ha1 = HeatmapAnnotation(foo1 = runif(10), 
    bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = rowAnnotation(foo2 = runif(10), 
    bar2 = sample(letters[1:3], 10, replace = TRUE))
ha3 = rowAnnotation(foo3 = runif(10), 
    bar3 = sample(month.name[1:3], 10, replace = TRUE))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) + 
    Heatmap(m, name = "mat2", left_annotation = ha2) + 
    ha3
draw(ht_list, merge_legend = TRUE)
image

如果您希望熱圖圖例成為“純熱圖圖例”兄纺,您可以設(shè)置 legend_grouping = "original"強(qiáng)制將所有注釋圖例放在一起,無(wú)論它們是行注釋圖例還是列注釋圖例化漆。

draw(ht_list, legend_grouping = "original")
image

通過(guò)設(shè)置color_bar = "discrete"估脆,連續(xù)顏色映射可以具有離散圖例,均適用于熱圖圖例和注釋圖例座云。

Heatmap(m, name = "mat", heatmap_legend_param = list(color_bar = "discrete"),
    top_annotation = HeatmapAnnotation(foo = 1:10,
        annotation_legend_param = list(
            foo = list(color_bar = "discrete"))))
image

如果value是字符向量疙赠,無(wú)論是注釋還是熱圖的單行一列矩陣,圖例標(biāo)簽的默認(rèn)順序都是sort(unique(value))疙教,如果value 是因子棺聊,則圖例標(biāo)簽的順序是levels(value)。永遠(yuǎn)記住順序可以分別通過(guò)Heatmap()heatmap_legend_param()/ annotation_legend_param()/HeamtapAnnotation()函數(shù)中設(shè)置atlabels參數(shù)進(jìn)行微調(diào)贞谓。

chr = sample(letters[1:3], 10, replace = TRUE)
chr
##  [1] "a" "c" "b" "a" "c" "a" "a" "c" "c" "b"
fa1 = factor(chr)
fa2 = factor(chr, levels = c("c", "a", "b"))
Heatmap(m, top_annotation = HeatmapAnnotation(chr = chr, fa1 = fa1, fa2 = fa2, fa3 = fa2,
    annotation_legend_param = list(fa3 = list(at = c("b", "c", "a")))))
image

5.5 添加自定義圖例

自定義圖例(由Legend()構(gòu)造)可以通過(guò)heatmap_legend_list參數(shù)添加到熱圖圖例列表draw()中限佩,注釋的圖例可以通過(guò)annotation_legend_list參數(shù)添加到注釋圖例列表中 。

拓展知識(shí) 中有一個(gè)很好的添加自定義圖例的例子 裸弦,但這里我們展示一個(gè)簡(jiǎn)單的例子祟同。

如前所述,只有熱圖和簡(jiǎn)單的注釋才能在圖上生成圖例理疙。ComplexHeatmap提供了很多注釋函數(shù)晕城,但都不支持生成圖例。在以下代碼中窖贤,我們向熱圖中添加了點(diǎn)注釋砖顷、線注釋和摘要注釋贰锁。

ha1 = HeatmapAnnotation(pt = anno_points(1:10, gp = gpar(col = rep(2:3, each = 5)), 
    height = unit(2, "cm")), show_annotation_name = FALSE)
ha2 = HeatmapAnnotation(ln = anno_lines(cbind(1:10, 10:1), gp = gpar(col = 4:5, lty = 1:2),
    height = unit(2, "cm")), show_annotation_name = FALSE)
m = matrix(rnorm(100), 10)
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) + 
          Heatmap(m, name = "mat2", top_annotation = ha2) +
          Heatmap(m[, 1], name = "mat3", 
            top_annotation = HeatmapAnnotation(
                summary = anno_summary(gp = gpar(fill = 2:3))
          ), width = unit(1, "cm"))
draw(ht_list, ht_gap = unit(7, "mm"), row_km = 2)
image

接下來(lái),我們?yōu)辄c(diǎn)滤蝠、線和箱線圖構(gòu)建圖例豌熄。

lgd_list = list(
    Legend(labels = c("red", "green"), title = "pt", type = "points", pch = 16, 
        legend_gp = gpar(col = 2:3)),
    Legend(labels = c("darkblue", "lightblue"), title = "ln", type = "lines", 
        legend_gp = gpar(col = 4:5, lty = 1:2)),
    Legend(labels = c("group1", "group2"), title = "km", type = "boxplot",
        legend_gp = gpar(fill = 2:3))
)
draw(ht_list, ht_gap = unit(7, "mm"), row_km = 2, annotation_legend_list = lgd_list)
image

5.6 邊緣圖例

默認(rèn)情況下,熱圖圖例和注釋圖例放在圖的右側(cè)物咳。兩種類型圖例的熱圖相對(duì)的一側(cè)可以由函數(shù)draw()中的heatmap_legend_sideannotation_legend_side參數(shù)控制锣险。可以為兩個(gè)參數(shù)設(shè)置的值是 left览闰,right芯肤,bottomtop

m = matrix(rnorm(100), 10)
ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1) +
    rowAnnotation(sth = runif(10)) +
    Heatmap(m, name = "mat2", top_annotation = ha2)
draw(ht_list, heatmap_legend_side = "left", annotation_legend_side = "bottom")
image

當(dāng)圖例放在底部或頂部時(shí)压鉴,圖例水平排列崖咨。我們可能還需要設(shè)置每一個(gè)圖例的水平圖例,這需要通過(guò)設(shè)置Heatmap()HeatmapAnnotation() 函數(shù)中的heatmap_legend_paramannotation_legend_param參數(shù):

ha1 = HeatmapAnnotation(foo1 = runif(10), bar1 = sample(c("f", "m"), 10, replace = TRUE),
    annotation_legend_param = list(
        foo1 = list(direction = "horizontal"),
        bar1 = list(nrow = 1)))
ha2 = HeatmapAnnotation(foo2 = runif(10), bar2 = sample(c("f", "m"), 10, replace = TRUE),
    annotation_legend_param = list(
        foo2 = list(direction = "horizontal"),
        bar2 = list(nrow = 1)))
ht_list = Heatmap(m, name = "mat1", top_annotation = ha1, 
        heatmap_legend_param = list(direction = "horizontal")) +
    rowAnnotation(sth = runif(10), 
        annotation_legend_param = list(sth = list(direction = "horizontal"))) +
    Heatmap(m, name = "mat2", top_annotation = ha2,
        heatmap_legend_param = list(direction = "horizontal"))
draw(ht_list, merge_legend = TRUE, heatmap_legend_side = "bottom", 
    annotation_legend_side = "bottom")
image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晴弃,一起剝皮案震驚了整個(gè)濱河市掩幢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌上鞠,老刑警劉巖际邻,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芍阎,居然都是意外死亡世曾,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門谴咸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轮听,“玉大人,你說(shuō)我怎么就攤上這事岭佳⊙。” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵珊随,是天一觀的道長(zhǎng)述寡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)叶洞,這世上最難降的妖魔是什么鲫凶? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮衩辟,結(jié)果婚禮上螟炫,老公的妹妹穿的比我還像新娘。我一直安慰自己艺晴,他們只是感情好昼钻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布掸屡。 她就那樣靜靜地躺著,像睡著了一般然评。 火紅的嫁衣襯著肌膚如雪折晦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天沾瓦,我揣著相機(jī)與錄音,去河邊找鬼谦炒。 笑死贯莺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宁改。 我是一名探鬼主播缕探,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼还蹲!你這毒婦竟也來(lái)了爹耗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谜喊,失蹤者是張志新(化名)和其女友劉穎潭兽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斗遏,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡山卦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诵次。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片账蓉。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逾一,靈堂內(nèi)的尸體忽然破棺而出铸本,到底是詐尸還是另有隱情,我是刑警寧澤遵堵,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布箱玷,位于F島的核電站,受9級(jí)特大地震影響鄙早,放射性物質(zhì)發(fā)生泄漏汪茧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一限番、第九天 我趴在偏房一處隱蔽的房頂上張望舱污。 院中可真熱鬧,春花似錦弥虐、人聲如沸扩灯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)珠插。三九已至惧磺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捻撑,已是汗流浹背磨隘。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顾患,地道東北人番捂。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像江解,于是被迫代替她去往敵國(guó)和親设预。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355