Skip to content

Instantly share code, notes, and snippets.

@darokun
Last active August 1, 2020 04:53
Show Gist options
  • Save darokun/80298bb93d01ae3f8f5c2e205ed5b4d1 to your computer and use it in GitHub Desktop.
Save darokun/80298bb93d01ae3f8f5c2e205ed5b4d1 to your computer and use it in GitHub Desktop.
Generating different and distinct colors in R
library(RColorBrewer)
qual_col_pals <- brewer.pal.info[brewer.pal.info$category == 'qual',]
col_vector <- unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))
#check
myunif <- runif(40, 1, 1)
barplot(myunif, col = col_vector)
@bmbroom
Copy link

bmbroom commented May 12, 2018

Some of the colors returned above (after removing exact duplicates) are very similar to each other. (e.g. "#E31A1C" and "#E41A1C", which I can't tell apart visually). Rather than rely on chance to avoid picking such pairs colors, I wrote the following little function that discards the color most similar to another until only the desired number of colors are left:

getDistinctColors <- function(n) {
    qual_col_pals <- brewer.pal.info[brewer.pal.info$category == 'qual',]
    col_vector <- unique (unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals))));
    stopifnot (n <= length(col_vector));
    xxx <- col2rgb(col_vector);
    dist_mat <- as.matrix(dist(t(xxx)));
    diag(dist_mat) <- 1e10;
    while (length(col_vector) > n) {
        minv <- apply (dist_mat,1,function(x)min(x));
        idx <- which(minv==min(minv))[1];
        dist_mat <- dist_mat[-idx, -idx];
        col_vector <- col_vector[-idx]
    }
    col_vector
}

It computes distances between colors in RGB space. Using a perceptual space like Lab would be better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment