Home > database >  Setting scale limits with `lims` for fill
Setting scale limits with `lims` for fill

Time:08-22

I am trying to (naively?) set the limits of a color scale, but what happens is that the color scale itself is overridden additionally. What am I making wrong or how can it be done?

Simple example:

p <- volcano %>% reshape2::melt(varnames=c("x", "y")) %>% as_tibble() %>% 
  ggplot(aes(x,y, fill=value))   geom_tile()   
  scale_fill_gradientn(colours=hcl.colors(15, palette = "Purple-Green"))
p

This works as expected...

p   lims(fill=c(50,200))

changes the whole color scale: This does not

NB: In the real world example I want to center the color scale symmetrically around 0 with a diverging color scale and I do not want to use scale_fill_gradient2

Thanks in advance for any help!

CodePudding user response:

Ok, now I found the solution myself....

Did not know that there is a limits keyword directly:

volcano %>% reshape2::melt(varnames=c("x", "y")) %>% as_tibble() %>% 
    ggplot(aes(x,y, fill=value))   geom_tile()   
    scale_fill_gradientn(colours=hcl.colors(15, palette = "Purple-Green"), limits=c(50,200))

Still don't fully get, why lims overrides the whole scale. And this mean one cannot change the limits afterwards (as one can do x and y scales?

enter image description here

CodePudding user response:

The reason why lims doesn't work here is that it adds a whole new scale object to the plot which overrides the one you have already specified. If you look at the code for lims, it does its work through sending all its arguments individually to the generic function ggplot2:::limits. In your case, this invokesggplot2:::limits.numeric, which creates a new scale object via ggplot2:::make_scale. This function ends up just calling scale_fill_continuous.

As for why you can use lims after specifying an x or y scale without overwriting the existing one, the answer is: you can't, it does override the existing scale, and in fact warns you that it is doing so. Suppose we specify an x axis scale with lots of breaks in your example:

library(tidyverse)

p <- volcano %>% 
  reshape2::melt(varnames = c("x", "y")) %>% 
  as_tibble() %>% 
    ggplot(aes(x,y, fill = value))   
    geom_tile()   
    scale_fill_gradientn(colours = hcl.colors(15, palette = "Purple-Green"), 
                         limits = c(50, 200))  
    scale_x_continuous(breaks = 0:44 * 2)

p

Now look what happens if we add x axis lims to our scale:

p   lims(x = c(0, 90))
#> Scale for 'x' is already present. Adding another scale for 'x', which will
#> replace the existing scale.

We lost all our breaks, and got a warning that our x scale was being overwritten.

So the bottom line is that passing numbers to lims just adds a vanilla contnuous scale to whichever aesthetic you specify. Doing lims(fill = c(0, 10)) gives exactly the same result as scale_fill_continuous(limits = c(0, 10)). The answer, as you have found yourself, is to specify the limits argument directly in the scale you wish to add.

Created on 2022-08-21 with reprex v2.0.2

  • Related