R 數(shù)據(jù)可視化 —— 聚類熱圖 ComplexHeatmap(二)注釋

熱圖注釋

前面我們介紹了如何繪制聚類熱圖嗤锉,在這一節(jié)我們將介紹如何添加注釋

熱圖的注釋是聚類熱圖的重要組成部分,能夠?qū)釄D的行扼倘、列附加信息添加到熱圖中嗓奢。

ComplexHeatmap 提供了靈活的熱圖注釋功能,可以在熱圖主體的上燎窘、下摹闽、左、右四個方向上添加注釋褐健,且支持自定義注釋圖形付鹿。

熱圖注釋使用 HeatmapAnnotation 類來構(gòu)建,例如

column_ha <- HeatmapAnnotation(
  foo1 = runif(10), 
  bar1 = anno_barplot(runif(10))
  )
row_ha <- rowAnnotation(
  foo2 = runif(10), 
  bar2 = anno_barplot(runif(10))
  )

其中 rowAnnotation 是行注釋 HeatmapAnnotation(..., which = "row") 的簡便寫法蚜迅,對應(yīng)的也有 columnAnnotation

在這里舵匾,我們分別創(chuàng)建了行列注釋,每個注釋中包含一個顏色條和一個柱狀圖谁不。

注意坐梯,注釋圖形是以 name-value 對的方式指定,即 foo1 表示繪制的圖形名稱刹帕,value 為繪制的內(nèi)容吵血。

如果傳遞的值是向量,則繪制的圖形是 簡單注釋轩拨,而想柱狀圖這種稱為 復(fù)雜注釋

我們可以將這些注釋添加到熱圖中

set.seed(123)
mat <- matrix(rnorm(100), 10)
rownames(mat) <- paste0("R", 1:10)
colnames(mat) <- paste0("C", 1:10)

Heatmap(
  mat, 
  name = "mat", 
  top_annotation = column_ha, 
  right_annotation = row_ha
  )

其中 top_annotation践瓷、right_annotation 指定了注釋放置的位置,我們也可以將注釋放置另外兩個位置

Heatmap(
  mat, 
  name = "mat", 
  bottom_annotation = column_ha, 
  left_annotation = row_ha
  )

熱圖注釋是可以獨立于熱圖而存在的亡蓉,可以使用 +(水平添加)或 %v%(豎直添加)將注釋添加到熱圖中

Heatmap(
  mat, 
  name = "mat"
  ) + row_ha
Heatmap(
  mat, 
  name = "mat"
  ) %v% column_ha

查看注釋對象信息

> 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.96242222222223mm extension on the bottom 

 name   annotation_type color_mapping width
 foo2 continuous vector        random   5mm
 bar2    anno_barplot()                10mm

1. 簡單注釋

簡單注釋是最常用的熱圖注釋晕翠,只需要傳遞一個向量,會將向量的值映射到顏色值砍濒,繪制出一個顏色條淋肾,例如

grid.newpage()
pushViewport(viewport(y = 0.7, height = 0.6, width = 0.8))

ha <- HeatmapAnnotation(foo = 1:10)
draw(ha)

這樣就可以單獨繪制注釋了,為了方便爸邢,除非必要樊卓,后面我們將只貼出注釋的代碼,重要的是知道怎么繪制的就行杠河。

離散型顏色條

ha <- HeatmapAnnotation(
  bar = sample(letters[1:3], 10, replace = TRUE)
  )

這些顏色是隨機的碌尔,每次運行的結(jié)果都不一樣,如果要固定顏色券敌,需要用到 col 參數(shù)

library(circlize)

col_fun <- colorRamp2(
  c(0, 5, 10), 
  c("#ff7f00", "white", "#1f78b4")
  )

ha <- HeatmapAnnotation(
  foo = 1:10,
  col = list(
    foo = col_fun
  )
  )

注意col 參數(shù)的值是一個 list唾戚,這意味著,如果有多個注釋圖形待诅,可以分別為不同的圖形指定顏色

例如叹坦,我們添加離散型數(shù)據(jù)

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ù)來設(shè)置

ha <- HeatmapAnnotation(
  foo = c(1:4, NA, 6:10),
  bar = c(sample(letters[1:3], 4, replace = TRUE), NA, sample(letters[1:3], 5, replace = TRUE)),
  col = list(
    foo = col_fun,
    bar = c("a" = "red", "b" = "green", "c" = "blue")
    ),
  na_col = "black"
  )

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

如果矩陣沒有列名募书,則會將參數(shù)名放置在注釋的中間

ha <- HeatmapAnnotation(
  foo = cbind(runif(10), runif(10))
  )

可以將一個數(shù)據(jù)框傳遞給 df 參數(shù)

ha <- HeatmapAnnotation(
  df = data.frame(
    foo = 1:10,
    bar = sample(letters[1:3], 10, replace = TRUE)
    )
  )

混合使用

ha <- HeatmapAnnotation(
  df = data.frame(
    foo = 1:10,
    bar = sample(letters[1:3], 10, replace = TRUE)
    ),
  foo2 = rnorm(10),
  col = list(
    foo = col_fun,
    bar = c("a" = "red", "b" = "green", "c" = "blue")
  )
  )

使用 border = TRUE 來添加單個注釋的框線

ha <- HeatmapAnnotation(
  df = data.frame(
    foo = 1:10,
    bar = sample(letters[1:3], 10, replace = TRUE)
    ),
  foo2 = cbind(rnorm(10), rnorm(10)),
  col = list(
    foo = col_fun,
    bar = c("a" = "red", "b" = "green", "c" = "blue")
  ),
  border = TRUE
  )

注意:矩陣型和數(shù)據(jù)框型的區(qū)別绪囱,矩陣表示的是一個注釋,而數(shù)據(jù)框的每個變量都是一個注釋

所有單個注釋的高度是一樣的莹捡,使用 simple_anno_size 來設(shè)置單個注釋的高度

