Palatable Palettes: Creating and applying bespoke colour schemes

Cara Thompson | NHS-R 2022 Conference | 17th November 2022

Hi there đź‘‹ !

đź‘© Cara Thompson

👩‍💻 Freelance data consultant specialising in dataviz and “enhanced” reproducible outputs

đź’™ Helping others maximise the impact of their expertise

🎨 Five tips for creating and applying bespoke colour schemes to your plots

Please suspend all disbelief

The Great Penguin Bake Off

The Great Penguin Bake Off

The Great Penguin Bake Off

The Great Penguin Bake Off

The Great Penguin Bake Off

The Great Penguin Bake Off

The Great Penguin Bake Off

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#1 - Use colour purposefully

Make it easy for the readers to remember what is what.

But my graphs aren’t about penguins baking banana bread!

#1 - Use colour purposefully

#1 - Use colour purposefully

Make it easy for the readers to remember what is what.

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#2 - Let others help you

🤫 - I find picking colours really tricky

Luckily, there are others who can help…

  • Your department brand guidelines
  • A photo + something like imagecolorpicker.com to pick out colours

#2 - Let others help you

#2 - Let others help you



#2 - Let others help you

#2 - Let others help you

#2 - Let others help you

  • Your department brand guidelines
  • A photo + something like imagecolorpicker.com to pick out colours
  • Take inspiration from other dataviz / art you like

#2 - Let others help you

#2 - Let others help you

  • Your department brand guidelines
  • A photo + something like imagecolorpicker.com to pick out colours
  • Take inspiration from other dataviz / art you like
  • Google images and “[whatever you like] palette”

#2 - Let others help you

#2 - Let others help you

  • Your department brand guidelines
  • A photo + something like imagecolorpicker.com to pick out colours
  • Take inspiration from other dataviz / art you like
  • Google images and “[whatever you like] palette”
  • Or… start from the colour wheel and read around how best to use it

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Package up as a default palette

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Package up as a default palette

#3 - Apply colours using a named vector

Once you’ve found your colours, the quick fix…

ggplot(penguins, 
       aes(x = bill_depth_mm,
           y = bill_length_mm,
           colour = species)) +
  geom_point(size = 5) +
  labs(x = "Baking duration",
       y = "Yumminess") +
  theme_nhsr_demo() +
  scale_colour_manual(values = c("#89973d", 
                                 "#e8b92f", 
                                 "#a45e41"))

#3 - Apply colours using a named vector

… might be a dangerous shortcut!

ggplot(penguins %>% 
         # Oh, that should be a factor, 
         # let me fix that for you!
         mutate(species = 
                  factor(species, 
                         levels = c("Chinstrap", 
                                    "Gentoo", 
                                    "Adelie"))), 
       aes(x = bill_depth_mm,
           y = bill_length_mm,
           colour = species)) +
  geom_point(size = 5) + 
  labs(x = "Baking duration",
       y = "Yumminess") +
  theme_nhsr_demo() +
  scale_colour_manual(values = c("#89973d", 
                                 "#e8b92f", 
                                 "#a45e41"))

#3 - Apply colours using a named vector

What is going on?

The values will be matched in order (usually alphabetical) with the limits of the scale, or with breaks if provided. If this is a named vector, then the values will be matched based on the names instead. Data values that don’t match will be given na.value.

#3 - Apply colours using a named vector

Create a named vector

banana_colours <- c("Adelie" = "#89973d",
                    "Chinstrap" = "#e8b92f",
                    "Gentoo" = "#a45e41")

ggplot(penguins,
       aes(x = bill_depth_mm,
           y = bill_length_mm,
           colour = species)) +
  geom_point(size = 5) +
  labs(x = "Baking duration",
       y = "Yumminess") +
  theme_nhsr_demo() +
  scale_colour_manual(values = banana_colours)

#3 - Apply colours using a named vector

Create a named vector

banana_colours <- c("Adelie" = "#89973d",
                    "Chinstrap" = "#e8b92f",
                    "Gentoo" = "#a45e41")

ggplot(penguins %>% 
         # Oh, that should be a factor, 
         # let me fix that for you!
         mutate(species = 
                  factor(species, 
                         levels = c("Chinstrap", 
                                    "Gentoo", 
                                    "Adelie"))), 
       aes(x = bill_depth_mm,
           y = bill_length_mm,
           colour = species)) +
  geom_point(size = 5) +
  labs(x = "Baking duration",
       y = "Yumminess") +
  theme_nhsr_demo() +
  scale_colour_manual(values = banana_colours)

