KeepNotes blog

Stay hungry, Stay Foolish.

0%

As indicated in the title, this article will discuss how to solve this problem in `ggplot2`.

I encounter this question when I want to construct two different color ranges to `col` aesthetic, such as `geom_line` and `geom_text`. Sometimes I may choose another way to visualize the data to avoid this situation, but I really want to know how to solve it if I have to use this color strategy.

From my Google search. I have found the best solution and it must be thanks to Elio Campitelli’s contribution, the author of the `ggnewscale` package. He demonstrates how to implement two color scales and explain what the principle is. You can refer to this article, Multiple color (and fill) scales with ggplot2.

Here I just show how it works. Firstly we prepare the dummy data.

``````library(tidyverse)
library(ggnewscale)

set.seed(123)
data <- tibble(
id = rep(1:5, each = 4),
day = sample(5:20, 20, replace = TRUE),
linecol = str_c("col", id),
day2 = day + 2,
label = rep(c("Group1", "Group2"), each = 10)
)``````

And then I’d like to draw a line plot with labels around it. The line colors are determined by the `linecol` variable, while label colors are by `label` group. Let's look at the error example that doesn’t work with no surprise.

``````data %>% ggplot(aes(x = day, y = id)) +
geom_line(aes(col = linecol)) +
scale_color_manual(values = c("red", "orange", "yellow", "green", "blue")) +
geom_text(aes(label = label, col = label)) +
scale_color_manual(values = c("blue", "orange"), guide = NULL)

# Error
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
Error in `palette()`:
! Insufficient values in manual scale. 7 needed but only 2 provided.``````

In order to solve it, you just need to add one line code as mentioned in that reference article. `structure(ggplot2::standardise_aes_names("colour"), class = "new_aes")` or the function `new_scale_color()` wrapped in `ggnewscale` package. If you want to use `scale_fill_*`, replacing "colour" to "fill" is fine.

So the final code without any error is shown below.

``````data %>% ggplot(aes(x = day, y = id)) +
geom_line(aes(col = linecol)) +
scale_color_manual(values = c("red", "orange", "yellow", "green", "blue")) +
structure(ggplot2::standardise_aes_names("colour"), class = "new_aes") +
# new_scale_color() +
geom_text(aes(label = label, col = label)) +
scale_color_manual(values = c("blue", "orange"), guide = NULL)``````

There is no doubt that this solution is not very common and formal. And I really hope it can be merged into `ggplot2` big family so that I only need to import one package. Ah!