Adding decorate_annotation to vertical joined upset plots within ComplexHeatmap package
Solution 1:
The solution shown below is based on the command as.ggplot
of the ggplotify
package. A function plot_upset
is first defined; it draws an upset plot with decorated heatmap annotation. The plot generated by this function is converted in a ggplot
object by as.ggplot
and stored in ht_list
.
library(ComplexHeatmap)
library(patchwork)
library(ggplotify)
movies <- read.csv(system.file("extdata", "movies.csv", package = "UpSetR"),
header = TRUE, sep = ";")
genre <- c("Action", "Romance", "Horror", "Children", "SciFi", "Documentary")
rating <- cut(movies$AvgRating, c(0, 1, 2, 3, 4, 5))
m_list <- tapply(seq_len(nrow(movies)), rating, function(ind) {
m <- make_comb_mat(movies[ind, genre, drop = FALSE])
m[comb_degree(m) > 0]
})
m_list <- normalize_comb_mat(m_list)
max_set_size <- max(sapply(m_list, set_size))
plot_upset <- function(m, name, maxSetSize) {
cs = comb_size(m)
ht <- UpSet(m, row_title = paste0("rating in", name),
set_order = NULL, comb_order = NULL,
top_annotation = HeatmapAnnotation(
"Genre Intersections" = anno_barplot(cs,
ylim = c(0, max(cs)*1.1),
border = FALSE,
gp = gpar(fill = "black"),
height = unit(4, "cm")
),
annotation_name_side = "left",
annotation_name_rot = 90),
right_annotation = upset_right_annotation(m, ylim = c(0, maxSetSize)))
ht = draw(ht)
od = column_order(ht)
decorate_annotation("Genre Intersections", {
grid.text(cs[od], x = seq_along(cs), y = unit(cs[od], "native") + unit(2, "pt"),
default.units = "native", just = c("left", "bottom"),
gp = gpar(fontsize = 6, col = "#404040"), rot = 45)
})
}
ht_list <- vector(2, mode="list")
for(i in seq_along(m_list)) {
m <- m_list[[i]]
name_m <- names(m_list)[i]
dht <- as.ggplot( ~ plot_upset(m, name_m, max_set_size))
ht_list[[i]] <- dht
}
patchwork::wrap_plots(ht_list, ncol=1)
Here is the final plot (only 3 of the 5 plots are reported).