vignettes_old/s5.legend.Rmd
5ab2cb81
 <!--
 %\VignetteEngine{knitr}
12e85497
 %\VignetteIndexEntry{5. Heatmap and Annotation Legends}
5ab2cb81
 -->
 
 Heatmap and Annotation Legends
 ========================================
 
 **Author**: Zuguang Gu ( z.gu@dkfz.de )
 
 **Date**: `r Sys.Date()`
 
 -------------------------------------------------------------
 
 ```{r global_settings, echo = FALSE, message = FALSE}
 library(markdown)
 options(markdown.HTML.options = c(options('markdown.HTML.options')[[1]], "toc"))
 
 library(knitr)
 knitr::opts_chunk$set(
     error = FALSE,
     tidy  = FALSE,
     message = FALSE,
     fig.align = "center",
     fig.width = 5,
     fig.height = 5)
 options(markdown.HTML.stylesheet = "custom.css")
 
 options(width = 100)
 ```
 
c9d5db63
 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.
 
 
 ## Basic settings
 
8f3d6c1e
 Legends for all heatmaps and row annotations are drawn together and legends for all column annotations are drawn together.
5ab2cb81
 The legends for heatmaps and legends for annotations are put in independent viewports.
 
 ```{r legend_default, fig.width = 8, fig.keep = "all"}
 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)
 
8f3d6c1e
 ha_column = HeatmapAnnotation(df = data.frame(type1 = c(rep("a", 5), rep("b", 5))),
5ab2cb81
     col = list(type1 = c("a" =  "red", "b" = "blue")))
8f3d6c1e
 ha_row = rowAnnotation(df = data.frame(type2 = c(rep("A", 6), rep("B", 6))),
5ab2cb81
     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`.
 
 ```{r legend_side, fig.width = 8, fig.keep = "all"}
 draw(ht_list, heatmap_legend_side = "left", annotation_legend_side = "bottom")
 ```
 
 `show_heatmap_legend` and `show_annotation_legend` set visibility of legends.
 
 
 ```{r legend_show, fig.width = 8, fig.keep = "all"}
 draw(ht_list, show_heatmap_legend = FALSE, show_annotation_legend = FALSE)
 ```
 
8f3d6c1e
 You can choose to only show some of the heatmap legends by setting `show_heatmap_legend` to
ac4a2fca
 a logical value when constructing single heatmaps.
5ab2cb81
 Also `HeatmapAnnotation()` (or the shortcut function `columnAnnotation()` and `rowAnnotation()`) provides
 `show_legend` argument to control visibility of annotation legends.
 
 ```{r legend_show_part, fig.width = 10}
8f3d6c1e
 ha_column = HeatmapAnnotation(df = data.frame(type1 = c(rep("a", 5), rep("b", 5))),
ac4a2fca
     col = list(type1 = c("a" =  "red", "b" = "blue")), show_legend = FALSE)
8f3d6c1e
 ha_row = rowAnnotation(df = data.frame(type2 = c(rep("A", 6), rep("B", 6))),
ac4a2fca
     col = list(type2 = c("A" =  "green", "B" = "orange")), show_legend = FALSE, width = unit(1, "cm"))
5ab2cb81
 
 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
 ```
 
c9d5db63
 ## Customization of legends
5ab2cb81
 
8f3d6c1e
 Legend itself can be flexibly customized. Parameters for making the legend can be set by `heatmap_legend_param`
c9d5db63
 (for heatmap) or `annotation_legend_param` (for annotations).
5ab2cb81
 The parameters that can be set are as follows:
 
 - `title`: title of the legend
 - `title_gp`: graphic parameters for the legend title
c9d5db63
 - `title_position`: position of title relative to the legend, possible values are `topcenter`, `topleft`, `leftcenter`, `lefttop`.
5ab2cb81
 - `color_bar`: style of the color bar, i.e. continuous or discrete
 - `grid_height`: height of the small grid in the color bar, only works for discrete color bar
 - `grid_width`: width of the color bar
 - `grid_border`: border of the color bar
 - `at`: break values shown on the legend
 - `labels`: labels which correspond to the breaks values
 - `labels_gp`: graphic parameters for legend labels
c9d5db63
 - `nrow` and `ncol`: if there are too many legends, they can be put into an array. These two parameters controls number of rows or columns
