R 數(shù)據(jù)可視化 —— 聚類熱圖 ComplexHeatmap(四)圖例
前言
忘了說了瞒渠,直接使用
install.packages("ComplexHeatmap")
安裝的版本比較老舊向臀,有些功能不支持芥吟。比如富文本解析函數(shù) gt_render
澎灸,以及一些參數(shù)和圖形表現(xiàn)形式的差異蛹头。
所以為了獲取更新的顿肺、完善的功能,推薦大家使用 devtools
安裝 GitHub
上的 2.7
版本
library(devtools)
install_github("jokergoo/ComplexHeatmap")
熱圖和簡單注釋會自動生成圖例渣蜗,并放置在圖像右邊區(qū)域屠尊。而復(fù)雜注釋默認不會顯示圖例,但是可以手動構(gòu)建和添加
所有圖例都是通過 Legend()
函數(shù)來構(gòu)造的耕拷,不論是單個圖例讼昆,還是多個圖例都屬于 Legends
類
熱圖和注釋的圖例可以分別在 Heatmap()
函數(shù)的 heatmap_legend_param
參數(shù)和 HeatmapAnnotation()
函數(shù)的 annotation_legend_param
參數(shù)中進行設(shè)置
1. 連續(xù)型圖例
連續(xù)型圖例需要傳遞一個顏色映射函數(shù),類似于熱圖及注釋函數(shù)中的 col
參數(shù)骚烧,但是圖例中的顏色映射函數(shù)中的 break
與顯式的并不完全一樣
例如
col_fun <- colorRamp2(
breaks = c(0, 0.5, 1),
colors = c("blue", "white", "red")
)
lgd <- Legend(col_fun = col_fun, title = "foo")
圖例中顯示的斷點數(shù)會自動調(diào)整浸赫,使標(biāo)簽數(shù)量接近 5
或 6
> class(lgd)
[1] "Legends"
attr(,"package")
[1] "ComplexHeatmap"
可以看到闰围,lgd
為 Legends
類,可以使用 width.Legends()
和 height.Legends()
獲取圖例的大小
> width.Legends(lgd)
[1] 9.90361111111111mm
> height.Legends(lgd)
[1] 28.0329444444444mm
圖例實際上由矩形既峡、線條和文本組成的包裝圖形對象羡榴。它可以通過 draw()
函數(shù)添加到繪圖中
pushViewport(viewport(width = 0.9, height = 0.9))
grid.rect()
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()
下面的例子中,我們將只給出圖例的配置运敢,而不再顯式地使用 draw
來繪制
可以使用 at
參數(shù)來調(diào)整圖例的斷點
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.25, 0.5, 0.75, 1))
labels
用于設(shè)置圖例標(biāo)簽校仑,labels_gp
用于設(shè)置標(biāo)簽圖形屬性
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.5, 1),
labels = c("low", "median", "high"),
labels_gp = gpar(col = "red", font = 3)
)
圖例標(biāo)題和標(biāo)簽可以設(shè)置為公式
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)
)
設(shè)置富文本
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"))
)
legend_height
可以設(shè)置豎直圖例主體的高度,不包括圖例標(biāo)題传惠,grid_width
控制圖例主體的寬度
lgd <- Legend(
col_fun = col_fun, title = "foo",
legend_height = unit(6, "cm"),
grid_width = unit(1, "cm")
)
border
用于控制圖例框線和刻度顏色迄沫,可以是邏輯值或顏色值
lgd <- Legend(
col_fun = col_fun, title = "foo",
border = "blue"
)
title_position
控制圖例標(biāo)題的位置,對于豎直圖例卦方,可選的值為 topleft
羊瘩、topcenter
、lefttop-rot
和 leftcenter-rot
例如盼砍,左側(cè)上方旋轉(zhuǎn)
lgd <- Legend(
col_fun = col_fun, title = "foooooooo",
title_position = "lefttop-rot",
legend_height = unit(4, "cm")
)
左側(cè)中心且旋轉(zhuǎn)
lgd <- Legend(
col_fun = col_fun, title = "foooooooo",
title_position = "leftcenter-rot",
legend_height = unit(4, "cm")
)
類似地尘吗,對于水平圖例,legend_width
可以設(shè)置相應(yīng)的寬度衬廷,topcenter
摇予、topleft
、lefttop
和 leftcenter
控制圖例標(biāo)題
例如
lgd <- Legend(col_fun = col_fun, title = "foo", direction = "horizontal")
設(shè)置寬度
lgd <- Legend(
col_fun = col_fun, title = "foo",
legend_width = unit(6, "cm"),
direction = "horizontal"
)
設(shè)置斷點吗跋、標(biāo)簽及其圖形參數(shù)
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.5, 1), direction = "horizontal",
labels = c("low", "median", "high"),
labels_gp = gpar(col = "red", font = 3)
)
設(shè)置標(biāo)題位置 topleft
侧戴、topcenter
、lefttop
跌宛、leftcenter
lgd <- Legend(
col_fun = col_fun, title = "foooooooo",
direction = "horizontal",
title_position = "topcenter"
)
lgd <- Legend(
col_fun = col_fun, title = "foooooooo",
direction = "horizontal",
title_position = "lefttop"
)
在上面的示例中酗宋,斷點都是等間隔的,其實 at
參數(shù)也可以設(shè)置為非等間隔的區(qū)間疆拘。例如
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1)
)
會在對應(yīng)斷點處顯示刻度蜕猫,為了防止重疊,會自動調(diào)整標(biāo)簽的放置位置哎迄,且會有連接線連接刻度和標(biāo)簽
如果標(biāo)簽不需要調(diào)整回右,則正常顯示
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.3, 1)
)
對于水平方向的圖例,設(shè)置方式類似
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
direction = "horizontal"
)
旋轉(zhuǎn)標(biāo)簽
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(0, 0.1, 0.15, 0.5, 0.9, 0.95, 1),
direction = "horizontal", labels_rot = 90,
title_position = "lefttop"
)
如果 at
參數(shù)設(shè)置為降序漱挚,則圖例也會翻轉(zhuǎn)
lgd <- Legend(
col_fun = col_fun, title = "foo",
at = c(1, 0.8, 0.6, 0.4, 0.2, 0)
)
2. 離散型圖例
離散型圖例的設(shè)置與連續(xù)型基本一致翔烁,我們主要介紹一下不同的地方
不同于連續(xù)型圖例的顏色設(shè)置,離散型用 legend_gp
參數(shù)來設(shè)置
lgd <- Legend(
at = 1:6, title = "foo",
legend_gp = gpar(fill = 1:6)
)
lgd <- Legend(
labels = month.name[1:6],
title = "foo",
legend_gp = gpar(fill = 1:6)
)
使用連續(xù)型顏色
at <- seq(0, 1, by = 0.2)
lgd <- Legend(
at = at, title = "foo",
legend_gp = gpar(fill = col_fun(at))
)
標(biāo)題位置設(shè)置與連續(xù)型圖例一樣
lgd <- Legend(
labels = month.name[1:6],
title = "foo",
legend_gp = gpar(fill = 1:6),
title_position = "lefttop",
title_gp = gpar(col = "red", fontsize = 14)
)
grid_width
和 grid_height
可以控制每個顏色矩形的大小
lgd <- Legend(
at = 1:6, legend_gp = gpar(fill = 1:6), title = "foo",
grid_height = unit(1, "cm"), grid_width = unit(5, "mm")
)
labels_gp
參數(shù)控制標(biāo)簽的圖形屬性
lgd <- Legend(
labels = month.name[1:6],
legend_gp = gpar(fill = 1:6), title = "foo",
labels_gp = gpar(col = "red", fontsize = 14)
)
使用 gt_render
函數(shù)設(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)
)
離散型圖例的一個重要特征是旨涝,可以將圖例排列為多行多列蹬屹。如果 ncol
為數(shù)值,則圖例會排列為 ncol
列
lgd <- Legend(
labels = month.name[1:10],
legend_gp = gpar(fill = 1:10),
title = "foo", ncol = 3,
title_position = "topcenter"
)
設(shè)置 by_row = TRUE
可以使圖例按行順序排列
lgd <- Legend(
labels = month.name[1:10],
legend_gp = gpar(fill = 1:10),
title = "foo", ncol = 3,
title_position = "topcenter",
by_row = TRUE
)
可以使用 gap
或 column_gap
設(shè)置兩列之間的間距
lgd <- Legend(
labels = month.name[1:10],
legend_gp = gpar(fill = 1:10),
title = "foo", ncol = 3,
title_position = "topcenter",
by_row = TRUE,
gap = unit(1, "cm")
)
row_gap
可以設(shè)置行間距
lgd <- Legend(
labels = month.name[1:10],
legend_gp = gpar(fill = 1:10),
title = "foo", ncol = 3,
row_gap = unit(5, "mm")
)
設(shè)置為一行
lgd <- Legend(
labels = month.name[1:6],
legend_gp = gpar(fill = 1:6),
title = "foooooo", nrow = 1,
title_position = "leftcenter"
)
Legend()
還支持使用簡單的圖形作為圖例,如 points
慨默、lines
贩耐、boxplots
,如果 type
設(shè)置為 points
或 p
厦取,則 pch
參數(shù)可以設(shè)置為一個字符潮太。例如
lgd <- Legend(
labels = month.name[1:6],
title = "foo", type = "points",
pch = 1:6, background = "#FF8080",
legend_gp = gpar(col = 1:6),
nrow = 1
)
設(shè)置為字母
lgd <- Legend(
labels = month.name[1:6],
title = "foo", type = "p",
pch = letters[1:6], background = "white",
legend_gp = gpar(col = 1:6),
nrow = 1
)
或者使用線條 type = "lines"/type = "l"
lgd <- Legend(
labels = month.name[1:6],
title = "foo", type = "lines",
pch = letters[1:6], background = "white",
legend_gp = gpar(col = 1:6, lty = 1:6),
nrow = 1
)
或者使用 type = "boxplot"/type = "box"
lgd <- Legend(
labels = month.name[1:6],
title = "foo", type = "boxplot",
pch = letters[1:6], background = "white",
legend_gp = gpar(fill = 1:6),
nrow = 1
)
lgd <- Legend(
labels = paste0("pch = ", 26:28),
type = "points", pch = 26:28
)
如果標(biāo)簽是多行,會自動調(diào)整圖例的高度
lgd <- Legend(
labels = c("aaaaa\naaaaa", "bbbbb\nbbbbb", "c", "d"),
legend_gp = gpar(fill = 1:4),
)
如果標(biāo)簽使多行或多列蒜胖,會根據(jù)文本長度自動調(diào)整間距
lgd <- Legend(
labels = c("aaaaa\naaaaa", "c", "d", "bbbbb\nbbbbb"),
legend_gp = gpar(fill = 1:4), nrow = 2
)
graphics
參數(shù)消别,可以為圖例設(shè)置自定義圖形抛蚤,該參數(shù)必須為一個函數(shù)列表台谢,每個函數(shù)有 4
個參數(shù)值:
-
x、y
:控制圖例格子的中心點 -
w岁经、h
:控制圖例格子的寬度和高度
graphics
的長度必須與 at
或 labels
參數(shù)的長度一致朋沮。如果 graphics
是命名列表,且與 labels
的名稱相對應(yīng)缀壤,會自動調(diào)整 graphics
的順序
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)
)
)
3. 圖例列表
要添加多個圖例樊拓,可以將每個圖例分別添加到 packLegend()
函數(shù)中,或以列表的形式傳遞塘慕。例如
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)
# 同上
# pd <- packLegend(list = list(lgd1, lgd2, lgd3))
draw(pd)
類似于單個圖例筋夏,也可以獲取圖例列表的大小
> width.Legends(pd)
[1] 19.1675555555556mm
> height.Legends(pd)
[1] 78.6988333333334mm
水平排列
pd <- packLegend(
lgd1, lgd2, lgd3,
direction = "horizontal"
)
如果圖例是豎直排列的,并且圖例的高度超過了指定值图呢,則會自動排列為多列
pd <- packLegend(
lgd1, lgd3, lgd2, lgd3, lgd2, lgd1,
max_height = unit(10, "cm"),
column_gap = unit(1, "cm")
)
column_gap
用于控制列的間距
對于水平排列的圖例条篷,也是類似的
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")
)
可以在繪制的時候,指定圖例列表的位置
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()
4. 熱圖和注釋的圖例
Heatmap()
函數(shù)的 heatmap_legend_param
參數(shù)蛤织,可以控制熱圖的圖例赴叹,例如
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"
)
)
heatmap_legend_param
接受一個列表,列表中的參數(shù)名稱與 Legend
中的參數(shù)對應(yīng)
類似地指蚜,在 HeatmapAnnotation()
函數(shù)中乞巧,也有一個 annotation_legend_param
參數(shù),用于控制注釋圖例
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)
color_bar = "discrete"
可以為連續(xù)型的顏色映射設(shè)置離散的圖例
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")))
)
5. 添加自定義圖例
只有熱圖和簡單注釋會自動添加熱圖摊鸡,復(fù)雜熱圖是沒有圖例的绽媒,例如
ha1 <- HeatmapAnnotation(
pt = anno_points(
1:10, height = unit(2, "cm"),
gp = gpar(col = rep(2:3, each = 5))),
show_annotation_name = FALSE
)
ha2 <- HeatmapAnnotation(
ln = anno_lines(
cbind(1:10, 10:1), height = unit(2, "cm"),
gp = gpar(col = 4:5, lty = 1:2)),
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)
可以在 draw
函數(shù)中使用 annotation_legend_list
參數(shù)添加自定義熱圖
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)
6. 圖例的位置
默認情況下,熱圖和注釋的圖例是放置在圖像的右邊免猾。
draw
函數(shù)的 heatmap_legend_side
和 annotation_legend_side
參數(shù)可以控制熱圖和注釋圖例的位置是辕。位置的選擇可以是 left
, right
, bottom
和 top
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")
對于放置在上面和下面的圖例,可能以水平的排列方式會更好些掸刊。
除了設(shè)置整個圖例的排列方式免糕,還要使用 annotation_legend_param
參數(shù)來設(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"
)