Author: Zuguang Gu ( [email protected] )
Date: 2018-06-19
The legends for heatmaps are composed with a color bar, labels and titles. ComplexHeatmap automatically generates legends according to the input matrix and annotations, while also provide flexibility to customize and add new legends.
Legends for all heatmaps and row annotations are drawn together and legends for all column annotations are drawn together. The legends for heatmaps and legends for annotations are put in independent viewports.
library(ComplexHeatmap)
library(circlize)
set.seed(123)
mat = matrix(rnorm(80, 2), 8, 10)
mat = rbind(mat, matrix(rnorm(40, -2), 4, 10))
rownames(mat) = paste0("R", 1:12)
colnames(mat) = paste0("C", 1:10)
ha_column = HeatmapAnnotation(df = data.frame(type1 = c(rep("a", 5), rep("b", 5))),
col = list(type1 = c("a" = "red", "b" = "blue")))
ha_row = rowAnnotation(df = data.frame(type2 = c(rep("A", 6), rep("B", 6))),
col = list(type2 = c("A" = "green", "B" = "orange")), width = unit(1, "cm"))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha_column)
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2")
ht_list = ht1 + ht2 + ha_row
draw(ht_list)
Side of legends can be set by heatmap_legend_side
and annotation_legend_side
.
draw(ht_list, heatmap_legend_side = "left", annotation_legend_side = "bottom")
show_heatmap_legend
and show_annotation_legend
set visibility of legends.
draw(ht_list, show_heatmap_legend = FALSE, show_annotation_legend = FALSE)
You can choose to only show some of the heatmap legends by setting show_heatmap_legend
to
a logical value when constructing single heatmaps.
Also HeatmapAnnotation()
(or the shortcut function columnAnnotation()
and rowAnnotation()
) provides
show_legend
argument to control visibility of annotation legends.
ha_column = HeatmapAnnotation(df = data.frame(type1 = c(rep("a", 5), rep("b", 5))),
col = list(type1 = c("a" = "red", "b" = "blue")), show_legend = FALSE)
ha_row = rowAnnotation(df = data.frame(type2 = c(rep("A", 6), rep("B", 6))),
col = list(type2 = c("A" = "green", "B" = "orange")), show_legend = FALSE, width = unit(1, "cm"))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha_column)
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2", show_heatmap_legend = FALSE)
ht1 + ht2 + ha_row
Legend itself can be flexibly customized. Parameters for making the legend can be set by heatmap_legend_param
(for heatmap) or annotation_legend_param
(for annotations).
The parameters that can be set are as follows:
title
: title of the legendtitle_gp
: graphic parameters for the legend titletitle_position
: position of title relative to the legend, possible values are topcenter
, topleft
, leftcenter
, lefttop
.color_bar
: style of the color bar, i.e. continuous or discretegrid_height
: height of the small grid in the color bar, only works for discrete color bargrid_width
: width of the color bargrid_border
: border of the color barat
: break values shown on the legendlabels
: labels which correspond to the breaks valueslabels_gp
: graphic parameters for legend labelsnrow
and ncol
: if there are too many legends, they can be put into an array. These two parameters controls number of rows or columnslegend_direction
: Controls the direction of the legend, possible values are vertical
and horizontal
. Works for both continuous
and discrete
legend_width
and legend_height
: when color_bar
is continuous
, the width or height of the legendFollowing example changes the default graphic parameters for labels and titles:
df = data.frame(type = c(rep("a", 5), rep("b", 5)))
ha = HeatmapAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
annotation_legend_param = list(type = list(title = "TYPE", title_gp = gpar(fontsize = 14),
labels_gp = gpar(fontsize = 8))))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha)
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2",
heatmap_legend_param = list(title = "Heatmap2", title_gp = gpar(fontsize = 8),
labels_gp = gpar(fontsize = 14)))
ht1 + ht2
You can specify break values and break labels (both for character values and numeric values) by at
and labels
in corresponding heatmap_legend_param
and annotation_legend_param
. Note at
can also be character break values.
ha = HeatmapAnnotation(df = df, col = list(type = c("a" = "red", "b" = "blue")),
annotation_legend_param = list(type = list(title = "TYPE", title_gp = gpar(fontsize = 14),
labels_gp = gpar(fontsize = 8), at = c("a", "b"), labels = c("A", "B"))))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha,
heatmap_legend_param = list(at = c(-3, 0, 3), labels = c("-three", "zero", "+three")))
ht1 + ht2
If you have many levels in your annotation or matrix, you can put all levels into an array by specifying
nrow
or ncol
:
ha_chr = rowAnnotation(chr = sample(paste0("chr", 1:20), nrow(mat), replace = TRUE),
annotation_legend_param = list(chr = list(ncol = 2, title = "chromosome", title_position = "topcenter")),
width = unit(5, "mm"))
ht1 = Heatmap(mat, name = "ht1")
ht1 + ha_chr
Or put at bottom of the heatmap:
ha_chr = rowAnnotation(chr = sample(paste0("chr", 1:20), nrow(mat), replace = TRUE),
annotation_legend_param = list(chr = list(nrow = 2, title = "chr", title_position = "leftcenter")),
width = unit(5, "mm"))
ht1 = Heatmap(mat, name = "ht1", show_heatmap_legend = FALSE)
draw(ht1 + ha_chr, heatmap_legend_side = "bottom")
If you want to order a discrete legend by column instead of row, use the direction argument:
ha_chr = rowAnnotation(chr = sample(paste0("chr", 1:20), nrow(mat), replace = TRUE),
annotation_legend_param = list(chr = list(nrow = 2, title = "chr", title_position = "leftcenter", legend_direction = "vertical")),
width = unit(5, "mm"))
ht1 = Heatmap(mat, name = "ht1", show_heatmap_legend = FALSE)
draw(ht1 + ha_chr, heatmap_legend_side = "bottom")
Discrete color bar for can be used for continuous values, if you specify color_bar
to discrete
.
For the simple annotation which contains continuous values, color_bar
can also be set to discrete
.
ha = HeatmapAnnotation(df = data.frame(value = runif(10)),
col = list(value = colorRamp2(c(0, 1), c("white", "blue"))),
annotation_legend_param = list(color_bar = "discrete", at = c(0, 0.5, 1)))
Heatmap(mat, name = "ht1", top_annotation = ha, heatmap_legend_param = list(color_bar = "discrete"))
Some users prefer to put the legend at the bottom of heatmaps.
ht = Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_direction = "horizontal",
legend_width = unit(5, "cm"), title_position = "lefttop"))
draw(ht, heatmap_legend_side = "bottom")
Similarly, the height of the legend can be adjusted by legend_height
if the legend is vertical.
Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_height = unit(5, "cm")))
If you want to change default settings for all heatmaps/annotations, you can set it globally by ht_global_opt()
.
ht_global_opt(heatmap_legend_title_gp = gpar(fontsize = 16), annotation_legend_labels_gp = gpar(fontface = "italic"))
ha = HeatmapAnnotation(df = data.frame(value = runif(10)),
col = list(value = colorRamp2(c(0, 1), c("white", "blue"))))
ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha)
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2", heatmap_legend_param = list(title_gp = gpar(fontsize = 8)))
ht1 + ht2
ht_global_opt(RESET = TRUE)
ComplexHeatmap only generates legends for heatmaps and simple annotations. Self-defined legends
can be passed by heatmap_legend_list
and annotation_legend_list
as a list of grob
objects.
grid package provides legendGrob()
to construct a legend grob with certain style but
styles are still limited. For advanced users, they can construct a legend grob totally from ground by frameGrob()
and placeGrob()
.
ha = HeatmapAnnotation(points = anno_points(rnorm(10)))
ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2", top_annotation = ha, show_heatmap_legend = FALSE)
lgd = legendGrob(c("dots"), pch = 16)
draw(ht1 + ht2, annotation_legend_list = list(lgd))
From version 1.9.7, ComplexHeatmap package provides a Legend()
function which can produce legends in grob
formats
(actually all legends in the package are implemented by Legend()
function).
In following example, we have several column annotations which contains points and we also want to show legends
for these non-heatmap graphics.
ha = HeatmapAnnotation(points = anno_points(rnorm(10), gp = gpar(col = rep(2:3, each = 5))))
ht = Heatmap(mat, name = "ht2", column_title = "Heatmap 2", top_annotation = ha)
lgd = Legend(at = c("class1", "class2"), title = "points", type = "points", legend_gp = gpar(col = 2:3))
draw(ht, annotation_legend_list = list(lgd))
Also check this blog link for more demonstrations.
sessionInfo()
## R version 3.5.0 (2018-04-23)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.4 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.7-bioc/R/lib/libRblas.so
## LAPACK: /home/biocbuild/bbs-3.7-bioc/R/lib/libRlapack.so
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
## [4] LC_COLLATE=C LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] stats4 parallel grid stats graphics grDevices utils datasets methods
## [10] base
##
## other attached packages:
## [1] dendextend_1.8.0 dendsort_0.3.3 cluster_2.0.7-1 HilbertCurve_1.10.1
## [5] GenomicRanges_1.32.3 GenomeInfoDb_1.16.0 IRanges_2.14.10 S4Vectors_0.18.3
## [9] BiocGenerics_0.26.0 circlize_0.4.4 ComplexHeatmap_1.18.1 knitr_1.20
## [13] markdown_0.8
##
## loaded via a namespace (and not attached):
## [1] fastcluster_1.1.25 shape_1.4.4 modeltools_0.2-21 GetoptLong_0.1.7
## [5] kernlab_0.9-26 lattice_0.20-35 colorspace_1.3-2 viridisLite_0.3.0
## [9] rlang_0.2.1 pillar_1.2.3 prabclus_2.2-6 RColorBrewer_1.1-2
## [13] fpc_2.1-11 GenomeInfoDbData_1.1.0 plyr_1.8.4 robustbase_0.93-0
## [17] stringr_1.3.1 zlibbioc_1.26.0 munsell_0.5.0 gtable_0.2.0
## [21] GlobalOptions_0.1.0 mvtnorm_1.0-8 evaluate_0.10.1 flexmix_2.3-14
## [25] class_7.3-14 highr_0.7 DEoptimR_1.0-8 trimcluster_0.1-2
## [29] Rcpp_0.12.17 scales_0.5.0 diptest_0.75-7 XVector_0.20.0
## [33] mime_0.5 gridExtra_2.3 rjson_0.2.20 ggplot2_2.2.1
## [37] png_0.1-7 stringi_1.2.3 tools_3.5.0 HilbertVis_1.38.0
## [41] bitops_1.0-6 magrittr_1.5 RCurl_1.95-4.10 lazyeval_0.2.1
## [45] tibble_1.4.2 whisker_0.3-2 MASS_7.3-50 viridis_0.5.1
## [49] mclust_5.4 nnet_7.3-12 compiler_3.5.0