Question: Align legends to each heatmap in a ComplexHeatmap with 2 heatmaps
1
gravatar for ramrs
15 days ago by
ramrs10
ramrs10 wrote:

I have created a ComplexHeatmap containing 2 Heatmaps, each with their own legend. The legend on the first Heatmap is continuous, whereas that of the second is discrete.

When I concatenate these Heatmaps vertically, and draw the HeatmapList, their legends are auto-aligned to the center of the plot. Is there any way I can have these legends positioned centered to the respective heatmaps and not to the center of the plot?

This is what I have:

Here's what I'd like to have:

How can I go about solving this problem? I'd really like to avoid creating customized Legends if I can, but if that's what it takes, that works too.

Thank you in advance for any help/pointers!

Note: I initially created this post on Bioinformatics SE, but since this is a Bioconductor package, I feel this question belongs here.

sessionInfo:

> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: macOS  10.14.4

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Users/ram/miniconda3/lib/R/lib/libRblas.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] viridis_0.5.1        viridisLite_0.3.0    ComplexHeatmap_2.1.0 forcats_0.4.0       
 [5] stringr_1.4.0        dplyr_0.8.0.1        purrr_0.2.5          readr_1.3.1         
 [9] tidyr_0.8.3          tibble_2.1.1         ggplot2_3.1.1        tidyverse_1.2.1     

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.0          RColorBrewer_1.1-2  compiler_3.5.1      pillar_1.3.1        cellranger_1.1.0   
 [6] plyr_1.8.4          tools_3.5.1         clue_0.3-57         jsonlite_1.6        lubridate_1.7.4    
[11] gtable_0.3.0        nlme_3.1-137        lattice_0.20-38     png_0.1-7           pkgconfig_2.0.2    
[16] rlang_0.3.1         cli_1.1.0           rstudioapi_0.10     parallel_3.5.1      haven_2.1.0        
[21] gridExtra_2.3       cluster_2.0.7-1     withr_2.1.2         xml2_1.2.0          httr_1.4.0         
[26] GlobalOptions_0.1.0 generics_0.0.2      hms_0.4.2           tidyselect_0.2.5    glue_1.3.0         
[31] R6_2.3.0            GetoptLong_0.1.7    readxl_1.3.1        modelr_0.1.4        magrittr_1.5       
[36] backports_1.1.4     scales_1.0.0        assertthat_0.2.1    rvest_0.3.3         shape_1.4.4        
[41] circlize_0.4.6      colorspace_1.4-1    stringi_1.4.3       lazyeval_0.2.2      munsell_0.5.0      
[46] broom_0.5.2         rjson_0.2.20        crayon_1.3.4

Dummy data and code:

devtools::install_github('jokergoo/ComplexHeatmap');
library(ComplexHeatmap);
library(viridis);