ha <- HeatmapAnnotation(
  df = data.frame(
    foo = 1:10,
    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")
  )

也可以設(shè)置全局變量 ht_opt$simple_anno_size 的值來控制單個注釋的大小

2. 注釋函數(shù)

HeatmapAnnotation 支持將注釋作為一個函數(shù)鬼吵,注釋函數(shù)定義了如何在指定的位置繪制相應(yīng)的圖片。

ComplexHeatmap 定義了許多注釋函數(shù)道盏,還可以自定義自己的注釋函數(shù)

所有注釋函數(shù)都是 anno_*() 的形式而柑,不需要指定要將其繪制在什么位置,它會自動檢測該放置在行還是列上荷逞。

上述的簡單注釋,都是隱式的使用了 anno_simple() 函數(shù)粹排,直接使用 anno_simple() 不會自動生成圖例种远,在后面的章節(jié)我們將會介紹如何繪制圖例

例如

ha <- HeatmapAnnotation(
  foo = anno_simple(1:10)
  )

等價于

ha <- HeatmapAnnotation(
  foo = 1:10
  )

anno_simple() 可以在注釋中添加額外的點或單字母字符,并通過 pch, pt_gppt_size 參數(shù)來控制

ha <- HeatmapAnnotation(
  foo = anno_simple(
    1:10, 
    pch = 1,
    pt_gp = gpar(col = "red"),
    pt_size = unit(1:10, "mm"))
  )

pch 設(shè)置為向量

ha <- HeatmapAnnotation(
  foo = anno_simple(
    1:10, 
    pch = 1:10
  )
)

pch 設(shè)置為字符向量

ha <- HeatmapAnnotation(
  foo = anno_simple(
    1:10, 
    pch = sample(letters[1:3], 10, replace = TRUE)
  )
)

如果 pch 值向量中有 NA 值顽耳,則什么也不會畫

ha <- HeatmapAnnotation(
  foo = anno_simple(
    1:10, 
    pch = c(1:4, NA, 6:8, NA, 10, 11)
  )
)

如果 anno_simple() 函數(shù)的值是矩陣坠敷,那么 pch 的長度與矩陣的行數(shù)、列數(shù)或矩陣的長度一致

例如射富,pch 與列數(shù)一致

ha <- HeatmapAnnotation(
  foo = anno_simple(
    cbind(1:10, 10:1), 
    pch = 1:2
  )
)

pch 對應(yīng)行數(shù)

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

anno_simple() 也有 simple_anno_size 參數(shù)膝迎,用于控制單個注釋的高度,height/width 參數(shù)用于控制簡單注釋的高度和寬度

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

注意

應(yīng)該在 anno_*() 函數(shù)內(nèi)設(shè)置 widthheight胰耗。HeatmapAnnotation() 函數(shù)內(nèi)的 width, height, annotation_widthannotation_height 參數(shù)是用來設(shè)置多熱圖的大小

3. 空注釋

anno_empty() 函數(shù)用于繪制一個空白占位符限次,可以在之后使用 decorate_annotation() 函數(shù)將自定義圖形添加到該空白處

anno = anno_empty()
draw(anno, test = "anno_empty")

下面我們舉一個簡單的例子,decoration 函數(shù)的具體介紹將放在后面

有時候柴灯,我們想根據(jù)基因所在的通路對基因進行分組卖漫,我們將文本注釋放置在熱圖的右邊,同時添加顏色柱形

group <- list(
  A = "Cell cycle",
  B = "DNA replication",
  C = "Mismatch repair",
  D = "MAPK signaling pathway"
)

ha = rowAnnotation(
  foo = anno_empty(
    border = FALSE, 
    # 計算空白注釋的寬度
    width = max_text_width(unlist(group)) + unit(4, "mm"))
  )

Heatmap(matrix(
  rnorm(1000), nrow = 100), 
  name = "mat", 
  # 分 4 塊
  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 = rainbow(4)[i], 
        col = NA
        ), 
      just = "left"
      )
    # 繪制文本
    grid.text(
      group[[i]], 
      x = unit(4, "mm"), 
      gp = gpar(
        col = rainbow(4)[i]
      ),
      just = "left")
  })
}

