Comment définir la couleur de l'intersection dans un diagramme de Venn?
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)
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)
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)
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 :
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.
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 thegrid
objects that make up the diagram"
Thus, in both cases we can grab relevant data from "vp". First, check the str
ucture 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)
2. SpatialPolygons
etgIntersection
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 SpatialPolygons
et 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)
Je suis tout à fait sûr que vous pouvez travailler directement sur les grobs
fonctions de découpage dans grid
ou gridSVG
package.