jokergoo / ComplexHeatmap

Make Complex Heatmaps
https://jokergoo.github.io/ComplexHeatmap-reference/book/
Other
1.29k stars 224 forks source link

Keep colors consistent throughout a list of heatmaps, add colored annotation bar #504

Closed KH4-97 closed 3 years ago

KH4-97 commented 4 years ago

Background

I'm currently trying to build a heatmap which shows the host ranges of 57 viruses against 41 hosts. The data frame (shown below) contains NAs, 0s, and 1s; each of which I'd like to assign a specific color to.

Heatmap-matrix

To organize the heatmap, I decided to group the hosts (rows) by genus. I then created a heatmap from each of these groups and vertically concatenated the heatmaps into a list.

The code I used and the heatmap output can be found using the link at the bottom.

Issues

  1. I've been having trouble assigning colors to: NA, 0, and 1 so that the colors remain consistent throughout all of the concatenated heatmaps.
  2. I'd also like to add an annotation color bar to the left axis which clearly distinguishes each host group from one another.
  3. I would also like to create a compact legend for this annotation color bar.
  4. Similarly, I'd also like to add some type of separation between groups of viruses on the bottom axis (which would allow for me to minimize the text on the bottom axis) The bottom axis separators could be vertical grid lines or another color bar.

Thanks!

Link to code

file:///Users/kona/Desktop/Hostrange-complex-heatmap-6.5.20.nb.html

jokergoo commented 4 years ago

Hi, I cannot access the file you attached.

For your case, I think you can construct a category variable genus and split the heatmap rows by this variable:

Heatmap(mat, row_split = genus)

The color can be set as e.g.:

Heatmap(..., na_col = "grey", col = c("0" = "Red", "1" = "blue"))
KH4-97 commented 4 years ago

Hi, I cannot access the file you attached.

For your case, I think you can construct a category variable genus and split the heatmap rows by this variable:

Heatmap(mat, row_split = genus)

The color can be set as e.g.:

Heatmap(..., na_col = "grey", col = c("0" = "Red", "1" = "blue"))

After trying this, I get the error message:

Error: Length or nrow of row_split should be same as nrow of matrix.

And my apologies, here's the code I used

HRdat <- read_excel("/Volumes/GoogleDrive/My Drive/M.S Research/Summer 2020 Research/Phage-Host Systems-2/PH_Host_Ranges-5.26.20.xlsx", 
    sheet = "Sheet1", n_max = 42)
Abau <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Acinetobacter baumannii', ])
Bcer <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Bacillus cereus', ])
Bjap <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Bradyrhizobium japonicum', ])
Ecol <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Escherichia coli', ])
Ldel <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Lactobacillus delbrueckii', ])
Lpla <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Lactobacillus plantarum', ])
Paer <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Pseudomonas aeruginosa', ])
Pflu <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Pseudomonas fluorescens', ])
Rvic <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Rhizobium leguminosarum bv. viciae', ])
Rleg <- as.matrix(HRdat[HRdat[, "Host_sp"] == 'Rhizobium leguminosarum', ])
leftovers <- HRdat %>% slice(11, 14, 18, 22, 23, 33, 34, 35, 36, 37, 38, 39, 40, 41) # Host species groups with only one individual
# Heatmap cell colors
colors = structure(1:3, names = c("No data", "Resistant", "Susceptible"))

# colornorm = colorRamp2(c(0, 1, 2, 3), c("gray62", "peachpuff1", "tomato", "tomato4"))

# Legend colors
col_letters = c("a" = "pink", "b" = "purple", "c" = "blue")
# Each host species is assigned to one heatmap (with the exception of 'ht11')

ht1 = Heatmap(
  Abau,
  name = "A. baumannii",
  cluster_rows = FALSE,
  row_km = 10,
  row_split = "Host_sp",
  width = unit(15, "cm"),
  height = unit(5.59, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht2 = Heatmap(
  Bcer,
  name = "B. cereus",
  cluster_rows = FALSE,
  height = unit(3.75, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht3 = Heatmap(
  Bjap,
  name = "B. japonicum",
  cluster_rows = FALSE,
  height = unit(5.59, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht4 = Heatmap(
  Ecol,
  name = "E. coli",
  cluster_rows = FALSE,
  height = unit(3.75, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht5 = Heatmap(
  Ldel,
  name = "L. delbrueckii",
  cluster_rows = FALSE,
  height = unit(5.59, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht6 = Heatmap(
  Lpla,
  name = "L. plantarum",
  cluster_rows = FALSE,
  height = unit(5.59, "mm"),
  column_names_gp = gpar(fontsize = 5.0),
  row_title = "Hosts",
  row_title_gp = gpar(fontsize = 12))

ht7 = Heatmap(
  Paer,
  name = "P. aeruginosa",
  cluster_rows = FALSE,
  height = unit(3.75, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht8 = Heatmap(
  Pflu,
  name = "P. fluorescens",
  cluster_rows = FALSE,
  height = unit(3.75, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht9 = Heatmap(
  Rvic,
  name = "R. leguminosarum viciae",
  cluster_rows = FALSE,
  height = unit(5.59, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht10 = Heatmap(
  Rleg,
  name = "R. leguminosarum",
  cluster_rows = FALSE,
  height = unit(3.75, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

ht11 = Heatmap(
  as.matrix(leftovers),
  name = "Leftovers",
  cluster_rows = FALSE,
  height = unit(20.9, "mm"),
  column_names_gp = gpar(fontsize = 5.0))

# Vertical concatenation of heatmaps
ht_list = ht1 %v% ht2 %v% ht3 %v% ht4 %v% ht5 %v% ht6 %v% ht7 %v% ht8 %v% ht9 %v% ht10 %v% ht11
htmpbody <- draw(ht_list, show_heatmap_legend = FALSE, gap = unit(0.45, "mm"), 
                 heatmap_legend_side = "left", column_title = "Phages",
                 column_title_gp = gpar(fontsize = 12),
                 column_title_side = c("bottom"))
jokergoo commented 4 years ago

How about this code:

split = HRdat[, "Host_sp"]
split[!split %in% c('Acinetobacter baumannii', 'Bacillus cereus', 'Bradyrhizobium japonicum',
    'Escherichia coli', 'Lactobacillus delbrueckii', 'Lactobacillus plantarum',
    'Pseudomonas aeruginosa', 'Pseudomonas fluorescens', 'Rhizobium leguminosarum bv. viciae',
    'Rhizobium leguminosarum')] = "others"

Heatmap(HRdat, row_split = split, na_col = 1, col = c("1" = 2, "2" = 3))