第 3 章 熱圖注釋
熱圖注釋是熱圖的重要組成部分惕医,它顯示與熱圖中的行或列相關(guān)聯(lián)的附加信息泞坦。 ComplexHeatmap包為設(shè)置注釋和定義新的注釋圖形提供了非常靈活的支持。注釋可以放在熱圖的四個側(cè)面,由top_annotation
鲫构,bottom_annotation
, left_annotation
和right_annotation
參數(shù)組成玫坛。
接下來我們將對不同第注釋函數(shù)anno_*()
進(jìn)行說明结笨,如空注釋anno_empty()
、塊注釋anno_block()
湿镀、圖像注釋anno_image()
炕吸、點注釋anno_points()
、線注釋anno_lines()
勉痴、條形圖注釋anno_barplot()
赫模、箱線圖注釋anno_boxplot()
、直方圖注釋anno_histogram()
蒸矛、密度注釋anno_density()
等注釋方法瀑罗。
四個參數(shù)的值應(yīng)該在HeatmapAnnotation
類中并且由HeatmapAnnotation()
函數(shù)構(gòu)造,如果是行注釋則由rowAnnotation()
函數(shù)構(gòu)造雏掠。(rowAnnotation()
只是一個與HeatmapAnnotation(..., which = "row")
相同的輔助函數(shù)) 斩祭,熱圖注釋的簡單用法如下。
set.seed(123)
mat = matrix(rnorm(100), 10)
rownames(mat) = paste0("R", 1:10)
colnames(mat) = paste0("C", 1:10)
column_ha = HeatmapAnnotation(foo1 = runif(10), bar1 = anno_barplot(runif(10)))
row_ha = rowAnnotation(foo2 = runif(10), bar2 = anno_barplot(runif(10)))
Heatmap(mat, name = "mat", top_annotation = column_ha, right_annotation = row_ha)
將熱圖注釋指定為底部注釋和左側(cè)注釋乡话。
Heatmap(mat, name = "mat", bottom_annotation = column_ha, left_annotation = row_ha)
在上面的例子中停忿,column_ha
和row_ha
都有兩個注釋,其中 foo1
和foo2
是數(shù)字向量蚊伞,bar1
和bar2
是條形圖。類似向量的注解在這里稱為“簡單注釋”吮铭,條形圖注解稱為“復(fù)雜注釋”时迫。您已經(jīng)可以看到注釋必須定義為名稱=值對(例如 foo = ...
)。
熱圖注釋也可以獨立于熱圖谓晌。它們可以通過+
(水平連接)或%v%
(垂直連接)到熱圖列表掠拳。
# code only for demonstration
Heatmap(...) + rowAnnotation() + ...
Heatmap(...) %v% HeatmapAnnotation(...) + ...
HeatmapAnnotation()
返回一個HeatmapAnnotation
類對象。對象通常由幾個注釋組成纸肉。如以下部分溺欧,首先介紹單個注釋的設(shè)置,然后展示如何將它們組合在一起柏肪。
可以看到column_ha
和row_ha
對象的信息:
column_ha
## A HeatmapAnnotation object with 2 annotations
## name: heatmap_annotation_0
## position: column
## items: 10
## width: 1npc
## height: 15.3514598035146mm
## this object is subsetable
## 5.92288888888889mm extension on the left
## 9.4709mm extension on the right
##
## name annotation_type color_mapping height
## foo1 continuous vector random 5mm
## bar1 anno_barplot() 10mm
row_ha
## A HeatmapAnnotation object with 2 annotations
## name: heatmap_annotation_1
## position: row
## items: 10
## width: 15.3514598035146mm
## height: 1npc
## this object is subsetable
## 9.96242222222222mm extension on the bottom
##
## name annotation_type color_mapping width
## foo2 continuous vector random 5mm
## bar2 anno_barplot() 10mm
在本章的以下示例中姐刁,除非必要,否則我們將僅顯示沒有熱圖的注釋圖形烦味。如果你想用一個熱圖來試試吧聂使,你只需指定HeatmapAnnotation
,我們是以ha
名稱來作為top_annotation
,bottom_annotation
柏靶,left_annotation
或 right_annotation
討論對象弃理。
列注釋和行注釋的設(shè)置基本相同。如果沒有什么特別的屎蜓,我們只以列注釋作為示例痘昌。如果您想嘗試一行注釋,只需添加which = "row"
到 HeatmapAnnotation()
或直接切換到rowAnnotation()
功能炬转。
3.1簡單注釋
所謂的“簡單注釋”是最常用的注釋樣式辆苔,它是類似熱圖或類似網(wǎng)格的圖形,其中使用顏色映射到注釋值返吻。要生成一個簡單的注釋姑子,您只需簡單地將一個特定的名稱注釋向量放入HeatmapAnnotation()
中。
ha = HeatmapAnnotation(foo = 1:10)
離散型數(shù)據(jù)注釋:
ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE))
除了HeatmapAnnotation()
测僵,您可以使用任何字符串作為注釋名稱街佑。
如果未指定顏色,則隨機生成顏色捍靠。col
設(shè)置注釋的顏色沐旨,col
需要設(shè)置命名列表。
對于連續(xù)值注釋榨婆,顏色映射應(yīng)該是由 circlize::colorRamp2()
生成的顏色映射函數(shù)磁携。
library(circlize)
col_fun = colorRamp2(c(0, 5, 10), c("blue", "white", "red"))
ha = HeatmapAnnotation(foo = 1:10, col = list(foo = col_fun))
對于離散注釋,顏色應(yīng)該是命名向量良风,其中名稱對應(yīng)于注釋中的級別谊迄。
ha = HeatmapAnnotation(bar = sample(letters[1:3], 10, replace = TRUE),
col = list(bar = c("a" = "red", "b" = "green", "c" = "blue")))
如果您指定多個向量,則會有多個注釋(foo
和bar
)烟央。您還可以看到foo
和bar
全部放入單個HeatmapAnnotation()
中是如何設(shè)置col
. 也許現(xiàn)在您可以理解顏色列表中的名稱實際上是用來映射到注釋名稱的统诺。col
中的值將用于構(gòu)建簡單注釋的圖例。
ha = HeatmapAnnotation(
foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
NA
值的顏色由na_col
參數(shù)控制疑俭。
ha = HeatmapAnnotation(
foo = c(1:4, NA, 6:10),
bar = c(NA, sample(letters[1:3], 9, replace = TRUE)),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
na_col = "black"
)
gp
主要控制網(wǎng)格邊界的圖形參數(shù)粮呢。
ha = HeatmapAnnotation(
foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
gp = gpar(col = "black")
)
簡單注釋也可以是矩陣(數(shù)字或字符),矩陣中的所有列共享相同的顏色映射模式钞艇。注意矩陣中的列對應(yīng)于列注釋中的行啄寡。矩陣的列名稱也用作注釋名稱。
ha = HeatmapAnnotation(foo = cbind(a = runif(10), b = runif(10)))
如果矩陣沒有列名哩照,則仍然使用注解的名稱挺物,但繪制在注解的中間。
ha = HeatmapAnnotation(foo = cbind(runif(10), runif(10)))
由于簡單的注釋可以采用不同的模式(例如數(shù)字或字符)葡秒,它們可以組合為數(shù)據(jù)幀并發(fā)送到df
參數(shù)姻乓。在你的項目中成像嵌溢,你可能已經(jīng)有了一個注釋表,你可以直接通過 df
.
anno_df = data.frame(foo = 1:10,
bar = sample(letters[1:3], 10, replace = TRUE))
ha = HeatmapAnnotation(df = anno_df,
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
單個注釋和數(shù)據(jù)框可以混合使用蹋岩。在以下示例中赖草,foo2
由于未指定顏色,將使用隨機顏色剪个。
ha = HeatmapAnnotation(df = anno_df,
foo2 = rnorm(10),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
)
)
border
控制每個注釋的邊界秧骑。
ha = HeatmapAnnotation(
foo = cbind(1:10, 10:1),
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
border = TRUE
)
簡單注釋的高度由simple_anno_size
參數(shù)控制。由于所有單個注釋具有相同的高度扣囊,因此 的值 simple_anno_size
是單個unit
值乎折。注意有喜歡爭論 width
,height
侵歇,annotation_width
和annotation_height
骂澄,但它們是用來調(diào)整的完整heamtap注釋(這總是混合幾種注釋)的寬度/高度。
ha = HeatmapAnnotation(
foo = cbind(a = 1:10, b = 10:1),
bar = sample(letters[1:3], 10, replace = TRUE),
col = list(foo = col_fun,
bar = c("a" = "red", "b" = "green", "c" = "blue")
),
simple_anno_size = unit(1, "cm")
)
當(dāng)您有多個熱圖時惕虑,最好將所有熱圖上的簡單注釋的大小保持相同的大小坟冲。ht_opt$simple_anno_size
可以設(shè)置全局控制簡單注解的大小。
3.2簡單注釋作為注釋函數(shù)
HeatmapAnnotation()
通過將注釋設(shè)置為函數(shù)來支持“復(fù)雜注釋”溃蔫。annotation 函數(shù)定義了如何在熱圖中的列或行對應(yīng)的某個位置繪制圖形健提。ComplexHeatmap包中預(yù)定義了很多注釋函數(shù) 。在本章的最后伟叛,我們將介紹如何通過AnnotationFunction
類構(gòu)造自己的注釋函數(shù)私痹。
對于anno_*()
形式的所有注釋函數(shù),如果在HeatmapAnnotation()
或rowAnnotation()
中指定 统刮,則不需要明確地做任何anno_*()
事情來判斷它是應(yīng)該繪制在行上還是列上紊遵。anno_*()
將會自動檢測是行注釋環(huán)境還是列注釋環(huán)境。
上一節(jié)中的簡單注解是由anno_simple()
注解函數(shù)內(nèi)部構(gòu)造的 侥蒙。直接使用anno_simple()
不會自動為最終繪圖生成圖例癞蚕,但是,它可以為更多的注釋圖形提供更大的靈活性(注意在第5章 我們將展示辉哥,雖然anno_simple()
不能自動生成圖例,但可以控制圖例并添加到最終繪圖中手動)攒射。
對于上一節(jié)中的示例:
# code only for demonstration
ha = HeatmapAnnotation(foo = 1:10)
實際上等同于:
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_simple(1:10))
anno_simple()
制作類似熱圖的注釋(或簡單的注釋)醋旦。基本上如果用戶只做類似熱圖的注釋会放,他們不需要直接使用anno_simple()
饲齐,但是這個功能允許在注釋網(wǎng)格上添加更多符號。
anno_simple()
允許在注釋網(wǎng)格頂部添加“點”或單字母符號咧最。pch
捂人,pt_gp
和pt_size
控制點的設(shè)置御雕。pch
的值可以是具有可能NA
值的向量。
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1,
pt_gp = gpar(col = "red"), pt_size = unit(1:10, "mm")))
設(shè)置pch
為向量:
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = 1:10))
設(shè)置pch
為字母向量:
ha = HeatmapAnnotation(foo = anno_simple(1:10,
pch = sample(letters[1:3], 10, replace = TRUE)))
設(shè)置pch
為帶有NA
值的向量(pch 值為NA
不繪制任何內(nèi)容):
ha = HeatmapAnnotation(foo = anno_simple(1:10, pch = c(1:4, NA, 6:8, NA, 10, 11)))
如果 anno_simple()
的值是矩陣滥搭,pch
也可以使用酸纲。 pch
的長度應(yīng)該與矩陣的行數(shù)或列數(shù)甚至矩陣的長度相同(矩陣的長度是矩陣中所有數(shù)據(jù)點的長度)。
pch
的長度對應(yīng)矩陣的列:
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:2))
pch
對應(yīng)于矩陣行的長度:
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = 1:10))
pch
是一個矩陣:
pch = matrix(1:20, nc = 2)
pch[sample(length(pch), 10)] = NA
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1), pch = pch))
到現(xiàn)在為止瑟匆,您可能想知道如何設(shè)置已添加到簡單注釋中的符號的圖例闽坡。在這里,我們將僅向您展示一個簡單的示例愁溜,在下面的例子中疾嗅,我們假設(shè)簡單的注釋是一種 p 值,我們將 p 值小于 0.01 的添加*
冕象。
set.seed(123)
pvalue = 10^-runif(10, min = 0, max = 3)
is_sig = pvalue < 0.01
pch = rep("*", 10)
pch[!is_sig] = NA
# color mapping for -log10(pvalue)
pvalue_col_fun = colorRamp2(c(0, 2, 3), c("green", "white", "red"))
ha = HeatmapAnnotation(
pvalue = anno_simple(-log10(pvalue), col = pvalue_col_fun, pch = pch),
annotation_name_side = "left")
ht = Heatmap(matrix(rnorm(100), 10), name = "mat", top_annotation = ha)
# now we generate two legends, one for the p-value
# see how we define the legend for pvalue
lgd_pvalue = Legend(title = "p-value", col_fun = pvalue_col_fun, at = c(0, 1, 2, 3),
labels = c("1", "0.1", "0.01", "0.001"))
# and one for the significant p-values
lgd_sig = Legend(pch = "*", type = "points", labels = "< 0.01")
# these two self-defined legends are added to the plot by `annotation_legend_list`
draw(ht, annotation_legend_list = list(lgd_pvalue, lgd_sig))
anno_simple()
的高度可以通過height
參數(shù)或 simple_anno_size
內(nèi)部控制代承。simple_anno_size
控制單行注釋的大小和height
/width
控制簡單注釋的總高度/寬度。如果設(shè)置了height
/ width
渐扮, simple_anno_size
則被忽略论悴。
ha = HeatmapAnnotation(foo = anno_simple(1:10, height = unit(2, "cm")))
ha = HeatmapAnnotation(foo = anno_simple(cbind(1:10, 10:1),
simple_anno_size = unit(2, "cm")))
對于我們后面介紹的所有注釋函數(shù),單個注釋的高度或?qū)挾榷紤?yīng)該在anno_*()
函數(shù)內(nèi)部進(jìn)行設(shè)置席爽。
# code only for demonstration
anno_*(..., width = ...)
anno_*(..., height = ...)
同樣意荤,width
,height
只锻,annotation_width
和annotation_height
在參數(shù)HeatmapAnnotation()
被用于調(diào)整多個注釋的大小玖像。
3.3 空注釋
anno_empty()
是一個不繪制任何內(nèi)容的占位符。以后可以通過decorate_annotation()
功能添加用戶定義的圖形齐饮。
ha = HeatmapAnnotation(foo = anno_empty(border = TRUE))
在后續(xù)章節(jié)中將介紹裝飾函數(shù)的使用捐寥,但在這里我們舉一個簡單的例子。在基因表達(dá)表達(dá)分析中,有些情況下我們將熱圖分成幾組印衔,我們希望突出顯示每組中的一些關(guān)鍵基因梭纹。在這種情況下,我們只需將基因名稱添加到熱圖的右側(cè)乡洼,而不將它們與相應(yīng)的行對齊。(anno_mark()
可以將標(biāo)簽正確地與其對應(yīng)的行對齊匕坯,但在在這里顯示的示例中束昵,這不是必需的)。
在以下示例中葛峻,由于行被拆分為四個切片锹雏,因此空注釋也被拆分為四個切片∈踅保基本上我們所做的是在每個空的注釋切片中礁遵,我們添加一個彩色段和文本轻绞。
random_text = function(n) {
sapply(1:n, function(i) {
paste0(sample(letters, sample(4:10, 1)), collapse = "")
})
}
text_list = list(
text1 = random_text(4),
text2 = random_text(4),
text3 = random_text(4),
text4 = random_text(4)
)
# note how we set the width of this empty annotation
ha = rowAnnotation(foo = anno_empty(border = FALSE,
width = max_text_width(unlist(text_list)) + unit(4, "mm")))
Heatmap(matrix(rnorm(1000), nrow = 100), name = "mat", row_km = 4, right_annotation = ha)
for(i in 1:4) {
decorate_annotation("foo", slice = i, {
grid.rect(x = 0, width = unit(2, "mm"), gp = gpar(fill = i, col = NA), just = "left")
grid.text(paste(text_list[[i]], collapse = "\n"), x = unit(4, "mm"), just = "left")
})
}
空注釋的第二個用途是添加復(fù)雜的注釋圖形,其中空注釋偽裝成虛擬繪圖區(qū)域佣耐≌可以AnnotationFunction
為復(fù)雜的注釋圖形按類構(gòu)造注釋函數(shù),允許子集和拆分晰赞,但仍然可以作為次要選擇稼病,直接在空注釋內(nèi)部繪制,實現(xiàn)起來更容易掖鱼、更快(但靈活性較差然走,不允許拆分)。
下面我們將展示如何添加點注釋的“復(fù)雜版本”戏挡。唯一需要注意的是x軸(y軸如果是行注釋)上的位置應(yīng)該對應(yīng)列重新排序后的列索引芍瑞。
ha = HeatmapAnnotation(foo = anno_empty(border = TRUE, height = unit(3, "cm")))
ht = Heatmap(matrix(rnorm(100), nrow = 10), name = "mat", top_annotation = ha)
ht = draw(ht)
co = column_order(ht)
value = runif(10)
decorate_annotation("foo", {
# value on x-axis is always 1:ncol(mat)
x = 1:10
# while values on y-axis is the value after column reordering
value = value[co]
pushViewport(viewport(xscale = c(0.5, 10.5), yscale = c(0, 1)))
grid.lines(c(0.5, 10.5), c(0.5, 0.5), gp = gpar(lty = 2),
default.units = "native")
grid.points(x, value, pch = 16, size = unit(2, "mm"),
gp = gpar(col = ifelse(value > 0.5, "red", "blue")), default.units = "native")
grid.yaxis(at = c(0, 0.5, 1))
popViewport()
})
3.4塊注釋
塊注釋更像是一個顏色塊,它在熱圖的行或列被拆分時標(biāo)識組褐墅。
Heatmap(matrix(rnorm(100), 10), name = "mat",
top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4))),
column_km = 3)
標(biāo)簽可以添加到每個塊拆檬。
Heatmap(matrix(rnorm(100), 10),
top_annotation = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
labels = c("group1", "group2", "group3"),
labels_gp = gpar(col = "white", fontsize = 10))),
column_km = 3,
left_annotation = rowAnnotation(foo = anno_block(gp = gpar(fill = 2:4),
labels = c("group1", "group2", "group3"),
labels_gp = gpar(col = "white", fontsize = 10))),
row_km = 3)
請注意,labels
或圖形參數(shù)的長度應(yīng)與切片數(shù)具有相同的長度妥凳。
anno_block()
函數(shù)為行/列切片繪制矩形竟贯,其中一個矩形僅對應(yīng)一個切片。那么逝钥,如果我們想在多個切片上繪制矩形以顯示它們屬于某些組屑那,該怎么辦,如下面的熱圖所示艘款?
set.seed(123)
mat2 = matrix(rnorm(50*50), nrow = 50)
ha = HeatmapAnnotation(foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5]))
split = rep(1:5, each = 10)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
目前持际,很難在anno_block()
中直接支持它,但仍然有解決方法哗咆。實際上蜘欲,要在多個切片上繪制矩形,我們需要知道兩件事:1. 切片在圖中的位置 2. 繪制矩形的空間晌柬。慶幸的是位置可以通過直接轉(zhuǎn)到對應(yīng)的視窗獲得姥份,并且可以通過anno_empty()
函數(shù)分配空間。
在下面的代碼中年碘,我們使用anno_empty()
創(chuàng)建一個空注釋:
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
假設(shè)我們要將前三列切片作為一組殿衰,將后兩列切片作為第二組。
用于注釋的第一和第三切片的位置"empty"
可以通過以下方式獲得:
seekViewport("annotation_empty_1")
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport("annotation_empty_3")
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
loc2
## $x
## [1] 4.07403126835173inches
##
## $y
## [1] 6.51051067246731inches
視圖窗口名稱"annotation_empty_1"
對應(yīng)于注釋的第一個切片empty
盛泡,我們?nèi)〉谝粋€“空”注釋切片的左下角和第三個切片的右上角,保存在loc1
和 loc2
變量中娱颊。
這里重要的是grid::deviceLoc()
函數(shù)的使用傲诵。它直接將在某個視口中測量的位置轉(zhuǎn)換為圖形設(shè)備中的位置凯砍。
最后,我們?nèi)?code>"global"視口拴竹,因為"global"
視口的大小是圖形設(shè)備的大小悟衩,繪制矩形并添加標(biāo)簽。
seekViewport("global")
grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y,
just = c("left", "bottom"), gp = gpar(fill = "red"))
grid.text("group 1", x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5)
注釋的視圖窗口名稱采用固定格式栓拜,即 annotation_{annotation_name}_{slice_index}
. 可以通過list_components()
函數(shù)獲取完整的視口名稱集座泳。
list_components()
## [1] "ROOT" "global"
## [3] "global_layout" "global-heatmaplist"
## [5] "main_heatmap_list" "heatmap_mat2"
## [7] "mat2_heatmap_body_wrap" "mat2_heatmap_body_1_1"
## [9] "mat2_heatmap_body_1_2" "mat2_heatmap_body_1_3"
## [11] "mat2_heatmap_body_1_4" "mat2_heatmap_body_1_5"
## [13] "mat2_dend_row_1" "mat2_dend_column_1"
## [15] "mat2_dend_column_2" "mat2_dend_column_3"
## [17] "mat2_dend_column_4" "mat2_dend_column_5"
## [19] "annotation_empty_1" "annotation_foo_1"
## [21] "annotation_empty_2" "annotation_foo_2"
## [23] "annotation_empty_3" "annotation_foo_3"
## [25] "annotation_empty_4" "annotation_foo_4"
## [27] "annotation_empty_5" "annotation_foo_5"
## [29] "global-heatmap_legend_right" "heatmap_legend"
如果要添加多個組級矩形,我們可以將代碼包裝成一個簡單的函數(shù)group_block_anno()
:
ha = HeatmapAnnotation(
empty = anno_empty(border = FALSE, height = unit(8, "mm")),
foo = anno_block(gp = gpar(fill = 2:6), labels = LETTERS[1:5])
)
Heatmap(mat2, name = "mat2", column_split = split, top_annotation = ha,
column_title = NULL)
library(GetoptLong) # for the function qq()
group_block_anno = function(group, empty_anno, gp = gpar(),
label = NULL, label_gp = gpar()) {
seekViewport(qq("annotation_@{empty_anno}_@{min(group)}"))
loc1 = deviceLoc(x = unit(0, "npc"), y = unit(0, "npc"))
seekViewport(qq("annotation_@{empty_anno}_@{max(group)}"))
loc2 = deviceLoc(x = unit(1, "npc"), y = unit(1, "npc"))
seekViewport("global")
grid.rect(loc1$x, loc1$y, width = loc2$x - loc1$x, height = loc2$y - loc1$y,
just = c("left", "bottom"), gp = gp)
if(!is.null(label)) {
grid.text(label, x = (loc1$x + loc2$x)*0.5, y = (loc1$y + loc2$y)*0.5, gp = label_gp)
}
}
group_block_anno(1:3, "empty", gp = gpar(fill = "red"), label = "group 1")
group_block_anno(4:5, "empty", gp = gpar(fill = "blue"), label = "group 2")
當(dāng)熱圖被分割時幕与,塊注釋中的每個塊都可以被認(rèn)為是一個虛擬的繪圖區(qū)域挑势。anno_block()
允許一個新參數(shù)graphics
,該參數(shù)接受在每個切片中繪制圖形的自定義函數(shù)啦鸣。它必須有兩個參數(shù):
- 當(dāng)前切片的行/列索引(我們稱之為
index
)潮饱, - 來自 split 變量的與當(dāng)前切片相對應(yīng)的水平向量(我們稱之為
level
)。當(dāng) e.grow_km
僅設(shè)置或row_split
僅設(shè)置為一個分類變量時诫给,則level
是長度為 1 的向量香拉。如果有多個分類變量用row_km
和設(shè)置row_split
,level
則是一個長度與分類變量個數(shù)相同的向量中狂。
設(shè)置圖形時凫碌,將忽略 anno_block 中的所有其他圖形參數(shù)。請參閱以下示例:
col = c("1" = "red", "2" = "blue", "A" = "green", "B" = "orange")
Heatmap(matrix(rnorm(100), 10), row_km = 2, row_split = sample(c("A", "B"), 10, replace = TRUE)) +
rowAnnotation(foo = anno_block(
graphics = function(index, levels) {
grid.rect(gp = gpar(fill = col[levels[2]], col = "black"))
txt = paste(levels, collapse = ",")
txt = paste0(txt, "\n", length(index), " rows")
grid.text(txt, 0.5, 0.5, rot = 0,
gp = gpar(col = col[levels[1]]))
},
width = unit(3, "cm")
))
3.5圖像標(biāo)注
圖像可以作為注釋胃榕。anno_image()
支持png
, svg
, pdf
, eps
, jpeg/jpg
,tiff
格式的圖像盛险。它們作為注釋導(dǎo)入的方式如下:
-
png
、jpeg/jpg
和tiff
圖像由png::readPNG()
勤晚、jpeg::readJPEG()
和tiff::readTIFF()
導(dǎo)入并由grid::grid.raster()
繪制枉层。 -
svg
圖像首先由rsvg::rsvg_svg()重新格式化
,然后由grImport2::readPicture()
導(dǎo)入和grImport2::grid.picture()
繪制赐写。 -
pdf
和eps
圖像由grImport::PostScriptTrace()
和grImport::readPicture()
導(dǎo)入鸟蜡,然后由grImport::grid.picture()
繪制。
以下示例的免費圖標(biāo)來自 https://github.com/Keyamoon/IcoMoon-Free挺邀。圖像路徑向量被設(shè)置為 的第一個參數(shù)anno_image()
揉忘。
image_png = sample(dir("IcoMoon-Free-master/PNG/64px", full.names = TRUE), 10)
image_svg = sample(dir("IcoMoon-Free-master/SVG/", full.names = TRUE), 10)
image_eps = sample(dir("IcoMoon-Free-master/EPS/", full.names = TRUE), 10)
image_pdf = sample(dir("IcoMoon-Free-master/PDF/", full.names = TRUE), 10)
# we only draw the image annotation for PNG images, while the others are the same
ha = HeatmapAnnotation(foo = anno_image(image_png))
不同格式的圖像可以在輸入向量中混合使用。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_image(c(image_png[1:3], image_svg[1:3],
image_eps[1:3], image_pdf[1:3])))
邊框和背景顏色(如果圖像具有透明背景)可以通過gp
設(shè)置端铛。
ha = HeatmapAnnotation(foo = anno_image(image_png,
gp = gpar(fill = 1:10, col = "black")))
border
控制整個邊界的注釋泣矛。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_image(image_png, border = "red"))
圖像周圍的填充或空間由 space
設(shè)置。
ha = HeatmapAnnotation(foo = anno_image(image_png, space = unit(3, "mm")))
如果只需要繪制部分圖像禾蚕,可以將image
向量中的其它元素設(shè)置為''
或NA
您朽。
image_png[1:2] = ""
ha = HeatmapAnnotation(foo = anno_image(image_png))
3.6 點注釋
點注釋anno_points()
為實現(xiàn)顯示數(shù)據(jù)點在列表中的分布。數(shù)據(jù)點對象x
可以是單個向量或矩陣换淆。如果它是一個矩陣哗总,圖形屬性設(shè)置(例如pch
几颜,size
和gp
)可以關(guān)聯(lián)到矩陣的列。再次注意讯屈,如果x
是矩陣蛋哭,則行x
對應(yīng)于熱圖矩陣中的列。
ha = HeatmapAnnotation(foo = anno_points(runif(10)))
ha = HeatmapAnnotation(foo = anno_points(matrix(runif(20), nc = 2),
pch = 1:2, gp = gpar(col = 2:3)))
ylim
控制“y軸”或“數(shù)據(jù)軸”上的范圍(如果是行注釋涮母,則數(shù)據(jù)軸為水平)谆趾,extend
控制數(shù)據(jù)軸方向上的擴展空間。axis
控制是否顯示軸并控制軸 axis_param
的設(shè)置叛本。軸的默認(rèn)設(shè)置為:
default_axis_param("column")
## $at
## NULL
##
## $labels
## NULL
##
## $labels_rot
## [1] 0
##
## $gp
## $fontsize
## [1] 8
##
##
## $side
## [1] "left"
##
## $facing
## [1] "outside"
##
## $direction
## [1] "normal"
你可以覆蓋其中的一些:
ha = HeatmapAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
axis_param = list(
side = "right",
at = c(0, 0.5, 1),
labels = c("zero", "half", "one")
))
)
控制軸標(biāo)簽的旋轉(zhuǎn)可能對你有用沪蓬。
ha = rowAnnotation(foo = anno_points(runif(10), ylim = c(0, 1),
width = unit(2, "cm"),
axis_param = list(
side = "bottom",
at = c(0, 0.5, 1),
labels = c("zero", "half", "one"),
labels_rot = 45
))
)
軸的配置與其他具有軸的注釋功能相同。
點注釋的默認(rèn)大小為 5mm炮赦。它可以由height
/width
中的參數(shù)控制 anno_points()
怜跑。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_points(runif(10), height = unit(2, "cm")))
3.7 線注釋
anno_lines()
通過段列表連接數(shù)據(jù)點。與 anno_points()
類似吠勘,數(shù)據(jù)變量可以是數(shù)值向量:
ha = HeatmapAnnotation(foo = anno_lines(runif(10)))
或矩陣:
ha = HeatmapAnnotation(foo = anno_lines(cbind(c(1:5, 1:5), c(5:1, 5:1)),
gp = gpar(col = 2:3), add_points = TRUE, pt_gp = gpar(col = 5:6), pch = c(1, 16)))
如上所示性芬,可以通過設(shè)置將點添加到線中add_points = TRUE
。
通過設(shè)置smooth = TRUE
可以添加平滑線(by loess()
)而不是原始線剧防,但應(yīng)謹(jǐn)慎使用植锉,因為熱圖中列的順序用作擬合的“x值”,并且僅當(dāng)您認(rèn)為擬合反對重新排序的順序是有道理的峭拘。
當(dāng)輸入數(shù)據(jù)變量是對每一列單獨執(zhí)行平滑的矩陣時俊庇,平滑也有效。
如果smooth
是TRUE
鸡挠,add_points
則默認(rèn)設(shè)置為TRUE
辉饱。
ha = HeatmapAnnotation(foo = anno_lines(runif(10), smooth = TRUE))
線注釋的默認(rèn)大小為 5 毫米。它可以由height
/ 中的width
參數(shù)控制 anno_lines()
拣展。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_lines(runif(10), height = unit(2, "cm")))
3.8條形圖標(biāo)注
數(shù)據(jù)點可以表示為條形圖彭沼。 anno_barplot()
的一些參數(shù):如ylim
,axis
备埃,axis_param
和 anno_points()
是一樣的姓惑。
ha = HeatmapAnnotation(foo = anno_barplot(1:10))
條行圖的寬度由 bar_width
控制。它是熱圖中單元格寬度的相對值按脚。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, bar_width = 1))
圖形參數(shù)由gp
控制于毙。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, gp = gpar(fill = 1:10)))
您可以通過baseline
選擇條形的基線。
ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = "min"))
ha = HeatmapAnnotation(foo = anno_barplot(seq(-5, 5), baseline = 0))
如果輸入值是一個矩陣辅搬,它將是堆疊的條形圖唯沮。
ha = HeatmapAnnotation(foo = anno_barplot(matrix(nc = 2, c(1:10, 10:1))))
gp
參數(shù)的長度可以是矩陣中的列數(shù):
ha = HeatmapAnnotation(foo = anno_barplot(cbind(1:10, 10:1),
gp = gpar(fill = 2:3, col = 2:3)))
條形圖注釋的默認(rèn)大小為 5 毫米。它可以由height
/width
中的參數(shù)控制 anno_barplot()
。
# code only for demonstration
ha = HeatmapAnnotation(foo = anno_barplot(runif(10), height = unit(2, "cm")))
以下示例顯示了可視化比例矩陣的條形圖注釋(行總和為 1)介蛉。
m = matrix(runif(4*10), nc = 4)
m = t(apply(m, 1, function(x) x/sum(x)))
ha = HeatmapAnnotation(foo = anno_barplot(m, gp = gpar(fill = 2:5),
bar_width = 1, height = unit(6, "cm")))
軸的方向可以反轉(zhuǎn)夯缺,這在注釋放在熱圖左側(cè)時很有用。
ha_list = rowAnnotation(axis_reverse = anno_barplot(m, gp = gpar(fill = 2:5),
axis_param = list(direction = "reverse"),
bar_width = 1, width = unit(4, "cm"))) +
rowAnnotation(axis_normal = anno_barplot(m, gp = gpar(fill = 2:5),
bar_width = 1, width = unit(4, "cm")))
draw(ha_list, ht_gap = unit(4, "mm"))
direction = "reverse"
也適用于其他具有軸的注釋函數(shù)甘耿,但它常用于條形圖注釋。
add_numbers
可以將參數(shù)設(shè)置為TRUE
竿滨,以便在條形頂部繪制與條形關(guān)聯(lián)的數(shù)字佳恬。對于列注釋,文本默認(rèn)旋轉(zhuǎn) 45 度于游。
ha = HeatmapAnnotation(foo = anno_barplot(1:10, add_numbers = TRUE,
height = unit(1, "cm")))
3.9箱線圖注釋
Boxplot注解以及后面介紹的注解函數(shù)更適合小矩陣毁葱。不適合就有多列矩陣的列注釋。
對于anno_boxplot()
贰剥,輸入數(shù)據(jù)變量應(yīng)該是矩陣或列表倾剿。如果 x
是矩陣,如果是列注釋蚌成,則箱線圖的統(tǒng)計量按列計算前痘,如果是行注釋,則按行計算担忧。
set.seed(12345)
m = matrix(rnorm(100), 10)
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm")))
圖形參數(shù)由gp
控制芹缔。
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"),
gp = gpar(fill = 1:10)))
框的寬度由box_width
控制。outline
控制是否顯示離群點瓶盛。
ha = HeatmapAnnotation(foo = anno_boxplot(m, height = unit(4, "cm"),
box_width = 0.9, outline = FALSE))
anno_boxplot()
只為一行繪制一個箱線圖最欠。多個箱線圖注釋演示了如何定義為單行繪制多個箱線圖的注釋函數(shù),單個箱線圖演示如何為一組行繪制單個箱線圖惩猫。
3.10直方圖標(biāo)注
作為直方圖的注釋更適合作為行注釋芝硬。數(shù)據(jù)變量的設(shè)置與anno_boxplot()
相同,可以是矩陣或列表轧房。
與anno_boxplot()
類似拌阴,輸入數(shù)據(jù)變量應(yīng)該是矩陣或列表。如果 x
是矩陣锯厢,如果是列注釋皮官,則直方圖按列計算,如果是行注釋实辑,則直方圖按行計算捺氢。
m = matrix(rnorm(1000), nc = 100)
ha = rowAnnotation(foo = anno_histogram(m)) # apply `m` on rows
直方圖的中斷次數(shù)由n_breaks
控制。
ha = rowAnnotation(foo = anno_histogram(m, n_breaks = 20))
顏色由gp
控制剪撬。
ha = rowAnnotation(foo = anno_histogram(m, gp = gpar(fill = 1:10)))
3.11密度曲線注釋
與直方圖注釋類似摄乒,anno_density()
將分布顯示為擬合曲線。
ha = rowAnnotation(foo = anno_density(m))
可以控制密度峰值的高度,使分布看起來像一個“joyplot”馍佑。
ha = rowAnnotation(foo = anno_density(m, joyplot_scale = 2,
gp = gpar(fill = "#CCCCCC80")))
或者將分布可視化為小提琴圖斋否。
ha = rowAnnotation(foo = anno_density(m, type = "violin",
gp = gpar(fill = 1:10)))
當(dāng)輸入變量中有太多行時,正常密度峰值的空間可能太小拭荤。在這種情況下茵臭,我們可以通過熱圖可視化分布。
m2 = matrix(rnorm(50*10), nrow = 50)
ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm")))
熱圖分布的顏色模式由heatmap_colors
控制舅世。
ha = rowAnnotation(foo = anno_density(m2, type = "heatmap", width = unit(6, "cm"),
heatmap_colors = c("white", "orange")))
在ComplexHeatmap包中旦委,有一個densityHeatmap()
函數(shù)可以將分布可視化為熱圖。將在密度熱圖介紹 雏亚。
3.12 Joyplot注釋
anno_joyplot()
特定于所謂的 Joyplot ( http://blog.revolutionanalytics.com/2017/07/joyplots.html )缨硝。輸入數(shù)據(jù)應(yīng)該是矩陣或列表。
anno_joyplot()
如果輸入是矩陣罢低,則注釋始終應(yīng)用于列查辩。因為joyplot可視化了平行分布,矩陣不是必需的格式网持,列表已經(jīng)足夠了宜岛,如果你不確定如何設(shè)置為矩陣,只需將其轉(zhuǎn)換為列表來使用它翎碑。
m = matrix(rnorm(1000), nc = 10)
lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"),
gp = gpar(fill = 1:10), transparency = 0.75))
或者只顯示線條(scale
參數(shù)控制曲線的相對高度)谬返。
m = matrix(rnorm(5000), nc = 50)
lt = apply(m, 2, function(x) data.frame(density(x)[c("x", "y")]))
ha = rowAnnotation(foo = anno_joyplot(lt, width = unit(4, "cm"), gp = gpar(fill = NA),
scale = 4))
輸入變量的格式很特殊。它可以是以下兩個之一:
- 一個矩陣(記住
anno_joyplot()
總是應(yīng)用于矩陣的列)日杈,其中 x 坐標(biāo)1:nrow(matrix)
對應(yīng)于矩陣中的每一列對應(yīng)于圖中的一個分布遣铝。 - 一個數(shù)據(jù)框列表,其中每個數(shù)據(jù)框有兩列對應(yīng)于 x 坐標(biāo)和 y 坐標(biāo)莉擒。
3.13地平線圖標(biāo)注
水平線圖 作為注釋只能添加為行注釋酿炸。輸入變量的格式與上面介紹anno_horizon()
的相同anno_joyplot()
。
地平線圖注釋的默認(rèn)樣式為:
lt = lapply(1:20, function(x) cumprod(1 + runif(1000, -x/100, x/100)) - 1)
ha = rowAnnotation(foo = anno_horizon(lt))
每個軌道中的值通過 歸一化x/max(abs(x))
涨冀。
對于正值和負(fù)值的顏色是由gpar()
中pos_fill
和neg_fill
控制填硕。
ha = rowAnnotation(foo = anno_horizon(lt,
gp = gpar(pos_fill = "orange", neg_fill = "darkgreen")))
pos_fill
和neg_fill
可以作為向量分配。
ha = rowAnnotation(foo = anno_horizon(lt,
gp = gpar(pos_fill = rep(c("orange", "red"), each = 10),
neg_fill = rep(c("darkgreen", "blue"), each = 10))))
負(fù)值的峰值是從底部還是從頂部開始鹿鳖。
ha = rowAnnotation(foo = anno_horizon(lt, negative_from_top = TRUE))
每兩個相鄰圖表之間的空間扁眯。
ha = rowAnnotation(foo = anno_horizon(lt, gap = unit(1, "mm")))