3
votes

I want to set the thresholds at which the extreme colors are achieved, that is, given a gradient from color1 to color2 and a corresponding variable z, I want to define values c_min and c_max such that all points for which the value of z is over c_max have color2, and all points with the value of z is below c_min have color color1. Example:

df <- data.frame(x=rnorm(10), y=rnorm(10), z=c(-100, rnorm(8), 100))
ggplot(df, aes(x=x, y=y, col=z)) + geom_point() + 
  scale_color_gradient2(low="blue", mid="white", high="red")

Clearly, this is not satisfactory: most of the points will be white, only the extremes will have color. I would prefer to span the gradient between -3 and 3, and everything outside of these values should be either blue or red.

Of course, I could generate a gradient manually and use scale_color_manual to set the colors of the points:

pal <- colorRampPalette(c("blue", "white", "red"))(17)
breaks <- seq(-3, 3, length.out=16)
cols <- pal[findInterval(df$z, breaks) + 1]
plot(df$x, df$y, pch=19, col=cols)

## or, in ggplot
ggplot(df, aes(x=x, y=y, col=factor(1:nrow(df)))) + 
   geom_point() + scale_color_manual(values=cols)

How can I do that in ggplot2? Preferably, without manually calculating the gradient?

1

1 Answers

5
votes

One option is to set the limits of a scale and squish anything that exceeds the limits (out-of-bounds/oob values) to the nearest extreme:

ggplot(df, aes(x=x, y=y, col=z)) + geom_point() + 
  scale_color_gradient2(low="blue", mid="white", high="red", 
                        limits = c(-3, 3), oob = scales::squish)

enter image description here

Another option is to manually set the positions (after rescaling to [0-1] range) where colours should occur in scale_color_gradient. "blue" and "red" are repeated to give both the extremes (0, 1) and the rescaled -3/3 (0.485/0.515) that colour.

ggplot(df, aes(x=x, y=y, col=z)) + geom_point() + 
  scale_color_gradientn(colours = c("blue", "blue", "white", "red", "red"),
                        values = c(0, 0.485, 0.5, 0.515, 1))

enter image description here