Search code examples
rvenn-diagram

legend venn diagram in venneuler


I would like to create a legend for a venneuler venn diagram. This should be straight forward because the function venneuler returns the colors used to the console. The colors are of a value between 0 and 1. I want to know how to turn those numberic values stored in $colors into something I can use to fill the fill argument in legend.

I have attempted this below by using the $colors extracted from venneuler and indexing from colors(). I know this is not correct because colors() is indexed with interval values but put it in to show what I'd like.

set.seed(20)
x <- matrix(sample(0:1, 100, replace = TRUE), 10, 10)
colnames(x) <- LETTERS[1:10]
rownames(x) <- letters[1:10]

require(venneuler)
y <- venneuler(x)
plot(y)

y$colors

legend(.05, .9, legend = colnames(x), fill = colors()[y$colors])

Solution

  • By perusing plot.VennDiagram and its defaults you can see how it converts the numbers in y$colors to rgb color strings. (Try getAnywhere("plot.VennDiagram") to have a look yourself.)

    Here I've collected the two bits of code that processed the colors (in your case) into a single function that will do the conversion for you. The positioning of the legend could probably be improved, but that's another problem...

    col.fn <- function(col, alpha=0.3) {
        col<- hcl(col * 360, 130, 60)
        col <- col2rgb(col)/255
        col <- rgb(col[1, ], col[2, ], col[3, ], alpha)
        col
    }
    
    COL <- col.fn(y$colors)
    # The original order of columns in x is jumbled in the object returned
    # by venneuler. This code is needed to put the colors and labels back
    # in the original order (here alphabetical).
    LABS <- y$labels
    id <-  match(colnames(x), LABS)
    
    plot(y)
    legend(.05, .9, legend = LABS[id], fill = COL[id], x="topleft")
    

    enter image description here