在來個例子吧赠群,我們使用 decorate_annotation 函數(shù)來繪制一個散點圖

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)
# 生成 10 個均勻分布的隨機值
value <- runif(10)
# 將空白裝飾一下
decorate_annotation("foo", {
  # 對應(yīng)于矩陣的列
  x = 1:10
  # 根據(jù)列順序重排這些隨機值羊始,用于設(shè)置 y 軸的值
  value = value[co]
  # 添加 viewport
  pushViewport(
    viewport(
      # x 軸范圍
      xscale = c(0.5, 10.5), 
      # y 軸范圍
      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(
      # 虛線上下的值設(shè)置不同顏色
      col = ifelse(value > 0.5, "red", "blue")), 
    default.units = "native"
    )
  # 設(shè)置 y 軸斷點
  grid.yaxis(at = c(0, 0.5, 1))
  popViewport()
})

雖然代碼比較長,但是還是很簡單的查描。當然突委,你首先得看懂我前面說的 grid 系統(tǒng)是個什么東西

獲取代碼:https://github.com/dxsbiocc/learn/blob/main/R/plot/decorate_example.R

4. 塊注釋

塊注釋也就是添加一個顏色條,用于標識不同的分組冬三,例如

Heatmap(
  matrix(rnorm(100), 10), 
  name = "mat",
  top_annotation = HeatmapAnnotation(
    foo = anno_block(
      gp = gpar(fill = 2:4))
    ),
  column_km = 3
  )

可以在每個塊中添加文本注釋

Heatmap(
  matrix(rnorm(100), 10), 
  column_km = 3,
  # 添加上方注釋
  top_annotation = HeatmapAnnotation(
    foo = anno_block(
      # 設(shè)置填充色
      gp = gpar(fill = 2:4),
      # 設(shè)置文本標簽
      labels = c("group1", "group2", "group3"), 
      # 文本標簽樣式
      labels_gp = gpar(col = "white", fontsize = 10)
      )
    ),
  row_km = 3,
  # 設(shè)置左邊注釋
  left_annotation = rowAnnotation(
    foo = anno_block(
      gp = gpar(fill = 2:4),
      labels = c("group1", "group2", "group3"), 
      labels_gp = gpar(col = "white", fontsize = 10))
    )
  )

記住:標簽和圖形參數(shù)的長度必須與熱圖塊的數(shù)量一致

anno_block() 函數(shù)只能為一個切片繪制一個顏色塊匀油,那如果分組是兩個層級呢?比如长豁,基因有與之相關(guān)的通路钧唐,通路又可以分為信號通路、細胞進程等

例如

set.seed(123)
mat <- matrix(
  rnorm(50*50), 
  nrow = 50
  )

group <- c(
  "MAPK",
  "PI3K-Akt",
  "ErbB",
  "Cell cycle",
  "Apoptosis"
)

ha <- HeatmapAnnotation(
  foo = anno_block(
    gp = gpar(
      fill = 2:6,
      fontsize = 10), 
    labels = group
    )
  )

split = rep(1:5, each = 10)

Heatmap(
  mat, name = "mat", 
  column_split = split, 
  top_annotation = ha, 
  column_title = NULL
  )

現(xiàn)在匠襟,我們想再添加一個塊注釋钝侠,標識前三個為信號通路该园,后兩個為細胞進程通路

該怎么添加呢?要繪制圖形帅韧,首先要有個位置來繪制圖片里初,那可不可以先在上方添加一個空白的注釋

ha <- HeatmapAnnotation(
  empty = anno_empty(border = FALSE),
  foo = anno_block(
    gp = gpar(fill = 2:6), 
    labels = LETTERS[1:5]
    )
)
Heatmap(
  mat, name = "mat", 
  column_split = split, 
  top_annotation = ha, 
  column_title = NULL
  )

現(xiàn)在,已經(jīng)有位置來繪制顏色塊了忽舟,還有一個關(guān)鍵信息双妨,如何獲取到前三個塊的坐標,和后兩個塊的坐標呢叮阅?

對于每個注釋刁品,都有相應(yīng)的 viewport,其命名方式為 annotation_{annotation_name}_{slice_index}浩姥,可以使用 list_components() 函數(shù)來獲取所有的 viewport

> list_components()
 [1] "ROOT"                       "global"                     "global_layout"              "global-heatmaplist"        
 [5] "main_heatmap_list"          "heatmap_mat"                "mat_heatmap_body_wrap"      "mat_heatmap_body_1_1"      
 [9] "mat_heatmap_body_1_2"       "mat_heatmap_body_1_3"       "mat_heatmap_body_1_4"       "mat_heatmap_body_1_5"      
[13] "mat_dend_row_1"             "mat_dend_column_1"          "mat_dend_column_2"          "mat_dend_column_3"         
[17] "mat_dend_column_4"          "mat_dend_column_5"          "annotation_empty_1"         "annotation_foo_1"          
[21] "annotation_empty_2"         "annotation_foo_2"           "annotation_empty_3"         "annotation_foo_3"          
[25] "annotation_empty_4"         "annotation_foo_4"           "annotation_empty_5"         "annotation_foo_5"          
[29] "global-heamap_legend_right" "heatmap_legend"

我們可以看到挑随,空白注釋的 viewportannotation_empty_1 - 5

知道了 viewport 的名稱,可以使用 seekViewport 函數(shù)切換到對應(yīng)的 viewport

# 獲取第一個切片的左側(cè)坐標
seekViewport("annotation_empty_1")
loc1 <- deviceLoc(
  x = unit(0, "npc"), 
  y = unit(0, "npc")
  )
# 獲取第三個切片的右側(cè)坐標
seekViewport("annotation_empty_3")
loc2 <- deviceLoc(
  x = unit(1, "npc"), 
  y = unit(1, "npc")
  )

然后使用 grid::deviceLoc() 函數(shù)來獲取 viewport 對應(yīng)點在整個圖形設(shè)備中的坐標

> loc1
$x
[1] 0.492125984251969in

$y
[1] 7.11417322834646in

獲取到所有信息之后勒叠,我們要切換到 global 這個全局的 viewport 下兜挨,繪制顏色塊

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(
  "Signal transduction", 
  x = (loc1$x + loc2$x) * 0.5, 
  y = (loc1$y + loc2$y) * 0.5
  )

最后,獻上完整的代碼

pdf("~/Downloads/hm.pdf")

set.seed(123)
mat <- matrix(
  rnorm(50*50), 
  nrow = 50
  )

group <- c(
  "MAPK",
  "PI3K-Akt",
  "ErbB",
  "Cell cycle",
  "Apoptosis"
)

split = rep(1:5, each = 10)

ha <- HeatmapAnnotation(
  empty = anno_empty(border = FALSE),
  foo = anno_block(
    gp = gpar(fill = 2:6), 
    labels = group
    )
)

Heatmap(
  mat, name = "mat", 
  column_split = split, 
  top_annotation = ha, 
  column_title = NULL
  )

library(glue)
block_group_anno <- function(group, empty_anno, gp = gpar(),
                             label = NULL, label_gp = gpar()) {
  # 獲取最左側(cè) viewport
  seekViewport(glue(
    'annotation_{anno}_{slice}', 
    slice = min(group),
    anno = empty_anno)
    )
  # 獲取左下角坐標點
  loc1 <- deviceLoc(
    x = unit(0, "npc"), 
    y = unit(0, "npc")
  )
  # 獲取最右側(cè) viewport
  seekViewport(glue(
    'annotation_{anno}_{slice}', 
    slice = max(group),
    anno = empty_anno)
  )
  # 獲取右上角坐標點
  loc2 <- deviceLoc(
    x = unit(1, "npc"), 
    y = unit(1, "npc")
  )
  # 切換到全局 viewport
  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
    )
  }
}
# 將前三個熱圖塊作為一組
block_group_anno(1:3, "empty", gp = gpar(fill = "red"), label = "Signal transduction")
# 后兩個作為一組
block_group_anno(4:5, "empty", gp = gpar(fill = "green"), label = "Cellular Processes")

dev.off()

獲取代碼:https://github.com/dxsbiocc/learn/blob/main/R/plot/multi_group_plock_anno.R