dummy_top_mat <- structure(c(0.4563, 0.2211, 1.2235, 0.067, 1.6859, 1.0936, 0.4533, 
1.6844, 1.0039, 0.5402, 0.6841, 1.498, 1.042, 0.1711, 0.3565, 
2.2814, 3.0516, 1.5012, 0.5367, 3.0846, 1.1909, 0.235, 1.4266, 
0.4858, 2.9054, 0.3733, 0.6902, 0.8555, 0.4234, 2.6778, 0.1568, 
0.5556, 2.0172, 0.8034, 2.2897, 0.1166, 3.8033, 0.1431, 2.0606, 
1.2725, 1.5365, 0.4123, 1.2087, 1.1264, 0.8334, 1.1943, 1.58, 
1.5849, 0.3004, 0.3722, 0.0362, 0.0532, 1.4867, 0.4053, 0.3615, 
0.0897, 1.3217, 1.1447, 1.3058, 0.1903, 0.1067, 0.9482, 1.3382, 
3.2955, 0.391, 1.0418, 0.2041, 1.208, 1.5857, 3.5313, 0.472, 
1.389, 0.2143, 0.0226, 0.029, 0.444, 2.0521, 0.3955, 0.3495, 
0.5062, 1.3236, 1.3234, 0.7111, 0.1176, 2.2223, 1.2073, 0.3964, 
2.1175, 0.3382, 0.2816, 0.71, 3.1417, 0.2402, 0.5793, 0.7662, 
1.6782, 0.0986, 0.087, 0.5447, 2.6672, 1.2498, 1.0676, 1.8608, 
1.8146, 0.1422, 0.4221, 0.0303, 0.9541, 0.7358, 1.7664, 1.5144, 
0.2034, 0.9366, 0.7837, 0.3284, 0.1477, 1.8306, 1.3564, 0.1126, 
0.0171, 2.9858, 0.0233, 0.2796, 0.6995, 1.6081, 0.215, 1.7093, 
0.5178, 1.7061, 2.473, 1.8912, 0.7661, 4.4102, 1.2963, 0.6542, 
0.4281, 0.4491, 0.6, 0.4076, 1.6869, 0.4747, 3.9823, 1.1226, 
2.7355, 2.7036, 0.2241, 0.983, 1.0992, 1.4736, 0.1584, 0.2995, 
0.2272, 0.5744, 0.9314, 0.6924, 0.0812, 1.361, 0.727, 0.1525, 
1.3367, 0.566, 2.7801, 0.2349, 3.2655, 1.0675, 0.449, 0.5411, 
0.8291, 0.52, 0.0507, 0.6538, 0.4636, 1.2063, 0.9784, 0.1925, 
0.0756, 0.136, 1.2529, 0.317, 0.0281, 0.8668, 3.4138, 5.3898, 
0.521, 0.087, 3.4819, 0.1114, 0.0061, 0.9804, 1.139, 1.4159, 
1.0297, 0.6503, 1.0828, 2.3527, 0.057, 0.5602, 0.4017, 0.9985, 
0.8673), .Dim = c(10L, 20L), .Dimnames = list(c("gene01", "gene02", 
"gene03", "gene04", "gene05", "gene06", "gene07", "gene08", "gene09", 
"gene10"), c("sample01", "sample02", "sample03", "sample04", 
"sample05", "sample06", "sample07", "sample08", "sample09", "sample10", 
"sample11", "sample12", "sample13", "sample14", "sample15", "sample16", 
"sample17", "sample18", "sample19", "sample20")));

dummy_bottom_mat <- structure(c("Positive", "Positive", "Positive", "Positive", "Negative", 
"Positive", "Positive", "Positive", "Positive", "Negative", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Negative", "Positive", 
"Negative", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Negative", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Negative", "Positive", "Positive", "Positive", "Negative", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Negative", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Negative", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive", "Positive", "Positive", "Positive", "Positive", "Positive", 
"Positive"), .Dim = c(6L, 20L), .Dimnames = list(c("marker1", 
"marker2", "marker3", "marker4", "marker5", "marker6"), c("sample01", 
"sample02", "sample03", "sample04", "sample05", "sample06", "sample07", 
"sample08", "sample09", "sample10", "sample11", "sample12", "sample13", 
"sample14", "sample15", "sample16", "sample17", "sample18", "sample19", 
"sample20")));

hmap1 <- Heatmap(dummy_top_mat, col = colorRampPalette(viridis(15))(100), name = 'log2 (TPM)', na_col = 'grey60', cluster_rows = FALSE, cluster_columns = FALSE, row_names_side = 'left', column_title_side = 'top', rect_gp = gpar(col='white', lwd=0.5), height=unit(10*0.75,'cm'), width = unit(20*0.75, 'cm'), column_title = 'Gene Expression');

