1

I'm trying to use scale_colour_gradientn to clearly show neg vs pos values: negative is blue, positive is red. But gradientn seems to ignore my vector of colors, and just makes one big gradient instead of n small gradients. Here's my sample code ...

xx <- -100:100
yy <- xx
fma <- data.frame( xx, yy)
ggplot( fma) +
  geom_point( aes( xx, yy, col=yy)) +
  scale_colour_gradientn(
    colours=c('#0000ff','#0000ff','#ff0000','#ff0000'),
    values=c(  -100,       -1,      1,      100))

How can I convince gradientn to color everything in [-100,-1] blue and everything in [1,100] red?

camille
  • 16,432
  • 18
  • 38
  • 60
Sullivan
  • 443
  • 1
  • 6
  • 14
  • 1
    Possible duplicate: https://stackoverflow.com/questions/18487369/ggplot-set-scale-color-gradientn-manually (the values should go from 0 to 1, they do not correspond to the values in your data). – MrFlick Aug 17 '18 at 19:36
  • From the docs for `scale_color_gradientn` regarding `values`: if colours should not be evenly positioned along the gradient this vector gives the position (between 0 and 1) for each colour in the colours vector. – camille Aug 17 '18 at 19:38
  • Thanks, the comments are very helpful. – Sullivan Aug 17 '18 at 20:07

2 Answers2

4

if you'd like to keep the color scale as a gradient, instead of a dichotemous scale, you could do this:

xx <- -100:100
yy <- xx
fma <- data.frame( xx, yy)
ggplot( fma) +
  geom_point( aes( xx, yy, col=yy)) +
  scale_colour_gradientn(
    colours=c('indianred4','indianred1','white','darkseagreen1','darkseagreen4'),
    values=c(  0,       49.5,  50,    50.5,      100)/100)

enter image description here

the values-argument only takes values between 0 and 1, which means that in your case, -100 is equal to 0, and 100 is 1.

I have added the color white, which corresponds to ~0, for neutrality. This white range could be expanded, by setting .495 to something like .40, and .50 to .50

also notice that I'm making a vector for the values argument without decimals, for convenience and readability, and then dividing it with a 100, to rescale it so the values argument can use it.

emilBeBri
  • 625
  • 13
  • 18
1

Rather than use scale_color_continuous, I'd make a factor variable that tells what color to color those points and use scale_color_discrete or *_manual. In this example, we use a conditional in the aes so col receives either TRUE or FALSE depending on the value of yy, but if you wanted more possible values, you could use switch or case_when to populate a yy_range variable with the possible color categories.

ggplot(fma) +
    geom_point(aes( xx, yy, col = yy < 0)) +
    scale_color_discrete(c('#0000ff','#ff0000'))

enter image description here

divibisan
  • 11,659
  • 11
  • 40
  • 58