注意:我們將圖片保存成了文件拌汇,而不是在 RStudio 中直接繪制。

可能是由于 deviceLoc 獲取的是圖形設(shè)備的坐標位置弊决,而不是相對于繪圖窗口的位置噪舀,所以,在 RStudio 中需要拉伸繪圖窗口才能看到后面繪制的矩形丢氢。所以我們直接使用 pdf 來保存成文件傅联,就不會有這個問題了。

5. 圖片注釋

可以將圖片作為注釋添加到熱圖中疚察,anno_image() 函數(shù)支持 png, svg, pdf, eps, jpeg/jpg, tiff 圖片格式

anno_image() 函數(shù)會在內(nèi)部自動解析各種格式的圖片蒸走,只需要傳遞圖片路徑即可。但是需要安裝對應(yīng)的包

  • grImport2:該包用于處理 svg 圖片貌嫡,但是安裝之后所有圖片都無法顯示比驻,有問題,不建議安裝
  • rsvg:轉(zhuǎn)換 svg 格式
  • grImport:處理 pdfeps 圖片

同時岛抄,要確保系統(tǒng)中安裝了 ghostscript别惦,不然無法使用 pdfeps 格式文件

例如,我們從 https://github.com/Keyamoon/IcoMoon-Free 下載到圖標文件

path <- '~/Downloads/IcoMoon-Free-master/'

image_png = sample(dir(glue("{path}/PNG/64px"), full.names = TRUE), 10)
image_eps = sample(dir(glue("{path}/EPS/"), full.names = TRUE), 10)
image_pdf = sample(dir(glue("{path}/PDF/"), full.names = TRUE), 10)

添加圖標注釋

grid.newpage()
pushViewport(viewport(y = 0.6, height = 0.6, width = 0.8))

ha <- HeatmapAnnotation(foo = anno_image(image_png))

draw(ha)

混合不同格式的圖片

ha <- HeatmapAnnotation(
  foo = anno_image(
    c(image_png[1:3], 
      image_eps[1:3], 
      image_pdf[1:3]
      ),
    gp = gpar(
      fill = rainbow(9),
      col = "grey"
    )
  )
)

設(shè)置邊框以及圖片周圍空白填充間距

ha <- HeatmapAnnotation(
  foo = anno_image(
    image_pdf,
    border = TRUE,
    space = unit(3, "mm"),
    gp = gpar(
      fill = rainbow(9),
      col = "grey"
    )
  )
)

如果圖片的路徑為空或 NA夫椭,則不會顯示

image_pdf[1:2] = c("", NA)
ha <- HeatmapAnnotation(
  foo = anno_image(
    image_pdf,
    border = TRUE,
    space = unit(3, "mm"),
    gp = gpar(
      fill = rainbow(9),
      col = "grey"
    )
  )
)

6. 點注釋

散點注釋使用 anno_points() 函數(shù)來展示點的分布掸掸。

點數(shù)據(jù)對象可以是向量或矩陣,如果是矩陣,則圖形屬性參數(shù)如 pch扰付、sizegp 是按列設(shè)置的堤撵。

注意:矩陣的行對應(yīng)熱圖的列

傳遞一個向量

image_pdf[1:2] = c("", NA)
ha <- HeatmapAnnotation(
  foo = anno_points(runif(10))
)

傳遞矩陣,圖形參數(shù)值的長度與列數(shù)一致

ha <- HeatmapAnnotation(
  foo = anno_points(
    matrix(runif(20), nc = 2), 
    pch = 1:2, 
    gp = gpar(col = 2:3)
    )
)

ylim 可以設(shè)置 y 軸的范圍,extend 控制數(shù)據(jù)軸上的擴展空間,axis 參數(shù)控制是否顯示軸滔驶,axis_param 參數(shù)用于設(shè)置軸

使用 default_axis_param() 可以獲取行或列注釋的軸默認屬性

> 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),
    extend = 0.1,
    axis_param = list(
      side = "right",
      at = c(0, 0.5, 1), 
      labels = c("zero", "half", "one")
    )
    )
)

標簽旋轉(zhuǎn)

ha <- rowAnnotation(
  foo = anno_points(
    runif(10),
    ylim = c(0, 1),
    extend = 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
    )
    )
)

其他有軸的圖形設(shè)置都是類似的

7. 線注釋

anno_lines() 用于繪制線條,與點注釋類似航揉,數(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, 5)
  )
)

我們可以設(shè)置 add_points = TRUE 來添加點,pt_gp 設(shè)置點的圖形屬性,pch 設(shè)置點的形狀

可以設(shè)置 smooth = TRUE 來添加擬合曲線,在這種情況下志电,add_points 默認為 TRUE。同時也需要注意长酗,擬合是按照排序后的列順序執(zhí)行的溪北,需要確保該順序符合你的要求

ha <- HeatmapAnnotation(
  foo = anno_lines(
    cbind(c(1:5, 1:5), c(5:1, 5:1)),
    gp = gpar(col = 2:3),
    smooth = TRUE,
    pt_gp = gpar(col = 5:6),
    pch = c(1, 5)
  )
)

線注釋的默認大小為 5mm,可以在函數(shù)內(nèi)使用 height/width 來調(diào)整

8. 條形圖注釋

anno_barplot() 函數(shù)用于添加條形圖注釋夺脾,其中一些參數(shù),如 ylim, axis, axis_paramanno_points() 一樣

ha <- HeatmapAnnotation(
  foo = anno_barplot(1:10)
)

bar_width 用于設(shè)置條形的寬度茉继,其值為相對于熱圖主體單元格的寬度

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    1:10,
    bar_width = 0.8)
)

設(shè)置圖形屬性

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    1:10,
    gp = gpar(
      fill = rainbow(10)
    ))
)

使用 baseline 參數(shù)來設(shè)置基線

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    -5:5,
    baseline = 0,
    gp = gpar(
      fill = rainbow(10)
    ))
)
ha <- HeatmapAnnotation(
  foo = anno_barplot(
    -5:5,
    baseline = "min",
    gp = gpar(
      fill = rainbow(10)
    ))
)