hmap2 <- Heatmap(dummy_bottom_mat, col = c('Negative'='red', 'Positive'='blue'), na_col = 'grey60', row_split = factor( c('gp1','gp1','gp1','gp1','gp2','gp2'), c('gp1','gp2'), ordered = TRUE), name = 'Marker\nStatus', rect_gp = gpar(col='white',lwd=1), row_title = NULL, height = unit(6*0.75,'cm'), width = unit(20*0.75, 'cm'), row_names_side = 'left', column_title = 'Biomarkers');

draw(hmap1 %v% hmap2, ht_gap = unit(1, 'cm'), auto_adjust = FALSE);
R complexheatmap • 108 views
ADD COMMENTlink modified 13 days ago by Zuguang Gu70 • written 15 days ago by ramrs10
Answer: Align legends to each heatmap in a ComplexHeatmap with 2 heatmaps
2
gravatar for Zuguang Gu
13 days ago by
Zuguang Gu70
Germany
Zuguang Gu70 wrote:

No, since you put the two heatmaps as one plot, the legends are grouped.

You can either edit in Inkscape or make two heatmaps in two plots. You can get the column of the first heatmap by:

hmap1 = draw(hmap1)
column_order = column_order(hmap1)

and assign to the second heatmap:

Heatmap(..., column_order = column_order)

To make the size of single rows identical for the two heatmaps if you save into two PDF files, you can adjust the height of the PDF files according to following link:

https://jokergoo.github.io/ComplexHeatmap-reference/book/other-tricks.html#set-the-same-cell-size-for-different-heatmaps-with-different-dimensions

ADD COMMENTlink written 13 days ago by Zuguang Gu70

I do use the column_order to unify column order as I'm using auto_adjust = FALSE in the draw(). I also already predicate the height/width of the png output using the number of rows and columns respectively in hmap1.

I need to automate this logic so it can work for any number of rows What you're telling me is to do this:

png(...)
hmp1 <- draw(hmp1, ...)
hmp2 <- Heatmap(..., column_order = column_order(hmp1))
draw(hmp2, x = unit(0, 'npc'), y = <calculated height of hmp1 + ht_gap>)
dev.off()

instead of using hmp1 %v% hmp2?

EDIT: Tried this, it won't work as draw for Heatmap class does not accept x= and y= parameters. How can I automate this?

ADD REPLYlink modified 12 days ago • written 12 days ago by ramrs10
1

OK, I see. You want to put the two heatmaps together so that you can compare directly between the two heatmaps. The thing is if you add two heatmaps, the legends are always plotted together. One way I can think to improve this is to move the legends to the bottom of the heatmap:


hmap1 <- Heatmap(dummy_top_mat, col = colorRampPalette(viridis(15))(100), name = 'log2 (TPM)', na_col = 'grey60', cluster_rows = FALSE, cluster_columns = FALSE, row_names_side = 'left', column_title_side = 'top', rect_gp = gpar(col='white', lwd=0.5), height=unit(10*0.5,'cm'), width = unit(20*0.5, 'cm'), column_title = 'Gene Expression',
    show_column_names = FALSE, heatmap_legend_param = list(direction = "horizontal"));

hmap2 <- Heatmap(dummy_bottom_mat, col = c('Negative'='red', 'Positive'='blue'), na_col = 'grey60', row_split = factor( c('gp1','gp1','gp1','gp1','gp2','gp2'), c('gp1','gp2'), ordered = TRUE), name = 'Marker\nStatus', rect_gp = gpar(col='white',lwd=1), row_title = NULL, height = unit(6*0.5,'cm'), width = unit(20*0.5, 'cm'), row_names_side = 'left', column_title = 'Biomarkers',
    heatmap_legend_param = list(direction = "horizontal", nrow = 1, title = "Marker Status"));

draw(hmap1 %v% hmap2, auto_adjust = FALSE,
    heatmap_legend_side = "bottom");

enter image description here

ADD REPLYlink written 12 days ago by Zuguang Gu70
Please log in to add an answer.

Help
Access

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.
Powered by Biostar version 16.09
Traffic: 129 users visited in the last hour