Search code examples
rggplot2colorsaxis

Is there a way in R ggplot2 to turn the plot axes into a continuous color scale?


I have some code here that will use colorRampPalette() and scale_color_gradientn() to color the points along the scale of the limits.

Colors <- colorRampPalette(c("beige", "darkolivegreen1","green","aquamarine", "darkcyan",
"dodgerblue4", "purple4", "magenta3", "pink"))
Colors_range <- Colors(50)

ggplot(iris, aes(x = Petal.Width, y = Petal.Length, color = Petal.Length)) + 
  geom_point() + 
  facet_wrap(~ Species, scales = "free_y") +
  scale_color_gradientn(colors = Colors_range, limits = c(0,7)) 

I want there to be a way to adapt this to continuously color the y or x axes rather than the points. I can do one solid color with axis.line.y

ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) + 
  geom_point() + 
  facet_wrap(~ Species, scales = "free_y") +
  theme(axis.line.y = element_line(size = 3, color = "green", linetype=1))

I see a potential way to use geom_vline somehow but prefer axis.line.y in the respect that it doesn't shift the plot at all.

ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) + 
  geom_point() + 
  facet_wrap(~ Species, scales = "free_y") +
  geom_vline(xintercept = -0.1, color = "green", size = 3)

Solution

  • Not aware of an option to get a gradient colored axis line. Instead, if you want to fake an axis line then one option would be to use ggforce::geom_link2 where I set the limits via coord_cartesian:

    library(ggplot2)
    library(ggforce)
    
    ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +
      geom_point() +
      geom_link2(
        aes(color = Petal.Length, x = 0),
        linewidth = 1
      ) +
      facet_wrap(~Species, scales = "free_y") +
      coord_cartesian(clip = "off", xlim = range(iris$Petal.Width)) +
      scale_color_gradientn(colors = Colors_range, limits = c(0, 7))
    

    A second option would be to use a geom_line which however requires some additional data wrangling:

    dat_line <- iris |>
      split(~Species) |>
      lapply(\(x) {
        data.frame(
          Species = unique(x$Species),
          Petal.Width = 0,
          Petal.Length = seq(
            min(x$Petal.Length), max(x$Petal.Length),
            length.out = 100
          )
        )
      }) |>
      dplyr::bind_rows()
    
    ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) +
      geom_point() +
      geom_line(
        data = dat_line,
        aes(color = Petal.Length),
        linewidth = 1
      ) +
      facet_wrap(~Species, scales = "free_y") +
      coord_cartesian(clip = "off", xlim = range(iris$Petal.Width)) +
      scale_color_gradientn(colors = Colors_range, limits = c(0, 7))