Evolve new colour palettes in R with evoPalette

[This article was first published on R – Daniel Oehm | Gradient Descending, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

What’s that saying? Choice is the enemy of happiness, or something like that. There are so many colour palettes out there, that saying tends to resonate when either choosing one, or creating a new one. So, I started to think about a way I could make this more organic, and came up with the idea for evoPalette.

evoPalette allows for the discovery and generation of new colour palettes for R. Taking user input it uses an evolutionary algorithm to spawn new palettes with the expectation the colours you like will be combined over time. This can be repeated as many times as needed until you find something that works for you.

There’s a lot to colour theory, no choice is trivial, and so leaving some of those choices largely to an algorithm will have varying success. This is trading best practice for fun and discovery but I’m okay with that!

The algorithm in a nutshell

Very briefly, evolutionary algorithms operate in 3 main steps:

  1. Selection: Each candidate has a measure of fitness and those that reach some threshold survive. In this case parents of the next generation are selected by the user and so fitness is essentially personal preference.
  2. Crossover: Children are spawned from a random combination of two parents genes. In this case colours represent a gene.
  3. Mutation: Mutation occurs in two ways 1) there is a chance of a completely new colour generated for a palette and 2) each colour varies locally around it’s initial value.

The process can continue for as long as needed.

Installation

You can install evoPalette from Github with the following command.

devtools::install_github("doehm/evoPalette")

(It’s only on Git for the moment. We’ll see how it goes.)

Getting started

To jump straight into it launch the Shiny app with

launch_evo_palette()

To generate the first set of palettes, click ‘evolve’. Using the default setting the initial palettes will be randomly drawn from a standard set saved in evoPalette and paletteer. Paletteer contains some 1700+ palettes from a number of packages.

Select one or more palettes that you like and think may work well together from the check box and click ‘evolve’. The next generation of palettes will be created.

Select the parents for the next generation from the checkbox

With each generation you’ll notice how the palette is converging to a similar theme based on your selections, along with some variation of each individual colour and a chance of a completely new colour. The features that you liked about one palette have a chance to be combined with other colours and flow through to the next generation. Although, this isn’t completely ensured since there is still a stochastic element at play, but you may discover another combination that works well for you. The selected parent palettes are shown in the sidebar for reference.

The children of selected palettes. Note the similar combinations of colours and random mutations. Names are randomly generated.

Selecting only a single parent is convenient for generating minor variations to tweak the colours.

Select ‘Example: Fill aesthetic’ to see how the palette works in practice (similarly for ‘Example: Colour aesthetic’).

To save a palette, select the desired palette from the check box and click ‘save‘. A box will appear giving the opportunity to change the randomly generated palette name but, why would you want to!

The palette is now accessible from palette_box() once the app is closed. Multiple palettes can be saved which are collected in the palette box, just save one at a time. The palette box is refreshed when starting a new session so remember to save it to disk.

Palette ‘instructive customers’ saved to palette box.
palette_box()

$instructive_customers
[1] "#C7B6C8" "#74B6BA" "#7783C4" "#B56D4E" "#F28E47" "#FCE269"

To begin again, deselect all palettes, click ‘evolve’. New palettes are randomly selected beginning a new process.

A palette is viewed by using show_palette().

show_palette(palette_box()["instructive_customers"])

The continuous scales are simply created from the two colours on the ends and one in the middle (room for improvement).

Control

The user has some control over the algorithm by adjusting the mutation rate and variation allowed for each colour. Select the parameters from the drop down in the menu.

Click the drop down to access parameters list.
  • Number of colours to generate for each palette. Initial starting palettes with more / fewer colours are coerced to have the desired amount. So, a standard palette with more or fewer than this amount will be slightly different.
  • Number of palettes to generate at each evolution. The default is 9.
  • Mutation rate – Each colour in the palette has a probability of random mutation equal to this value (default p = 0.05)
  • Mutation variation – Each colour will vary slightly around it’s original value.
  • Load existing palettes from the global environment. Object should be a list, ideally with names i.e. the same format as palette_box().
  • Are you feeling lucky? Select for generating palettes from completely random colours.

When you are happy with your selections, click ‘evolve’ and begin a new process.

Scales

The generated colour palettes are easily added to ggplots using the scale functions scale_fill_evo and scale_colour_evo.

library(ggplot2)
mpg %>% 
  ggplot(aes(x = displ, fill = class)) +
  geom_histogram() +
  scale_fill_evo("instructive_customers")

The first palette in the list is used if no name is given. The scales are also parameterised to reverse the palette and switch discrete / continuous.

Evolution isn’t perfect

Colour theory is pretty complex stuff so choosing a good palette isn’t easy, let alone evolving one. So, you’re going to have some hits and some misses. This is definitely more for fun seeing what you discover rather than finding the perfect palette. Having said that you could discover some gold!

There are best practices when choosing a palette for data visualisation depending on the context and what is to be shown. For example people tend to respond to certain colours representing high / low, hot / cold or good / bad, there is also colourblindness considerations. evoPalette won’t necessarily adhere to these ideals.

This is best for generating discrete colour palettes with 4-7 distinct colours. It will help you find colours which are to your liking and generate a palette which is unlikely to already exist. It’s fun to experiment and see what you come up with!

evoPalette palettes

Some of the initial starting palettes I’ve created and are shown below. A few are created from evoPalette, some from a clustering process. The 90’s rock palettes were created from the album covers. Sorry for doubling up on Alice in Chains ????.

g_evo <- readRDS(system.file("extdata/palettes.rds", package = "evoPalette"))
map2(g_evo$palette, g_evo$name, ~show_palette(.x, title = .y)) %>%
   wrap_plots(ncol = 2)

The post Evolve new colour palettes in R with evoPalette appeared first on Daniel Oehm | Gradient Descending.

To leave a comment for the author, please follow the link and comment on their blog: R – Daniel Oehm | Gradient Descending.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)