mindlessgreen
mindlessgreen

Reputation: 12112

Adding legend to venn diagram

I am using library VennDiagram to plot venn diagrams. But this function does not have a functionality to add legend and set names are displayed on or close to the sets themselves.

library(VennDiagram)
x <- list(c(1,2,3,4,5),c(4,5,6,7,8,9,10))
venn.diagram(x,filename="test.png",fill=c("#80b1d3","#b3de69"),
             category.names=c("A","B"),height=500,width=500,res=150)

venn-diagram

And with many sets, overplotting names is an issue and I would like to have a legend instead. The function is built on grid graphics and I have no idea how grid plotting works. But, I am attempting to add a legend anyway.

Looking into the venn.diagram function, I find that final plotted object is grob.list and it is a gList object and its plotted using grid.draw().

png(filename = filename, height = height, width = width, 
    units = units, res = resolution)
grid.draw(grob.list)
dev.off()

I figured out that I could create a legend by modifying the venn.diagram function with the code below.

cols <- c("#80b1d3","#b3de69")
lg <- legendGrob(labels=category.names, pch=rep(19,length(category.names)),
                 gp=gpar(col=cols, fill="gray"),byrow=TRUE)

Draw the object lg

png(filename = filename, height = height, width = width, 
    units = units, res = resolution)
grid.draw(lg)
dev.off()

to get a legend

legend

How do I put the venn diagram (gList) and the legend (gTree,grob) together in a usable way? I am hoping to get something like base plot style:

plot-with-legend

or the ggplot style

plit-with-legend

Upvotes: 2

Views: 3999

Answers (3)

KoenV
KoenV

Reputation: 4283

If you are allowed to use other packages than VennDiagram, I suggest the following code using the eulerr package:

library(eulerr)

vd <- euler(c(A = 5, B = 3, "A&B" = 2))
plot(vd, counts = TRUE,lwd = 2,
     fill=c("#80b1d3","#b3de69"),
     opacity = .7,
     key = list( space= "right", columns=1))

with key you define the legend location and appearance.

enter image description here

Upvotes: 3

mindlessgreen
mindlessgreen

Reputation: 12112

I have found a solution as well, but the venn diagram region is not square aspect ratio. And the legend is not spaced ideally.

library(gridGraphics)

png("test.png",height=600,width=600)
grab_grob <- function(){grid.echo();grid.grab()}
grid.draw(diag)
g <- grab_grob()
grid.arrange(g,lg,ncol=2,widths=grid::unit(c(0.7,0.3),"npc"))
dev.off()

plot

Upvotes: 1

GGamba
GGamba

Reputation: 13680

If you want to continue using the VennDiagram package and learn a bit of grid on the way:

Prepare diagram and legend

library(VennDiagram)
x <- list(c(1,2,3,4,5),c(4,5,6,7,8,9,10))
diag <- venn.diagram(x,NULL,fill=c("#80b1d3","#b3de69"),
             category.names=c("A","B"),height=500,width=500,res=150)


cols <- c("#80b1d3","#b3de69")
lg <- legendGrob(labels=c("A","B"), pch=rep(19,length(c("A","B"))),
                 gp=gpar(col=cols, fill="gray"),
                 byrow=TRUE)

Transform the diagram to a gTree

(I'd love to find a better way if anyone knows one)

library(gridExtra)

g <- gTree(children = gList(diag))

Plot the two gTrees side by side

gridExtra::grid.arrange(g, lg, ncol = 2, widths = c(4,1))

Or one above the other

grid.arrange(g, lg, nrow = 2, heights = c(4,1))

Upvotes: 1

Related Questions