Search code examples
rplotlegendheatmapcomplexheatmap

ComplexHeatmap: How to place heatmap legend and annotation legend differently?


I have produced this plot with library(ComplexHeatmap)

enter image description here

I want the Z-score at the bottom-position while the categorial variables shown on the right side. This post came close, but I cannot get it to work using rowAnnotation as in the script below.

Expected output

enter image description here

With these data:

set.seed(123)
library(ComplexHeatmap)
mat = matrix(rnorm(96, 2), 8, 12)
mat = rbind(mat, matrix(rnorm(48, -2), 4, 12))
hmap <- as.data.frame(t(mat))

hmap$type <- rep(c("Ctrl", "Cell_type1", "Cell_type2"), 4)
hmap$malig <- ifelse(hmap$type == "Ctrl", "Ctrl", "Tumor")

hmap_bt <- scale(as.matrix(hmap[, -c(13:14)]))

And using this script

draw(Heatmap(hmap_bt, 
             name = "Z-score",    
             col = colorRamp2(c(-2, 0, 2), c("#6DBCC3", "white", "#8B3A62")),

             show_column_names = FALSE,
             show_column_dend = FALSE,
             column_km = 3,
             
             left_annotation = rowAnnotation(Case = hmap[, c(13:14)]$malig,
                                             Type = hmap[, c(13:14)]$type,
                                             col = list(Case = c("Ctrl" = "#D1B551", "Tumor" = "#678F53"),
                                                        Type = c("Ctrl" = "#D1B551", "Cell_type1" = "green", "Cell_type2" = "blue")),
                                             annotation_legend_param = list(
                                               Case = list( 
                                                 title_gp = gpar(fontsize = 16, 
                                                                 fontface = "bold"), 
                                                 labels_gp = gpar(fontsize = 16)),
                                               Type = list( 
                                                 title_gp = gpar(fontsize = 16,
                                                                 fontface = "bold"), 
                                                 labels_gp = gpar(fontsize = 16)))),
             heatmap_legend_param = list(
               legend_direction = "horizontal", 
               legend_width = unit(6, "cm")), 
    ),

  heatmap_legend_side = "bottom"
)

Solution

  • Try using the option legend_grouping = "original" of the draw command.

    library(ComplexHeatmap)
    library(circlize)
    
    set.seed(123)
    mat = matrix(rnorm(96, 2), 8, 12)
    mat = rbind(mat, matrix(rnorm(48, -2), 4, 12))
    hmap <- as.data.frame(t(mat))
    
    hmap$type <- rep(c("Ctrl", "Cell_type1", "Cell_type2"), 4)
    hmap$malig <- ifelse(hmap$type == "Ctrl", "Ctrl", "Tumor")
    
    hmap_bt <- scale(as.matrix(hmap[, -c(13:14)]))
    And using this script
    
    df <- data.frame(Case = hmap[, c(13:14)]$malig,
                     Type = hmap[, c(13:14)]$type)
    
    annot <-  rowAnnotation(
      df = data.frame(Case = hmap[, c(13:14)]$malig,
                      Type = hmap[, c(13:14)]$type),
      col = list(Case = c("Ctrl" = "#D1B551", "Tumor" = "#678F53"),
                 Type = c("Ctrl" = "#D1B551", "Cell_type1" = "green", 
                          "Cell_type2" = "blue")),
      annotation_legend_param = list(
        Case = list( 
          title_gp = gpar(fontsize = 16, 
                          fontface = "bold"), 
          labels_gp = gpar(fontsize = 16)),
        Type = list( 
          title_gp = gpar(fontsize = 16,
                          fontface = "bold"), 
          labels_gp = gpar(fontsize = 16)))
    )
    
    htmp <- Heatmap(
      hmap_bt, 
      name = "Z-score",    
      col = colorRamp2(c(-2, 0, 2), c("#6DBCC3", "white", "#8B3A62")),
      
      show_column_names = FALSE,
      show_column_dend = FALSE,
      column_km = 3,
      
      left_annotation = annot,
      heatmap_legend_param = list(
        legend_direction = "horizontal", 
        legend_width = unit(6, "cm")), 
    )
    
    draw(htmp, heatmap_legend_side="bottom", annotation_legend_side="right",
               legend_grouping = "original")
    

    enter image description here