1

I want to plot something where there is a natural midpoint, many values below the midpoint, and only a few above the midpoint. I want to make the values above the midpoint stand out. But because they are so close to the midpoint (by virtue of the distribution of the data), they are hard to see.

Here is an example:

library(ggplot2)
mtcars$qsec <- mtcars$qsec-21
sp2<-ggplot(mtcars, aes(x=wt, y=mpg, color=qsec)) + geom_point()
sp2+scale_color_gradient2(midpoint=0, low="blue", mid="white",
                          high="red", space ="Lab" )

enter image description here

I want reds between 0 and 1 to be just as red as blues between 0 and -6 are blue. How can I do this, while keeping my scales continuous?

Or is discretization the only option? If so, can I keep part of the scale continuous while making part of it discrete?

Henrik
  • 65,555
  • 14
  • 143
  • 159
generic_user
  • 3,430
  • 3
  • 32
  • 56
  • 1
    I think `scale_color_gradientn` may be useful here. See e.g. [asymmetric color distribution in scale_gradient2?](https://stackoverflow.com/questions/11299705/asymmetric-color-distribution-in-scale-gradient2) – Henrik Mar 19 '18 at 17:54

1 Answers1

3

As suggested by Henrik, scale_color_gradientn does the job. The extra computation that needs to be done is to calculate the midpoint when 1 is the highest value and 0 is the lowest value, which can be accomplished using (midpoint-min(mtcars$qsec))/(max(mtcars$qsec)-min(mtcars$qsec)).

library(ggplot2)
mtcars$qsec <- mtcars$qsec-21
sp2<-ggplot(mtcars, aes(x=wt, y=mpg, color=qsec)) + geom_point()
midpoint <- 0
sp2+scale_color_gradientn( colours = c("red","white","blue"),
                           values=c(1.0, (midpoint-min(mtcars$qsec))/(max(mtcars$qsec)-min(mtcars$qsec)),0))