8f3d6c1e
 - `legend_direction`: Controls the direction of the legend, possible values are `vertical` and `horizontal`. Works for both `continuous` and `discrete`
c9d5db63
 - `legend_width` and `legend_height`: when `color_bar` is `continuous`, the width or height of the legend
 
 
 Following example changes the default graphic parameters for labels and titles:
5ab2cb81
 
 ```{r heatmap_list_advanced, fig.width = 10}
 df = data.frame(type = c(rep("a", 5), rep("b", 5)))
 ha = HeatmapAnnotation(df = df, col = list(type = c("a" =  "red", "b" = "blue")),
8f3d6c1e
     annotation_legend_param = list(type = list(title = "TYPE", title_gp = gpar(fontsize = 14),
5ab2cb81
                                                labels_gp = gpar(fontsize = 8))))
 ht1 = Heatmap(mat, name = "ht1", column_title = "Heatmap 1", top_annotation = ha)
8f3d6c1e
 ht2 = Heatmap(mat, name = "ht2", column_title = "Heatmap 2",
     heatmap_legend_param = list(title = "Heatmap2", title_gp = gpar(fontsize = 8),
f6325167
         labels_gp = gpar(fontsize = 14)))
5ab2cb81
 ht1 + ht2
 ```
 
8f3d6c1e
 You can specify break values and break labels (both for character values and numeric values) by `at` and `labels`
c9d5db63
 in corresponding `heatmap_legend_param` and `annotation_legend_param`. Note `at` can also be character break values.
5ab2cb81
 
 ```{r self_define_heatmap_legend, fig.width = 10}
 ha = HeatmapAnnotation(df = df, col = list(type = c("a" =  "red", "b" = "blue")),
8f3d6c1e
     annotation_legend_param = list(type = list(title = "TYPE", title_gp = gpar(fontsize = 14),
5ab2cb81
         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
 ```
 
c9d5db63
 If you have many levels in your annotation or matrix, you can put all levels into an array by specifying
 `nrow` or `ncol`:
 
 ```{r, fig.width = 6}
 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
 ```
 
f6325167
 Or put at bottom of the heatmap:
 
 ```{r, fig.width = 6}
 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")
 ```
8f3d6c1e
 If you want to order a discrete legend by column instead of row, use the direction argument:
 
 ```{r, fig.width = 6}
 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")
4b1d2fb5
 ```
f6325167
 
0623db7b
 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`.
5ab2cb81
 
 ```{r}
8f3d6c1e
 ha = HeatmapAnnotation(df = data.frame(value = runif(10)),
     col = list(value = colorRamp2(c(0, 1), c("white", "blue"))),
0623db7b
     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"))
5ab2cb81
 ```
 
c9d5db63
 Some users prefer to put the legend at the bottom of heatmaps.
 
 ```{r}
0623db7b
 ht = Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_direction = "horizontal",
c9d5db63
     legend_width = unit(5, "cm"), title_position = "lefttop"))
 draw(ht, heatmap_legend_side = "bottom")
 ```
 
0623db7b
 Similarly, the height of the legend can be adjusted by `legend_height` if the legend is vertical.
 
 ```{r}
 Heatmap(mat, name = "ht1", heatmap_legend_param = list(legend_height = unit(5, "cm")))
 ```
 
5ab2cb81
 If you want to change default settings for all heatmaps/annotations, you can set it globally by `ht_global_opt()`.
 
 ```{r, fig.width = 10}
 ht_global_opt(heatmap_legend_title_gp = gpar(fontsize = 16), annotation_legend_labels_gp = gpar(fontface = "italic"))
8f3d6c1e
 ha = HeatmapAnnotation(df = data.frame(value = runif(10)),
0623db7b
     col = list(value = colorRamp2(c(0, 1), c("white", "blue"))))
5ab2cb81
 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)
 ```
 
c9d5db63
 ## Add new legends
 
 **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()`.
 
 ```{r self_defined_annotation_legend, fig.width = 10}
 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.
 
 ```{r}
 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))
 ```
 
f6325167
 Also check [this blog link](http://zuguang.de/blog/html/dde69a9cf5a606a9486b19eb91ba6f4e.html) for more demonstrations.
 
5ab2cb81
 ## Session info
 
 ```{r}
 sessionInfo()
 ```