如果輸入的是矩陣咧叭,可以設(shè)置堆積條形圖

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    matrix(c(1:10, 10:1), nc = 2),
    gp = gpar(
      fill = rainbow(2),
      col = 3:4
    )
  )
)

圖形屬性參數(shù)的長度與矩陣列數(shù)一致

條形圖注釋的大小默認為 5mm,我們可以使用 height/width 設(shè)置其高度和寬度

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    matrix(c(1:10, 10:1), nc = 2),
    height = unit(2, "cm"),
    gp = gpar(
      fill = rainbow(2),
      col = 3:4
    )
  )
)

繪制百分比條形圖

m <- matrix(runif(4*10), nc = 4)
m <- t(apply(m, 1, function(x) x/sum(x)))

ha <- HeatmapAnnotation(
  foo = anno_barplot(
    m,
    height = unit(6, "cm"),
    bar_width = 1,
    gp = gpar(
      fill = rainbow(4))
  )
)

也可以設(shè)置軸的朝向

ha_list <- 
  rowAnnotation(
    axis_reverse = anno_barplot(
      m, gp = gpar(fill = rainbow(4)), 
      axis_param = list(direction = "reverse"), 
      bar_width = 1, width = unit(4, "cm"))
    ) +
  rowAnnotation(
    axis_normal = anno_barplot(
      m, gp = gpar(fill = rainbow(4)), 
      bar_width = 1, 
      width = unit(4, "cm"))
    )
draw(ha_list, ht_gap = unit(4, "mm"))

9. 箱線圖注釋

anno_boxplot() 用于繪制箱線圖注釋烁竭,數(shù)據(jù)對象為矩陣或列表菲茬。

如果數(shù)據(jù)是矩陣,且為列注釋派撕,將會按列對矩陣進行統(tǒng)計婉弹,行注釋將按行執(zhí)行統(tǒng)計

注意:箱線圖適用于小型數(shù)據(jù),如果數(shù)據(jù)列太多终吼,不推薦使用

mat <- matrix(rnorm(100), 10)
ha <- HeatmapAnnotation(
  foo = anno_boxplot(
    mat,
    height = unit(4, "cm")
  )
)

添加圖形屬性

mat <- matrix(rnorm(100), 10)
ha <- HeatmapAnnotation(
  foo = anno_boxplot(
    mat,
    height = unit(4, "cm"),
    gp = gpar(
      fill = rainbow(10)
    )
  )
)

outline 用于設(shè)置是否顯示離群點镀赌,box_width 用于設(shè)置箱子寬度

mat <- matrix(rnorm(100), 10)
ha <- HeatmapAnnotation(
  foo = anno_boxplot(
    mat,
    height = unit(4, "cm"),
    box_width = 0.8,
    outline = FALSE,
    gp = gpar(
      fill = rainbow(10)
    )
  )
)

10。 直方圖注釋

anno_histogram() 用于添加直方圖注釋际跪,適用于行注釋商佛,其參數(shù)與 anno_boxplot() 類似

mat <- matrix(rnorm(1000), nc = 100)
ha <- rowAnnotation(
  foo = anno_histogram(
    mat,
    n_breaks = 20,
    gp = gpar(fill = rainbow(10))
  )
)

n_breaks 用于設(shè)置柱子的數(shù)量

11. 密度注釋

anno_density() 函數(shù)用于繪制密度曲線注釋

mat <- matrix(rnorm(1000), nc = 100)
ha <- rowAnnotation(
  foo = anno_density(
    mat,
    joyplot_scale = 2,
    gp = gpar(fill = rainbow(10))
  )
)

使用 joyplot_scale 來控制分布峰值的高度,讓它看起來像山脊圖

以小提琴的方式繪制

ha <- rowAnnotation(
  foo = anno_density(
    mat,
    type = "violin",
    gp = gpar(fill = rainbow(10))
  )
)

如果行數(shù)太多了姆打,可以繪制熱圖

ha <- rowAnnotation(
  foo = anno_density(
    mat,
    type = "heatmap",
    heatmap_colors = c("#9970ab", "#5aae61")
  )
)

使用 heatmap_colors 來控制熱圖的顏色

12. Joyplot 注釋

joyplot 圖也就是我們說的山脊圖良姆,使用 anno_joyplot() 函數(shù)繪制,接受矩陣或列表數(shù)據(jù)

如果數(shù)據(jù)為矩陣幔戏,則總是按列計算的玛追,如果你不確定怎么設(shè)置,可以轉(zhuǎn)換為 list

輸入變量的格式為:

  • 矩陣:x 坐標為 1:nrow(matrix) 且矩陣的每一列是一個分布
  • 列表:數(shù)據(jù)框列表闲延,每個數(shù)據(jù)框包含兩列痊剖,表示 xy 坐標
mat <- matrix(rnorm(1000), nc = 10)
lt <- apply(mat, 2, function(x) data.frame(density(x)[c("x", "y")]))

ha <- rowAnnotation(
  foo = anno_joyplot(
    lt,
    width = unit(4, "cm"),
    gp = gpar(fill = rainbow(10)),
    transparency = 0.6
  )
)

或者韩玩,只顯示線條,同時使用 scale 設(shè)置峰值的高度

ha <- rowAnnotation(
  foo = anno_joyplot(
    lt,
    width = unit(4, "cm"),
    gp = gpar(fill = NA),
    scale = 2
  )
)

13. 地平線圖注釋

地平線圖只能作為行注釋邢笙,輸入數(shù)據(jù)的格式類似于 anno_joyplot()

lt <- lapply(1:20, function(x) cumprod(1 + runif(1000, -x/100, x/100)) - 1)

ha <- rowAnnotation(
  foo = anno_horizon(
    lt,
    height = unit(6, "cm"),
    gp = gpar(
      pos_fill = "orange",
      neg_fill = "darkgreen"
    )
  )
)

使用 pos_fillneg_fill 來設(shè)置正負值的填充色

也可以為 pos_fillneg_fill 設(shè)置向量值

ha <- rowAnnotation(
  foo = anno_horizon(
    lt,
    height = unit(6, "cm"),
    gp = gpar(
      pos_fill = rep(rainbow(10)[5:6], 10),
      neg_fill = rep(rainbow(10)[8:9], 10)
    )
  )
)

