2

I followed this link, trying to

  • make 0 as white
  • values more than 2 the same colour

The code below

library(reshape2)
library(ggplot2)
library(scales)
ran <- matrix(nrow = 3, ncol = 2, c(-2,-1,0,1,2,3))
ran_melt <- melt(ran)
ggplot(ran_melt, aes(Var1, Var2)) +
  geom_tile(aes(fill = value), color = "white") +
  scale_fill_gradientn(colours = c("red", "white", "blue"),
                       values = rescale(c(min(ran_melt$value), 0, max(ran_melt$value)))) +
  labs(fill = 'legend')

will plot this

enter image description here

If I change max(ran_melt$value) to 2:

ggplot(ran_melt, aes(Var1, Var2)) +
  geom_tile(aes(fill = value), color = "white") +
  scale_fill_gradientn(colours = c("red", "white", "blue"),
                       values = rescale(c(min(ran_melt$value), 0, 2))) +
  labs(fill = 'legend')

I got this: enter image description here

So how can I achieve my two goals?

Henrik
  • 65,555
  • 14
  • 143
  • 159
lanselibai
  • 1,203
  • 2
  • 19
  • 35

1 Answers1

2

You can use arguments limits and oob in scale_fill_gradientn to achieve what you're after:

ggplot(ran_melt, aes(Var1, Var2)) +
    geom_tile(aes(fill = value), color = "white") +
    scale_fill_gradientn(
        colours = c("red", "white", "blue"),
        limits = c(-2, 2),
        oob = squish) +
  labs(fill = 'legend')

enter image description here

Explanation: oob = squish gives values that lie outside of limits the same colour/fill value as the min/max of limits. See e.g. ?scale_fill_gradientn for details on oob.


Update

If you have asymmetric limits you can use argument values with rescale:

ggplot(ran_melt, aes(Var1, Var2)) +
    geom_tile(aes(fill = value), color = "white") +
    scale_fill_gradientn(
        colours = c("red", "white", "blue"),
        limits = c(-1, 2),
        values = rescale(c(-1, 0, 2)),
        oob = squish) +
    labs(fill = 'legend')

enter image description here

Maurits Evers
  • 49,617
  • 4
  • 47
  • 68
  • Thank you, but in this case, the 0 value should be in the middle of the `limits` so that it can be white. Can I make 0 value still white while setting `limits = c(-1, 2)`? – lanselibai May 01 '18 at 12:54
  • @lanselibai I don't understand your comment. The `0` value *is* in the middle and white in above example! If you have non-symmetric limits this will not work. – Maurits Evers May 01 '18 at 12:58
  • Okay, is there a way that from -1 to 0: red to white; from 0 to 2: white to blue? – lanselibai May 01 '18 at 13:00
  • @lanselibai Sure, please take a look at my updated answer. – Maurits Evers May 01 '18 at 13:03