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
p lims(fill=c(50,200))
changes the whole color scale:
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?
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