Comment définir la couleur de l'intersection dans un diagramme de Venn?


Marcus Nunes

J'ai trouvé de nombreuses ressources sur la façon de dessiner des diagrammes de Venn dans R. Stack Overflow en a beaucoup . Cependant, je ne peux toujours pas dessiner mes diagrammes comme je le souhaite. Prenez le code suivant comme exemple:

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)

entrez la description de l'image ici

Je veux que l'intersection entre les décors soit rouge. Cependant, si je change l'une des couleurs blanches en rouge, j'obtiens ce qui suit:

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

entrez la description de l'image ici

Ce n'est pas tout à fait ce que je veux. Je veux que seule l'intersection soit rouge. Si je change l'alpha, voici ce que j'obtiens:

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

entrez la description de l'image ici

Maintenant, j'ai du rose dans mon intersection. Ce n'est pas non plus ce que je veux. Ce que je veux, c'est quelque chose comme cette image de Wikipedia :

entrez la description de l'image ici

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.

Henrik

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

Saisissez les valeurs x et y et mettez-les au format requis pour 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]])))

Trouver l'intersection:

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

Prenez les étiquettes:

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

Tracez-le!

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)

entrez la description de l'image ici


2. SpatialPolygonsetgIntersection

Prenez les coordonnées des cercles:

# 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"]]

Convertissez les points en SpatialPolygonset trouvez leur 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) 

Tracez-le!

# 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)

entrez la description de l'image ici


Je suis tout à fait sûr que vous pouvez travailler directement sur les grobsfonctions de découpage dans gridou gridSVGpackage.

Articles connexes