Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

I know that venn diagrams are not as sexy as they used to be and that John Venn’s birthday was actually Aug 4, but venn diagram’s still serve a purpose here and there, especially if we can get some more interesting colors in there.

Plus, this question on how to hack the venneuler color palette appears to have gone unanswered for a couple years.

The venneuler::venneuler function doesn’t come with a color option directly accessible. However, venneuler package has an unexported plot method venneuler:::plot.VennDiagram that does have a color option that takes hex colors.

The trick is to match the sequencing the labels that comes out of venneuler in the outputted object vv to the colors you want for each label. I hack that below by using match(vv$labels, names(colors)). This allows you to get consistent results on coloring and labels across uses. # define labels labels <- c("Happy", "Bday") # define colors colors <- c("#7709d2","#64D209") # name colors with labels names(colors) <- labels # some toy data IMPORTANT PART IS THAT mat <- matrix(c(1880,270,270,470), nrow=2, ncol=2) colnames(mat) <- labels rownames(mat) <- labels make_venn <- function(dat, title="",fill_cols=NULL , alpha=.7, title_font=1){ vv <- venneuler::venneuler(dat) if (!is.null(fill_cols)){ plot(vv, main=title, font.main = title_font , col=fill_cols[match(vv$labels, names(colors))], alpha=alpha )
} else {
plot(vv, main=title, font.main = title_font, alpha=alpha)
}
}

make_venn(make_dat(mat),title="Happy Birthday Venn!"
,fill_cols=colors, title_font=2)


The key to selecting colors in the venneuler is the thinking in terms of the labels and colors, but the venneuler package expects data have labels that include the co-occurence of the underlying labels:, e.g. c(Happy=1880, Bday=470, "Happy&Bday"=270).

This presents a slight problem when we’ve only specified the colors for the labels and not their co-occurence. To handle the conversion of a matrix to the structure venneuler expects, I’ve written a helper function make_dat. The function tests if the dat passed in is a matrix or a vector, if it is a vector whether the names contain the required & character.

make_dat <- function(dat){
if (is.matrix(dat)) {
# self-datcuring
dg <- diag(dat)

# co-tags
nm <-  nn <-  matrix(nrow=nrow(dat),ncol=nrow(dat))

# get names and values from lower.tri
for (i in seq_along(rownames(dat))){
for (j in seq_along(rownames(dat))){
if (i!=j) nm[i,j] <- paste(rownames(dat)[i],rownames(dat)[j], sep="&")
if (i!=j) nn[i,j] <- dat[i,j]
}
}
nn <- na.omit(as.vector(nn))
nm <- na.omit(as.vector(nm))
names(nn) <- nm
c(dg,nn)
} else if (any(grepl("&",names(dat)))){
dat
} else stop("Data format of dat object is incorrect\n\tEither is not a matrix or\n\tnames do not contain '&' for co-tags" )
}


Happy Venn diagramming!