#3 - Apply colours using a named vector

Key advantages

  • Know the colours are applied to the right data points!
  • Keep colour-data pairings consistent throughout the project
  • Package up a default palette
  • Reuse colours in the text
    • ggtext::element_markdown()- Level up your plots

#3 - Apply colours using a named vector

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Package up as a default palette

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Package up as a default palette

#4 - Check for accessibility

📦 {colorblindr} - Claire D. McWhite and Claus O. Wilke

a package to apply simulations of color vision deficiencies to existing ggplot2 figures. It can simulate various classes and severities of color blindness, as well as desaturate plots.

#4 - Check for accessibility

banana_plot

#4 - Check for accessibility

colorblindr::cvd_grid()

#4 - Check for accessibility

Easiest way to do this? Build a palette that goes from a lighter colour to a darker colour.


A few helpful resources:

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation

#5 - Make use of colour interpolation

What if I don’t know how many colours I need?

  • Build more than you’re likely to need and allow R to pick colours to maximise distance
    • ⚠️ It just picks e.g. #1, #5 and #9 in the order of your vector
  • Pick 2 or 3 anchor colours and let R interpolate
    • colorRampPalette()

#5 - Make use of colour interpolation

my_anchor_colours <- c("green", "blue", "purple")

palmerpenguins::penguins %>%
  mutate(island_fm = paste0(island, sex)) %>%
  ggplot() + 
  geom_point(aes(x = bill_length_mm,
                 y = bill_depth_mm,
                 colour = island_fm,
                 size = body_mass_g),
             show.legend = FALSE) +
  theme_nhsr_demo() +
  scale_color_manual(
    values = colorRampPalette(
      my_anchor_colours)(9))

#5 - Make use of colour interpolation

imagecolorpicker.com + Chroma.js Color Palette Helper

#5 - Make use of colour interpolation

my_anchor_colours <- c("#4f3c78", "#d3970a", "#c0979c")

palmerpenguins::penguins %>%
  ggplot() + 
  geom_point(aes(x = bill_length_mm,
                 y = bill_depth_mm,
                 colour = island,
                 size = body_mass_g),
             show.legend = FALSE) +
  theme_nhsr_demo() +
  scale_color_manual(
    values = colorRampPalette(
      my_anchor_colours)(3))

#5 - Make use of colour interpolation

my_anchor_colours <- c("#4f3c78", "#d3970a", "#c0979c")

palmerpenguins::penguins %>%
  mutate(island_fm = paste0(island, sex)) %>%
  ggplot() + 
  geom_point(aes(x = bill_length_mm,
                 y = bill_depth_mm,
                 colour = island_fm,
                 size = body_mass_g),
             show.legend = FALSE) +
  theme_nhsr_demo() +
  scale_color_manual(
    values = colorRampPalette(
      my_anchor_colours)(9))

#5 - Make use of colour interpolation

my_anchor_colours <- c("#375248", "#d3970a", "#7691b1")

palmerpenguins::penguins %>%
  mutate(island_fm = paste0(island, sex)) %>%
  ggplot() + 
  geom_point(aes(x = bill_length_mm,
                 y = bill_depth_mm,
                 colour = island_fm,
                 size = body_mass_g),
             show.legend = FALSE) +
  theme_nhsr_demo() +
  scale_color_manual(
    values = colorRampPalette(
      my_anchor_colours)(9))

#5 - Make use of colour interpolation

There are only so many colours you can use in a plot!

  • Could other approaches work (facets?)
  • Try using different shapes (you can use letters / emoji!)

There’s so much more we could talk about!

  • Packaging up your palette for easy reuse carartemplates::carar_colours()

  • Creating your own scale_nhsdemo_colour/fill() functions
  • You can even have several palettes! scale_nhsdemo_colour("Birmingham")?
  • Basing your “dark text” colour on the central / most important colour in your palette
… but we can talk about this some other time!

Five tips for creating and applying bespoke colour palettes

#1 - Use colour purposefully

#2 - Let others help you

#3 - Apply colours using a named vector

#4 - Check for accessibility

#5 - Make use of colour interpolation


Happy plotting!

@cararthompson