使用 gap 設(shè)置兩張圖的間距啸如,negative_from_top 參數(shù)用于設(shè)置負值的峰值是否從頂部開始

ha <- rowAnnotation(
  foo = anno_horizon(
    lt,
    height = unit(6, "cm"),
    negative_from_top = TRUE,
    gap = unit(1, "mm"),
    gp = gpar(
      pos_fill = rep(rainbow(10)[5:6], 10),
      neg_fill = rep(rainbow(10)[8:9], 10)
    )
  )
)

14 文本注釋

使用 anno_text() 來添加文本注釋

ha <- rowAnnotation(
  foo = anno_text(
    month.name,
    location = 1,
    just = "center",
    rot = 45,
    gp = gpar(
      fontsize = 5:17
    )
  )
)

locationjust 會根據(jù)注釋的位置自動計算,如果注釋放置在右邊氮惯,則文本會左對齊叮雳,反之,在左邊妇汗,右對齊

根據(jù)所有文本會自動計算 width/height 的值帘不,一般不需要手動設(shè)置

ha <- rowAnnotation(
  foo = anno_text(
    month.name,
    location = 0.5,
    just = "center",
    gp = gpar(
      fill = rep(rainbow(10)[2:5], each = 4),
      col = "black",
      border = "black"
    ),
    width = max_text_width(month.name) * 1.2
  )
)

可以使用 gridtext 包繪制更復(fù)雜的文本

15. 標記注釋

anno_mark(代替了被替換的 anno_link)用于標記某些行/列,并使用線條連接文本和對應(yīng)的行/列

anno_mark() 至少需要兩個參數(shù)杨箭,at 提供原始數(shù)據(jù)矩陣的索引寞焙,labels 為相應(yīng)的文本標記

mat <- matrix(rnorm(1000), nrow = 100)
rownames(mat) <- 1:100
ha <- rowAnnotation(
  foo = anno_mark(
    at = c(1:4, 20, 60, 97:100), 
    labels = month.name[1:10])
  )

Heatmap(
  mat, name = "mat", 
  cluster_rows = FALSE, 
  right_annotation = ha,
  row_names_side = "left", 
  row_names_gp = gpar(fontsize = 4)
  )

16 摘要注釋

anno_summary() 用于對只有一行或一列的熱圖提供統(tǒng)計匯總注釋

如果數(shù)據(jù)為離散型向量,將繪制條形圖

v <- sample(letters[1:2], 50, replace = TRUE)
split <- sample(letters[1:2], 50, replace = TRUE)

ha <- HeatmapAnnotation(
  summary = anno_summary(height = unit(4, "cm"))
)

Heatmap(
  v, name = "mat", 
  col = c("a" = "red", "b" = "blue"),
  top_annotation = ha, 
  width = unit(2, "cm"), 
  row_split = split
)

對于連續(xù)型向量將繪制箱線圖

v <- rnorm(50)

ha <- HeatmapAnnotation(
  summary = anno_summary(
    gp = gpar(fill = 3:4),
    height = unit(4, "cm")
    )
)

Heatmap(
  v, name = "mat", 
  top_annotation = ha, 
  width = unit(2, "cm"), 
  row_split = split
)

我們通常不會單獨繪制只包含一列的熱圖互婿,而是會與其他熱圖繪制在一起

比如捣郊,我們在基因表達矩陣的邊上,繪制一個 lncRNAMiRNA 的表達熱圖

# 設(shè)置熱圖配色
col_fun <- colorRamp2(
  c(-2, 0, 2), 
  c("#8c510a", "white", "#01665e")
)

# 繪制主熱圖
exp <- matrix(rnorm(50*10), nrow = 50)
main <- Heatmap(
  exp, name = "main_matrix",
  col = col_fun
  )

# 繪制一列離散型熱圖
v <- sample(letters[1:2], 50, replace = TRUE)
lnc <- Heatmap(
  v, name = "mat1", 
  # 設(shè)置離散型顏色
  col = structure(c("#f46d43", "#66bd63"), name = letters[1:2]),
  top_annotation = HeatmapAnnotation(
    summary = anno_summary(
      height = unit(3, "cm")
    )
  ), 
  width = unit(1, "cm"),
  )

# 繪制一列連續(xù)型熱圖
v <- rnorm(50)
mi <- Heatmap(
  v, name = "mat2", 
  col = col_fun,
  top_annotation = HeatmapAnnotation(
    summary = anno_summary(
      gp = gpar(fill = 2:3), 
      height = unit(3, "cm"))
  ), 
  width = unit(1, "cm")
  )

# 按列添加多個熱圖
ht_list <- main + lnc + mi

split <- sample(letters[1:2], 50, replace = TRUE)

draw(ht_list, 
     row_split = split, 
     ht_gap = unit(5, "mm"), 
     heatmap_legend_list = list(lgd_boxplot)
     )

17. 縮放/連接注釋

anno_mark() 用于將某些行/列連接到文本標簽慈参,anno_zoom() 則用于將行列子集連接到一個繪圖區(qū)域呛牲,并可在該區(qū)域繪制自定義圖形⊥耘洌可以理解為從熱圖矩陣中拿出部分子集來繪制一個任意的圖形

例如娘扩,我們可以為每個分組繪制一個箱線圖

# 設(shè)置熱圖配色
col_fun <- colorRamp2(
  c(-2, 0, 2), 
  c("#8c510a", "white", "#01665e")
)

# 生成表達譜
exp <- matrix(rnorm(100*10), nrow = 100)
# 設(shè)置分組
group <- sample(letters[1:3], 100, 
                replace = TRUE, 
                prob = c(1, 5, 10)
                )

panel_fun <- function(index, nm) {
  # 添加繪圖 viewport
  pushViewport(viewport(xscale = range(exp), yscale = c(0, 2)))
  # 繪制區(qū)域外側(cè)框線
  grid.rect()
  grid.xaxis(gp = gpar(fontsize = 8))
  # 添加箱線圖
  grid.boxplot(
    exp[index, ], pos = 1, 
    gp = gpar(fill = index + 6),
    direction = "horizontal"
    )
  popViewport()
}

