roverlayvenn-diagram

How to put/overlay values from 2 Venn diagram in R


I am trying to show 2 values on Venn diagram in R.

Let's say we have a list of X and Y:

X = list(cond1 = c(...), cond2 = c(...), cond3 = c(...), cond4 = c(...))

Y = list(cond1 = c(...), cond2 = c(...), cond3 = c(...), cond4 = c(...))

cond1 in X and Y may have different values, sets; for instance:

X$cond1 = c(1,2,3,4,5)
Y$cond2 = c(1,4,5,6,7)

same applies to cond2, cond3 and cond4.

one can use different functions in R to draw Venn diagram separately for X and Y.

for instance using ggvenn library;

ggvenn(X) # venn1
ggvenn(Y) # venn2

how can we put values in Venn1 and Venn2 on the same Venn diagram?

Edit:

here is an example.

set.seed(123)
genes = paste0("gene", seq(1,1000))

X = list(
    cond1 = sample(genes, 200),
    cond2 = sample(genes, 100),
    cond3 = sample(genes, 120),
    cond4 = sample(genes, 60)   
)


Y = list(
    cond1 = sample(genes, 150),
    cond2 = sample(genes, 110),
    cond3 = sample(genes, 220),
    cond4 = sample(genes, 80)   
)

ggvenn(X, show_percentage = F)
ggvenn(Y, show_percentage = F)

X (up-left), Y(up-right). I want to have both values on the same Venn (bottom Venn diagram). I manually added values and color coded red for Y values.

enter image description here


Solution

  • There isn't an easy way to do it with the ggvenn package as it currently stands. You have to rewrite parts of the ggvenn code and call a certain function twice.

    Here is how I did it.

    1. Go to here: ggvenn.R code. Copy/paste all of these functions into your R session. This puts all of the packages functions in the global environment where R can see it. There may be a more elegant way to do this, but this is the easiest but most messy way.
    2. Now we will modify the ggvenn function so that it does what you want. We will call it my.ggvenn.
    ### Anything with a ".plus" is something that I added to the base function
    ### data.plus is the "Y" in your example, and data is the usual "X".
    my.ggvenn <- function(data, data.plus, columns = NULL,
                       show_elements = FALSE,
                       show_percentage = TRUE,
                       digits = 1,
                       fill_color = c("blue", "yellow", "green", "red"),
                       fill_alpha = .5,
                       stroke_color = "black",
                       stroke_alpha = 1,
                       stroke_size = 1,
                       stroke_linetype = "solid",
                       set_name_color = "black",
                       set_name_size = 6,
                       text_color = "black",
    ###This is the color of the Y numbers underneath
                       text_color.plus = "blue",
                       text_size = 4,
    ###This is the vertical justification
                       vjust.plus = 1,
                       label_sep = ",",
                       count_column = NULL,
                       show_outside = c("auto", "none", "always"),
                       auto_scale = FALSE)
    {
      show_outside <- match.arg(show_outside)
    
    ### we run this function 2 times, one for X (data) and one for Y (data.plus).  
    ### The objective is to perform the identical diagrams but adjust the Y one lower with vjust.
    
      venn <- prepare_venn_data(data, columns, show_elements, show_percentage, digits,
                                label_sep, count_column, show_outside, auto_scale)
    
    ### this was added by me; you can check out what it does but it creates the formatting
    
      venn.plus <- prepare_venn_data(data.plus, columns, show_elements, show_percentage, digits,
                                label_sep, count_column, show_outside, auto_scale)
      
      g <- venn$shapes %>%
        mutate(group = LETTERS[group]) %>%
        ggplot() +
        geom_polygon(aes(x = x, y = y, group = group, fill = group),
                     alpha = fill_alpha) +
        geom_polygon(aes(x = x, y = y, group = group),
                     fill = NA,
                     color = stroke_color,
                     size = stroke_size,
                     alpha = stroke_alpha,
                     linetype = stroke_linetype)
      if (nrow(venn$labels) > 0) {
        g <- g +
          geom_text(data = venn$labels,
                    aes(x = x, y = y, label = text, hjust = hjust, vjust = vjust),
                    color = set_name_color,
                    size = set_name_size)
      }
      if (nrow(venn$texts) > 0) {
        g <- g +
          geom_text(data = venn$texts,
                    aes(x = x, y = y, label = text, hjust = hjust, vjust = vjust),
                    color = text_color,
                    size = text_size)
      }
    ### this adjusts all of the Y values down by vjust + vjust.plus and colors them.
      if (nrow(venn.plus$texts) > 0) {
        g <- g +
          geom_text(data = venn.plus$texts,
                    aes(x = x, y = y, label = text, hjust = hjust, vjust = vjust+vjust.plus),
                    color = text_color.plus,
                    size = text_size)
      }
      if (nrow(venn$segs) > 0) {
        g <- g +
          geom_segment(data = venn$segs,
                       aes(x = x, y = y, xend = xend, yend = yend),
                       color = text_color,
                       size = 0.5)
      }
      g <- g +
        scale_fill_manual(values = fill_color) +
        guides(fill = "none") +
        coord_fixed() +
        theme_void()
      return(g)
    }
      
    my.ggvenn(X,Y, show_percentage = F)
    

    enter image description here