Marcus Nunes
Marcus Nunes

Reputation: 861

How to define color of intersection in a Venn diagram?

I found many resources on how to draw Venn diagrams in R. Stack Overflow has a lot of them. However, I still can't draw my diagrams the way I want. Take the following code as an example:

library("VennDiagram")

A <- 1:4
B <- 3:6
d <- list(A, B)

vp <- venn.diagram(d, fill = c("white", "white"), alpha = 1, filename = NULL, 
  category.names=c("A", "B"))
grid.draw(vp)

enter image description here

I want the intersection between the sets to be red. However, if I change any of the white colors to red, I get the following:

vp_red <- venn.diagram(d, fill = c("red", "white"), alpha = 1, filename = NULL, 
  category.names=c("A", "B"))
grid.draw(vp_red)

enter image description here

That's not quite what I want. I want only the intersection to be red. If I change the alpha, this is what I get:

vp_alpha <- venn.diagram(d, fill = c("red", "white"), alpha = 0.5, filename = NULL, 
  category.names=c("A", "B"))
grid.draw(vp_alpha)

enter image description here

Now I have pink in my intersection. This is not what I want as well. What I want is something like this image from Wikipedia:

enter image description here

How can I do this? Maybe VennDiagram package can't do it and I need some other package, but I've been testing different ways to do it, and I'm not being able to find a solution.

Upvotes: 6

Views: 6053

Answers (2)

djneuron
djneuron

Reputation: 81

It's very easy in eulerr R package

library(eulerr)
plot(euler(c("A"=5,"B"=4,"A&B"=2)),quantities = TRUE,fills=c("white","white","red"))

euler set colours

Upvotes: 4

Henrik
Henrik

Reputation: 67778

I will show two different possibilities. In the first example, polyclip::polyclip is used to get the intersection. In the second example, circles are converted to sp::SpatialPolygons and we get the intersection using rgeos::gIntersection. Then we re-plot the circles and fill the intersecting area.


The resulting object when using venn.diagram is

"of class gList containing the grid objects that make up the diagram"

Thus, in both cases we can grab relevant data from "vp". First, check the structure and list the grobs of the object:

str(vp)
grid.ls()
# GRID.polygon.234
# GRID.polygon.235
# GRID.polygon.236 <~~ these are the empty circles
# GRID.polygon.237 <~~ $ col : chr "black"; $ fill: chr "transparent"
# GRID.text.238 <~~ labels
# GRID.text.239
# GRID.text.240
# GRID.text.241
# GRID.text.242 

1. polyclip

Grab x- and y-values, and put them in the format required for polyclip:

A <- list(list(x = as.vector(vp[[3]][[1]]), y = as.vector(vp[[3]][[2]])))
B <- list(list(x = as.vector(vp[[4]][[1]]), y = as.vector(vp[[4]][[2]])))

Find intersection:

library(polyclip)
AintB <- polyclip(A, B)

Grab labels:

ix <- sapply(vp, function(x) grepl("text", x$name, fixed = TRUE))
labs <- do.call(rbind.data.frame, lapply(vp[ix], `[`, c("x", "y", "label")))

Plot it!

plot(c(0, 1), c(0, 1), type = "n", axes = FALSE, xlab = "", ylab = "")
polygon(A[[1]])
polygon(B[[1]])
polygon(AintB[[1]], col = "red")
text(x = labs$x, y = labs$y, labels = labs$label)

enter image description here


2. SpatialPolygons and gIntersection

Grab the coordinates of the circles:

# grab x- and y-values from first circle
x1 <- vp[[3]][["x"]]
y1 <- vp[[3]][["y"]]

# grab x- and y-values from second circle
x2 <- vp[[4]][["x"]]
y2 <- vp[[4]][["y"]]

Convert points to SpatialPolygons and find their intersection:

library(sp)
library(rgeos)
p1 <- SpatialPolygons(list(Polygons(list(Polygon(cbind(x1, y1))), ID = 1))) 
p2 <- SpatialPolygons(list(Polygons(list(Polygon(cbind(x2, y2))), ID = 2))) 

ip <- gIntersection(p1, p2) 

Plot it!

# plot circles 
plot(p1, xlim = range(c(x1, x2)), ylim = range(c(y1, y2))) 
plot(p2, add = TRUE) 

# plot intersection
plot(ip, add = TRUE, col = "red") 

# add labels (see above)
text(x = labs$x, y = labs$y, labels = labs$label)

enter image description here


I'm quite sure you could work directly on the grobs using clipping functions in grid or gridSVG package.

Upvotes: 8

Related Questions