Heatmap(
  exp, name = "exp", 
  col = col_fun,
  row_split = group,
  height = unit(10, "cm"),
  width = unit(12, "cm"),
  right_annotation = rowAnnotation(
    foo = anno_zoom(
      align_to = group,
      which = "row",
      panel_fun = panel_fun,
      size = unit(2, "cm"),
      gap = unit(1, "cm"),
      width = unit(4, "cm")
    ))
  )

anno_zoom() 函數(shù)的參數(shù)

  • align_to:定義了行或列的分組繪圖區(qū)域。如果是索引列表壮锻,則其中每個向量為一組琐旁,如果為分類變量,則將根據(jù) level 分組

  • panel_fun:自定義的繪圖函數(shù)猜绣。函數(shù)的第一個參數(shù)為 index灰殴,表示分組在矩陣中的索引,第二個參數(shù)為 nm途事,代表選擇的熱圖區(qū)域的名稱验懊,該名稱來自 align_to 的分類變量或 list 中的名稱

  • size:箱子的大小,可以是絕對值或相對值尸变,相對于熱圖的寬度和高度

  • gap:箱子的間隔

18. 多個注釋

18.1 常規(guī)設(shè)置

在前面的示例中义图,我們以鍵值對的方式在 HeatmapAnnotation() 函數(shù)中添加多個注釋,還有一些參數(shù)用于控制多個注釋召烂,這些參數(shù)的值長度要與注釋數(shù)目相同

不管是向量碱工、矩陣或數(shù)據(jù)框數(shù)據(jù),繪制簡單注釋都會自動添加圖例,使用 show_legend 可以控制圖例的顯示

對于輸入數(shù)據(jù)的不同怕篷,show_legend 的格式也有區(qū)別:

  • 長度為簡單注釋數(shù)量的邏輯向量
  • 長度為所有注釋的數(shù)量历筝,對應(yīng)于復(fù)雜注釋的值將被忽略
  • 命名向量,控制簡單注釋的子集

例如

ha = HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10),
  show_legend = c("bar" = FALSE)
)
Heatmap(
  matrix(rnorm(100), 10), 
  name = "mat", 
  top_annotation = ha
  )

border 控制單個注釋的外側(cè)框線廊谓,show_annotation_name 控制注釋名稱的顯示

ha <- HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10),
  gp = gpar(col = "red"),
  show_annotation_name = c(bar = FALSE),
  border = c(foo = TRUE)
)

annotation_name_gp, annotation_name_offset, annotation_name_sideannotation_name_rot 用于控制注釋名的樣式屬性和位置梳猪,后面三個可以被設(shè)置為命名向量。

annotation_name_offset 設(shè)置為命名向量時蒸痹,值不需要 unit 函數(shù)設(shè)置春弥,可以直接使用字符表示
annotation_name_offset = c(foo = "1cm")

gap 參數(shù)用于設(shè)置兩個注釋的間隔,可以是單個值或向量

ha <- HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10),
  gap = unit(2, "mm")
  )
ha <- HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10),
  gap = unit(c(2, 10), "mm")
  )

18.2 注釋的大小

height, width, annotation_heightannotation_width 用于控制復(fù)雜注釋的大小叠荠,通常來說匿沛,簡單注釋不需要設(shè)置,會根據(jù)圖形自動調(diào)整榛鼎。

例如

# foo: 1cm, bar: 5mm, pt: 1cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  pt = anno_points(1:10)
  )

當使用 height 參數(shù)設(shè)置注釋的高度時逃呼,簡單注釋的高度不會改變,只會改變復(fù)雜注釋的高度

# foo: 1cm, bar: 5mm, pt: 4.5cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  pt = anno_points(1:10),
  height = unit(6, "cm")
  )

simple_anno_size 控制所有簡單注釋的大小者娱,全局簡單注釋的大小可以使用 ht_opt$simple_anno_size 設(shè)置

# foo: 2cm, bar:1cm, pt: 3cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1),  
  bar = 1:10,
  pt = anno_points(1:10),
  simple_anno_size = unit(1, "cm"), 
  height = unit(6, "cm")
  )

所有簡單注釋都被設(shè)置為 1cm

annotation_height 可以分別為每個注釋設(shè)置高度

# foo: 1cm, bar: 2cm, pt: 3cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  pt = anno_points(1:10),
  annotation_height = unit(1:3, "cm")
  )

annotation_height 也可以設(shè)置為純數(shù)值抡笼,會將其作為注釋的相對比例值

# foo: 1cm, bar: 2cm, pt: 3cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  pt = anno_points(1:10),
  annotation_height = 1:3,
  height = unit(6, "cm")
  )

annotation_height 也可以混合絕對值和相對值

# foo: 1.5cm, bar: 1.5cm, pt: 3cm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  pt = anno_points(1:10),
  annotation_height = unit(c(1, 1, 3), c("null", "null", "cm")), 
  height = unit(6, "cm")
)

如果只有簡單注釋,設(shè)置 height 將不會有任何作用

# foo: 1cm, bar: 5mm
ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  height = unit(6, "cm")
  )

除非將 simple_anno_size_adjust 設(shè)置為 TRUE

ha <- HeatmapAnnotation(
  foo = cbind(1:10, 10:1), 
  bar = 1:10,
  simple_anno_size_adjust = TRUE,
  height = unit(6, "cm")
  )

19. 實用函數(shù)

有一些實用函數(shù)黄鳍,可以對注釋進行更靈活的操作蔫缸,例如,對于如下注釋

ha <- HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10)
  )

計算注釋的數(shù)量际起,觀察值的數(shù)量

> draw(ha)
> length(ha)
[1] 3
> nobs(ha)
[1] 10

獲取和設(shè)置注釋的名稱

> names(ha)
[1] "foo" "bar" "pt" 
> names(ha) <- c("A", "B", "C")
> names(ha)
[1] "A" "B" "C"

如果兩個 HeatmapAnnotation 對象具有相同的觀測值且注釋名稱不同,可以連接起來

