Skip to content

Feature suggestion: column annotations #3

@tomsing1

Description

@tomsing1

Great R package, @DillonHammill, thank you so much for making it available. As a computational biologist, I often need to show which experimental groups a sample (usually a column of the heatmap) comes from. Often, there are multiple relevant experimental properties, e.g. sex and treatment, for example.

I don't think adding such annotation columns is currently supported by HeatmapR (but perhaps I overlooked it?). Perhaps you might consider adding this feature in a future release.

To illustrate what I mean, here is an example generate with the ComplexHeatmap Bioconductor package:

library(ComplexHeatmap)
library(circlize)          # 

<img width="1282" height="1166" alt="Image" src="https://github.com/user-attachments/assets/afff87a5-59a5-4d0e-b1f9-9c97dd2e85b6" />

colorRamp2()
set.seed(123)

n_genes   <- 20
n_samples <- 24

mat <- matrix(
  rnorm(n_genes * n_samples, mean = 0, sd = 1.5),
  nrow = n_genes,
  ncol = n_samples,
  dimnames = list(
    paste0("Gene_", seq_len(n_genes)),
    paste0("S", sprintf("%02d", seq_len(n_samples)))
  )
)

treatment <- factor(
  rep(c("Control", "Drug_A", "Drug_B"), each = 8),
  levels = c("Control", "Drug_A", "Drug_B")
)

sex <- factor(
  rep(c("Male", "Female"), times = n_samples / 2),
  levels = c("Male", "Female")
)

treatment_colors <- c(
  Control = "#4E9FD1",   # steel blue
  Drug_A  = "#E07B54",   # terracotta
  Drug_B  = "#6DBF7E"    # sage green
)

sex_colors <- c(
  Male   = "#7B5EA7",    # purple
  Female = "#E8A0BF"     # blush pink
)

col_anno <- HeatmapAnnotation(
  Treatment = treatment,
  Sex = sex,
  col = list(
    Treatment = treatment_colors,
    Sex       = sex_colors
  ),
  annotation_legend_param = list(
    Treatment = list(title = "Treatment",  nrow = 1),
    Sex       = list(title = "Sex",        nrow = 1)
  ),
  annotation_height = unit(c(5, 5), "mm"),
  border = TRUE,
  annotation_name_gp = gpar(fontsize = 9, fontface = "bold"),
  annotation_name_side = "left"   # label appears on the left
)

body_colors <- colorRamp2(
  c(-3, 0, 3),
  c("#2C7BB6", "white", "#D7191C")   # blue → white → red
)

ht <- Heatmap(
  mat,
  name                  = "z-score",        # legend title
  
  top_annotation        = col_anno,          # placed ABOVE the matrix
  col                   = body_colors,
  cluster_columns       = TRUE,              
  column_split          = treatment,         # visually split by group
  column_gap            = unit(2, "mm"),     
  cluster_rows          = TRUE,
  show_row_names        = TRUE,
  row_names_gp          = gpar(fontsize = 8),
  show_column_names     = TRUE,
  column_names_gp       = gpar(fontsize = 7),
  column_names_rot      = 45,
 column_title          = c("Control", "Drug A", "Drug B"),
  column_title_gp       = gpar(fontsize = 10, fontface = "bold"),
  heatmap_legend_param  = list(
    title          = "z-score",
    legend_direction = "horizontal",
    title_position = "topcenter"
  )
)

draw(
  ht,
  merge_legend           = TRUE,
  heatmap_legend_side    = "bottom",
  annotation_legend_side = "bottom"
)
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions