How to define color of intersection in a Venn diagram?

前端 未结 2 1509
无人共我
无人共我 2021-01-13 02:57

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

相关标签:
2条回答
  • 2021-01-13 03:42

    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

    0 讨论(0)
  • 2021-01-13 03:44

    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)
    


    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)
    


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

    0 讨论(0)
提交回复
热议问题