Search code examples
rplotheatmaplatticelevelplot

Saturate a level plot to increase contrast at lower levels


Given a data set that looks like this:

D<-rep(seq(1,5),10)
T<-runif(50,1,20)
S<-c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9,10,10,10,10,10)
DF<-data.frame(D,T,S)

I make a level plot using the below code

library(lattice)
levelplot(T ~ S * D, data = DF,ylim=c(5,1),
xlab = "T", ylab = "S",
main = "LevelPlot", aspect=0.4,
col.regions =colorRampPalette(c('blue','red')),at=seq(0,20, length.out=120))

I want to focus on the subtle differences at the lower end of the data (The T variable) by increasing the contrast in colors. One way I've been able to do this is to change the "seq" argument to focus on data in the range of 0-5:

levelplot(T ~ S * D, data = DF,ylim=c(5,1),
xlab = "T", ylab = "S",
main = "LevelPlot", aspect=0.4,
col.regions =colorRampPalette(c('blue','red')),at=seq(0,5, length.out=120))

Now the contrast is where I want it to be, but I don't like that all data between 5-20 is blocked out. In other plotting programs I've been able to saturate the upper range so that all data above a certain value is represented by a single (max) color. In this case, all values above 5 would be red (and the color scale on the right would reflect this). Allowing for a more detailed contrast in color scale for values 0-5.

How is this possible to do in R?


Solution

  • You can use the colorkey and at to do this:

    my.brks <- seq(0, max(T), by = 3)
    my.at <- c(0, 1, 2, 3, 4, 5, round(max(T), 0))
    myColorkey <- list(at = my.brks, labels = list(at = my.brks, labels = my.at))
    
    levelplot(
      T ~ S * D,
      data = DF,
      ylim = c(5, 1),
      xlab = "T",
      ylab = "S",
      aspect = 0.4,
      at = my.at,
      col.regions = colorRampPalette(c('blue', 'red')),
      colorkey = myColorkey
    )
    

    enter image description here

    library(latticeExtra)
    levelplot(
      T ~ S * D,
      data = DF,
      ylim = c(5, 1),
      xlab = "T",
      ylab = "S",
      aspect = 0.4,
      at = my.at,
      col.regions = colorRampPalette(c('blue', 'red')),
      colorkey = myColorkey
    ) + layer(panel.text(S, D, round(T, 1)), data = DF)
    

    enter image description here