For week 23 of Tidy Tuesday the chart I wanted to make required two colour scales. For context the dataset detailed pride sponsors that also contributed to anti-LGBTQ+ politicians. TL;DR I wanted to make some rainbows with rainbow colours if the company made the HRC business pledge and a neutral colour for the companies that hadn’t.

I could use `scale_colour_gradientn()` for the colour rainbows but needed a solution for the neutral rainbows. I probably could have hacked it together by assigning a colour to each line, but fortunately, I found the {ggnewscale} package by Elio Campitelli that allows you to use two scales. The plot below is the final product. You can find the code on Git.

I think {ggnewscale} is pretty neat and thought it was worth sharing.

## What does {ggnewscale} do exactly?

It allows you to apply multiple colour scales to a ggplot. You do this by

• First fitting one set of geoms and a scale
• Insert the function `new_scale_colour()` or `new_scale_fill()`
• Fit another set of geoms with a new scale

The `new_scale_*()` functions essentially partition the geoms that you need under each scale.

## Example

I’ll demonstrate. Let’s set up some data first.

```library(tidyverse)

df <- bind_rows(
"group1" = tibble(x = runif(2000)),
"group2" = tibble(x = runif(2000)),
.id = "group"
)
```
```df
# A tibble: 4,000 × 2
group      x
<chr>  <dbl>
1 group1 0.207
2 group1 0.102
3 group1 0.817
4 group1 0.321
5 group1 0.371
6 group1 0.406
7 group1 0.730
8 group1 0.673
9 group1 0.735
10 group1 0.358
# … with 3,990 more rows
```

I’ve taken 2000 random draws from a uniform distribution for two different groups. We’ll apply a colour gradient to `x`.

```df |>
ggplot() +
geom_jitter(
aes(x, group, colour = x),
df,
size = 8, alpha = 0.5) +
scale_colour_gradientn(colours = c("purple", "orange")) +
labs(
colour = "Purple-Orange",
y = "Group"
)
```

Both groups get the same colour scale applied, as per usual. To treat `group1` and `group2` differently and apply a different colour scale to each we use the `new_scale_colour()` function.

```library(ggnewscale)

df |>
ggplot() +

# apply the purple-orange gradient to group 1
geom_jitter(
aes(x, group, colour = x),
filter(df, group == "group1"),
size = 8, alpha = 0.5) +
scale_colour_gradientn(colours = c("purple", "orange")) +
labs(colour = "Purple-Orange") +

# start a new scale
new_scale_colour() +

# apply the black-grey gradient to group 2
geom_jitter(
aes(x, group, colour = x),
filter(df, group == "group2"),
size = 8, alpha = 0.5) +
scale_colour_gradientn(colours = c("black", "grey80")) +
labs(
colour = "Black-Grey",
y = "Group")
```

Done! There are a few ways to do this but this is the most convenient that I have found. It’s also neat that you can easily change the legend title to correspond to each palette.

This is simple to do for only 2 groups. For many groups it becomes a bit more arduous and may be worth trying to functionalise the geoms. Although having any more than two groups will start to look like someone vomited Skittles.

Follow me on social media: