I have a list with multiple gene sets, let's say:
genes <- paste("gene",1:1000,sep="")
x <- list(A = sample(genes,300),
B = sample(genes,525),
C = sample(genes,440),
D = sample(genes,350))
I managed to get a pairwise (2 first columns, A vs B) Venn/euler diagram:
library(eulerr)
plot(euler(x[1:2]), quantities = TRUE)
Any idea how I can get automated pairwise 2-by-2 Venn/euler Diagram of all these gene sets?
ie: A vs B, A vs C, A vs D, B vs C, B vs D, C vs D.
In reality I have 70+ geneset that I want to compare to each other, then build a sort of matrix which would look like this:
Thanks !
It's fairly involved, but you can get Venns for all pairs using combn
, and strip the data out to create a facetted ggplot:
library(eulerr)
library(tidyverse)
venns <- combn(length(x), 2, FUN = function(i) {
res <- plot(euler(x[i]), quantities = TRUE)
res$col_vals <- names(x)[i]
res }, simplify = FALSE)
plot_df <- do.call("rbind", lapply(venns, function(e) {
do.call("rbind", Map(\(a, b, c, d) {
data.frame(x = a$x, y = a$y, piece = b, row = c, col = d)
}, a = e$data$fills, b = seq_along(e$data$fills), c = e$col_vals[1],
d = e$col_vals[2]))
})) |> mutate(row = factor(row, names(.env[["x"]])),
col = factor(col, names(.env[["x"]])))
text_df <- do.call("rbind", lapply(venns, function(a) {
res <- cbind(a$data$centers, row = factor(a$col_vals[1], names(x)),
col = factor(a$col_vals[2], names(x)))
res$labels[is.na(res$labels)] <- ""
res
}))
ggplot(plot_df, aes(x, y)) +
geom_polygon(aes( fill = factor(piece)), color = "black") +
geom_text(aes(label = labels), data = text_df, nudge_y = 1, fontface = 2) +
geom_text(aes(label = quantities), data = text_df, nudge_y = -2) +
facet_grid(row ~ col, drop = FALSE, switch = "y") +
scale_fill_manual(values = c("white", "#ececec", "#d9d9d9")) +
coord_equal() +
theme_void(base_size = 20) +
theme(legend.position = "none",
panel.background = element_rect(),
panel.spacing = unit(0, "mm"),
strip.text = element_text(margin = margin(10, 10, 10, 10)))