4
votes

I am trying to put two Venn diagrams in one single graph, i.e. I am using par(mfrow=c(1,2)) at the very beginning. However, when I use the Venn() function in the Vennerable package:

VennCompare = Venn(SetNames = c("A", "B", "C"), Weight = c(0, 38, 1, 0, 1, 80, 0, 14))
pdf(file="Venn.pdf", width=12, height=6)
par(mfrow=c(1,2))
plot(VennCompare, doWeights=FALSE)
plot(VennCompare, doWeights=TRUE, show = list(SetLabels = TRUE, Faces = FALSE))
dev.off()

The resultant pdf file contains 2 pages, and each page has a single Venn diagram.

How can I put the two diagrams into a single page (i.e. side-by-side)?

3
Vennerable seems to use grid graphics instead of R base graphics, so par(mfrow=c(1,2)) wont work.Jouni Helske
@Hemmo: thanks! so how can I make side-by-side plots in the grid environment?alittleboy
I've been trying to plot these using standard grid methods and it looks like plot(VennCompare) does not respond to view port methods.Bryan Hanson
@BryanHanson: that's exactly what I got just now... it's not working if I pass p1 = plot(VennCompare)...alittleboy
I think you may have to contact the package maintainer. They have have to add support for a viewport argument, and they seem to have the equivalent of a newpage in their method.Bryan Hanson

3 Answers

4
votes

As already discussed in comments, Vennerable uses grid graphics and fixes the grid parameters inside of the package functions. You should probably ask kindly from package maintainers if they could add this kind of functionality in their packages, but in a meantime I offer you a Sketchof a hack which allows you to do what you want:

The first command allows you to edit the function called makevp.eqsc which seems to contain the grid definitions:

trace("makevp.eqsc",edit=TRUE) 

Original code looks like this:

function (xrange, yrange) 
{
    pushViewport(plotViewport(name = "Vennmar", c(1, 1, 1, 1)))
    pushViewport(viewport(name = "Vennlay", layout = grid.layout(1, 
        1, widths = diff(xrange), heights = diff(yrange), respect = TRUE)))
    pushViewport(viewport(name = "Vennvp", layout.pos.row = 1, 
        layout.pos.col = 1, xscale = xrange, yscale = yrange))
}

The most relevant parts are grid.layout, which tells you what kind of grid you want to draw. Also layout.pos.row and layout.pos.col are important, they tell in which position to draw. Change the code for example like this:

function (xrange, yrange) 
{
    pushViewport(plotViewport(name = "Vennmar", c(1, 1, 1, 1)))
    pushViewport(viewport(name = "Vennlay", layout = grid.layout(2, 
        1, widths = diff(xrange), heights = diff(yrange), respect = TRUE)))
    pushViewport(viewport(name = "Vennvp", layout.pos.row = number, 
        layout.pos.col = 1, xscale = xrange, yscale = yrange))
} 

Now you will get two stacked graphs, like this:

number<-1 #change the argument inside of makevp.eqsc
plot(VennCompare, doWeights=FALSE)
number<-2
plot(VennCompare, doWeights=TRUE, 
  show = list(SetLabels = TRUE, Faces = FALSE),add=TRUE) #note add=TRUE

This doesn't look really nice, but by modifying makevp.eqsc you can probably archieve more nice results.

3
votes

I couldn't install that package, but a trick that might help here is to use grid.grab to capture the drawing into a grob that can be placed elsewhere,

library(grid)

myplot <- function(){

  pushViewport(viewport(x=0.5,width=1, just=0.5))
  grid.rect(gp=gpar(fill=grey(runif(1, 0.2, 0.8))))
  grid.points()
  popViewport()

}

p1 <- grid.grabExpr(myplot())
p2 <- grid.grabExpr(myplot())

library(gridExtra)

grid.arrange(p1, p2, ncol=2) 
0
votes

Try this:

v <- Venn(n=2)
plot(v)
grid.text("Title", vp = viewport(x=0.5, y=.9, w=unit(1, "npc"), h=unit(1, "npc")))