ha1 <- HeatmapAnnotation(
  foo = 1:10, 
  bar = cbind(1:10, 10:1),
  pt = anno_points(1:10)
  )
ha2 <- HeatmapAnnotation(
  FOO = runif(10), 
  BAR = sample(c("a", "b"), 10, replace = TRUE),
  PT = anno_points(rnorm(10))
  )
ha <- c(ha1, ha2)
> names(ha)
[1] "foo" "bar" "pt"  "FOO" "BAR" "PT" 

可以對 HeatmapAnnotation 對象進行取子集操作吐葱,行對應(yīng)為觀察值街望,列對應(yīng)注釋名稱

> ha_subset <- ha[1:5, c("foo", "PT")]
> ha_subset
A HeatmapAnnotation object with 2 annotations
  name: heatmap_annotation_154 
  position: column 
  items: 5 
  width: 1npc 
  height: 15.3514598035146mm 
  this object is subsetable
  5.21733333333333mm extension on the left 
  6.75733333333333mm extension on the right 

 name   annotation_type color_mapping height
  foo continuous vector        random    5mm
   PT     anno_points()                 10mm

20. 自定義注釋函數(shù)

ComplexHeatmap 中的所有注釋函數(shù)都是使用 AnnotationFunction 類來構(gòu)造的

AnnotationFunction 類的重要部分是一個函數(shù),該函數(shù)定義如何在與熱圖中的行或列相對應(yīng)的特定位置處進行繪制圖形

該函數(shù)包含三個參數(shù):

  • index:對應(yīng)于熱圖矩陣的行或列的索引弟跑,包含行或列重新排序后當前切片的行或列索引的列表
  • k:代表當前熱圖塊的索引
  • n:代表所有熱圖塊數(shù)目

后兩個參數(shù)是可選的灾前,注釋函數(shù)會在每個切片中獨立繪制。

var_import 參數(shù)用于存儲該函數(shù)的額外參數(shù)

AnnotationFunction 的一個特性是可子集化孟辑,用于需要定義輸入變量的拆分規(guī)則哎甲,包中自帶了子集化規(guī)則函數(shù) subset_gp(), subset_matrix_by_row()subset_vector(),如果未指定饲嗽,會根據(jù)輸入對象的類型自動推斷

例如炭玫,定義一個簡單的注釋函數(shù)

x <- 1:10
anno1 <- AnnotationFunction(
  fun = function(index, k, n) {
    n = length(index)
    # 根據(jù)索引長度分配 viewport 空間
    pushViewport(viewport(xscale = c(0.5, n + 0.5), yscale = c(0, 10)))
    grid.rect()
    # 繪制散點
    grid.points(1:n, x[index], default.units = "native")
    if(k == 1) grid.yaxis()
    popViewport()
  },
  # 傳遞函數(shù)的額外參數(shù)
  var_import = list(x = x),
  n = 10,
  subsetable = TRUE,
  height = unit(2, "cm")
)

下面來使用它

m = rbind(1:10, 11:20)
Heatmap(
  m, 
  top_annotation = HeatmapAnnotation(foo = anno1)
  )

應(yīng)用于分割熱圖塊

Heatmap(
  m, 
  top_annotation = HeatmapAnnotation(foo = anno1), 
  column_split = rep(c("A", "B"), each = 5)
  )

上面的函數(shù)可以改進,將數(shù)據(jù)變量放入內(nèi)部

anno2 <- AnnotationFunction(
    fun = function(index) {
        x = 1:10
        n = length(index)
        pushViewport(viewport())
        grid.points(1:n, x[index])
        popViewport()
    },
    n = 10,
    subsetable = TRUE
)

最精簡的方式是貌虾,只定義函數(shù)

anno3 <- AnnotationFunction(
    fun = function(index) {
        x = 1:10
        n = length(index)
        pushViewport(viewport())
        grid.points(1:n, x[index])
        popViewport()
    }
)

其實吞加,本節(jié)中介紹的所有 anno_*() 函數(shù)實際上并不是真正的注釋函數(shù),它們只是生成具有特定配置的注釋函數(shù)的函數(shù)

事實上,ComplexHeatmap 已經(jīng)提供了足夠多的函數(shù)了衔憨,可以滿足絕大部分的需求叶圃。是在沒有的,也可以通過 anno_empty() 放置一個空白占位践图,然后使用 decorate_annotation() 函數(shù)快速添加自定義圖形掺冠。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市码党,隨后出現(xiàn)的幾起案子德崭,更是在濱河造成了極大的恐慌,老刑警劉巖闽瓢,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件接癌,死亡現(xiàn)場離奇詭異,居然都是意外死亡扣讼,警方通過查閱死者的電腦和手機缺猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椭符,“玉大人荔燎,你說我怎么就攤上這事∠郏” “怎么了有咨?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒸健。 經(jīng)常有香客問我座享,道長,這世上最難降的妖魔是什么似忧? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任渣叛,我火速辦了婚禮,結(jié)果婚禮上盯捌,老公的妹妹穿的比我還像新娘淳衙。我一直安慰自己,他們只是感情好饺著,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布箫攀。 她就那樣靜靜地躺著,像睡著了一般幼衰。 火紅的嫁衣襯著肌膚如雪靴跛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天塑顺,我揣著相機與錄音汤求,去河邊找鬼俏险。 笑死,一個胖子當著我的面吹牛扬绪,可吹牛的內(nèi)容都是我干的竖独。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼挤牛,長吁一口氣:“原來是場噩夢啊……” “哼莹痢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起墓赴,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤竞膳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诫硕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坦辟,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年章办,在試婚紗的時候發(fā)現(xiàn)自己被綠了锉走。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡藕届,死狀恐怖挪蹭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情休偶,我是刑警寧澤梁厉,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站踏兜,受9級特大地震影響词顾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碱妆,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一计技、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧山橄,春花似錦、人聲如沸舍悯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萌衬。三九已至饮醇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秕豫,已是汗流浹背朴艰。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工观蓄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人祠墅。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓侮穿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親毁嗦。 傳聞我的和親對象是個殘疾皇子亲茅,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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