ggplot colour_gradient2() - midpoint works unexpected

Viewed 56

I have want to create a line plot with a gradient colouring aesthetic if a certain value drops below a threshold:

library(tidyverse)
foo <- tribble(
    ~x, ~y, ~c
    , 1, 1, 1
    , 2, 2, 2
    , 3, 3, 3
    , 4, 4, 4
)

foo %>%
    ggplot(aes(x, y, colour = c)) +
    geom_line(size = 3) +
    scale_colour_gradient2(low = "red", mid = "green", high = "green", midpoint = 3)

enter image description here

I want to create multiple of these plots with the same colouring logic, i.e. a gradient between green and red for 1 <= c <= 3. But when the underlying data changes, the colour gradient changes as well:

foo <- tribble(
    ~x, ~y, ~c
    , 1, 1, 1
    , 2, 2, 2
    , 3, 3, 3
    , 4, 4, 100
)

foo %>%
    ggplot(aes(x, y, colour = c)) +
    geom_line(size = 3) +
    scale_colour_gradient2(low = "red", mid = "green", high = "green", midpoint = 3)

enter image description here

I hope someone has a better answer than recalculating the underlying variable (foo %>% mutate(c = ifelse(c > 4, 4, c))).

1 Answers

This solution uses scale_color_gradientn with scales::rescale. The rescale function default is to = c(0, 1), meaning, the vector of values is rescaled to values in that range.

foo %>%
  ggplot(aes(x, y, colour = c)) +
  geom_line(size = 3) +
  scale_colour_gradientn(colors = c("red", "green", "green"), 
                         values = scales::rescale(foo$c))

enter image description here

Related