Custom colour scales for {ggplot2}

R-Ladies Cambridge | 23rd March 2023

👩 Nicola Rennie

A lollipop chart with each point showing a different stage of the author's career.

Aims

To help you choose appropriate colours and make using them in {ggplot2} easier


🎨 Working with colours in {ggplot2}

🎨 Choosing effective, accessible colours

🎨 Creating custom colour scales

🎨 Some additional resources

Gif of lemurs eating dessert

Plotting
with
lemurs!

Start with a single colour…

ggplot(lemurs, 
       aes(x = name,
           y = n)) +
  geom_col(fill = "#E30B5C") 

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured pink.

Data: github.com/rfordatascience/tidytuesday

…or colour by species instead!

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() 

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species.

Let’s change to a nicer palette…

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_brewer(palette = "Dark2")

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species.

See {paletteer} for a collection of colour palette scales.

… our choose our own colours!

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#4C1E4F",
               "#7D70BA",
               "#D35269")
    )

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species.

Choosing
colours

How to define colours in R


  • Hex code: "#D35269"

  • RGB value: rgb()

  • Colour names: colors()

There 657 recognised colour names in R!


Gif of cartoon lemur looking confused

How to choose colours

Checking for colour blind friendliness

{colorblindcheck}

my_colours = c("#4C1E4F", "#7D70BA", "#D35269")
colorblindcheck::palette_check(my_colours, plot = TRUE)
          name n tolerance ncp ndcp min_dist mean_dist max_dist
1       normal 3   28.4883   3    3 28.48830  30.44199 33.74932
2 deuteranopia 3   28.4883   3    2 26.17337  35.31761 42.21131
3   protanopia 3   28.4883   3    1 25.58046  27.82692 29.85853
4   tritanopia 3   28.4883   3    3 32.22092  34.99349 36.84926

Checking for colour blind friendliness

{colorblindcheck}

Checking for colour blind friendliness

{colorblindr}

colorblindr::cvd_grid(lemur_plot)

Checking for colour blind friendliness


  • Minimise the number of colours (no more than 8)

  • Vary the luminosity of the colours

  • Check palettes for different chart types: {plotcolr}

  • Don’t rely on colour: {ggpattern}

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. Bars are coloured by species, and bars are also filled with different patterns to highlight combined use of colour and pattern for accessibility.

Custom
colour
scales

Now we want to re-use our colours…

…so let’s make a function!

First, let’s define our colours in a list:

my_colours = list(
  my_favourite_colours = c("#4C1E4F", "#7D70BA", "#D35269")
)

Turn colours into a palette

my_palettes = function(palette_name,
                       n,
                       type = c("discrete", "continuous")) {
  palette = my_colours[[palette_name]]
  if (missing(n)) {
    n = length(palette)
  }
  type = match.arg(type)
  out = switch(type,
               continuous = grDevices::colorRampPalette(palette)(n),
               discrete = palette[1:n]
  )
  structure(out, palette_name = palette_name, class = "palette")
}

Check it works…

my_palettes("my_favourite_colours", type = "discrete")
[1] "#4C1E4F" "#7D70BA" "#D35269"

Make some scale functions

Discrete scales

scale_colour_mycols_d = function(palette_name, ...) {
  ggplot2::scale_colour_manual(
    values = my_palettes(palette_name, type = "discrete"), ...)
}

scale_fill_mycols_d = function(palette_name, ...) {
  ggplot2::scale_fill_manual(
    values = my_palettes(palette_name, type = "discrete"), ...)
}

Make some scale functions

Continuous scales

scale_colour_mycols_c = function(palette_name, ...) {
  ggplot2::scale_colour_gradientn(
    colours = my_palettes(palette_name, type = "continuous"), ...)
}

scale_fill_mycols_c = function(palette_name, ...) {
  ggplot2::scale_fill_gradientn(
    colours = my_palettes(palette_name, type = "continuous"), ...)
}

Use colour or color

scale_color_mycols_d <- scale_colour_mycols_d
scale_color_mycols_c <- scale_colour_mycols_c

See it in action

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_mycols_d("my_favourite_colours")

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on species.

See it in action

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = n)) +
  geom_col() +
  scale_fill_mycols_c("my_favourite_colours", 
                      limits = c(0, 12500),
                      breaks = c(0, 12500))

A bar chart showing number of lemurs. On the x-axis three species of lemurs are shown including the Crowned lemur, Gray mouse lemur, and Ring-tailed lemur. On the y-axis the count of the number of each species is shown. The number of lemurs ranges from just under 2500 for Crowned lemurs, to almost 12500 for Gray mouse lemurs. The number of Crowned lemurs is significantly lower than the other two species shown. The bars are coloured based on number of lemurs.

Next
steps!

What to do next?

Slides

Questions?