3

I am trying to plot a venn diagram in an optimized way (see below) and with the cases as internal labels (not the number of cases in each intersection). I know there are post for each of them but non of the solutions allowed me to do both.

I have this:

x <- list()
x$A <- as.character(c("Per_36","Cent","CeM","vDG","LAVL","RSGd"))
x$B <- as.character(c("vCA1","DLE","Per_36","vDG","DIE","Per_35"))
x$C <- as.character(c("vCA1","Cg1","LAVL", "RSGc", "RSGd","Per_35","Per_36"))
x$D <- as.character(c("Por","Cg1","RSGc","LAVL","Per_35","RSGd","Per_36"))


require(VennDiagram)
v0 <-venn.diagram(x, lwd = 3, col = c("red", "green", "orange", "blue"),
                fill = c("red", "blue", "green", "orange"), apha = 0.5, filename = NULL)
grid.draw(v0)
overlaps <- calculate.overlap(x)
overlaps <- rev(overlaps)
for (i in 1:length(overlaps)){
  v0[[i+8]]$label <- paste(overlaps[[i]], collapse = "\n")
}

grid.newpage()
grid.draw(v0)

I get the following output:

enter image description here

Regarding the organization of the venn diagramI want to do this:

c <- venn(x, simplify = TRUE, small = 0.5, intersections = TRUE)

enter image description here

which I got from package gplots() using the venn function with simplify = TRUE. However, in the venn function, I seem to no be able to replace the counts by the names of the labels. I used the intersections = TRUE, which by the description of the argument should work, but it doesn't (although if I look inside the variable c, the info is there).

    Logical flag indicating if the returned object should have the attribute 
"individuals.in.intersections" featuring for every set a list of individuals
 that are assigned to it.

Question: Using VennDiagrampackage, is there a way to do exactly the same as the simplify argument does in the venn function from gplots package?

Question 2: Using the venn function from gplots package, is there a way to display the names of each element instead of the element counts? Like I did in the 'venn.diagram' function?

Thanks in advance,

1
  • I am trying to draw a Venn diagram with internal labels and your question is a good example, I have only 3 lists so I cannot get it to work because I cannot figure out why you are addin 8 to the index in this line: v0[[i+8]]$label?
    – Ibo
    Commented May 15, 2018 at 23:16

1 Answer 1

2

Here is my approach which is by far no solution rather a hack.

# Print a venn and save it to an object
a <- venn(list(letters[1:5], letters[3:8]))
# save the intersections
b <- attr(a, "intersections")

# find the coordinates
s <- seq(0,500,100); abline(h=s); text(s, y=s, x=0)
s <- seq(0,500,50);  abline(v=s); text(s, y=0, x=s)

enter image description here

# the hack, destroy the venn to avoid the plotting of the internal numbers 
rownames(a) <- letters[1:nrow(a)]
a
plot.venn(a)
>Error in data[n, 1] : subscript out of bounds

# include the internal labels
text(200,300,paste(b$`01`,collapse = "\n"))
text(200,200,paste(b$`11`,collapse = "\n"))
text(200,100,paste(b$`10`,collapse = "\n"))

enter image description here

It's annoying with multiple venns. Otherwise you can save the venn as an .svg and edit it with inkscape or similar softwares or ask the developer by email.

Edit: If your plots looking alwas the same you can check the source code for the venn function (In RStudio by hitting F2) and copy paste the positions for 4 and 5 circle venns and replace the labels function lab("1000", data) with your desired labels.

For 4 circles:

      text(35, 250, lab("1000", data))
      text(140, 315, lab("0100", data))
      text(260, 315, lab("0010", data))
      text(365, 250, lab("0001", data))
      text(90, 280, lab("1100", data), cex = small)
      text(95, 110, lab("1010", data))
      text(200, 50, lab("1001", data), cex = small)
      text(200, 290, lab("0110", data))
      text(300, 110, lab("0101", data))
      text(310, 280, lab("0011", data), cex = small)
      text(130, 230, lab("1110", data))
      text(245, 75, lab("1101", data), cex = small)
      text(155, 75, lab("1011", data), cex = small)
      text(270, 230, lab("0111", data))
      text(200, 150, lab("1111", data))

Edit

Nowadays I would switch to a ggplot solution

ggVennDiagram::ggVennDiagram(x)

enter image description here

1
  • I need to generate many of these diagrams, your suggestion would require an attention to each diagram that I initially don't want to spend. I will only do it if I really need to. But thanks. It is a way to put it there. Both functions allows you to get each element in each intersections, they just don't allow you to put them into the diagram in a more presentable way.
    – CAOC
    Commented Feb 19, 2016 at 12:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.