1
votes

Given a data set like this:

TT <- c(23.67, 23.67, 23.68, 23.67, 23.67, 23.67, 23.66, 23.59, 23.54, 23.30, 20.65, 16.13,
       13.39, 12.81, 12.04, 11.70, 11.42, 11.24, 10.86, 10.63,  9.88,  9.19,  8.79,  8.37,
       7.85,  7.36,  7.10,  6.99,  6.88,  6.69,  6.39,  6.35,  6.31,  6.25,  6.18,  6.02,
       6.00,  5.96,  5.93,  5.93,  5.86,  5.85,  5.85,  5.85,  5.82,  5.80,  5.78,  5.75)

x <- rep(1, 48)
D <- seq(1, 48)

DF <- data.frame(D, x, TT)

My goal is to plot out the differences in T using a color pallet from Red to Blue. My current plot looks like this:

gg <- ggplot(data = DF, aes(x = x, y=D, height = 1.1, width = 1.3, fill = TT))+
  geom_tile() +  
  scale_fill_gradient(high = "firebrick2", low = 'dodgerblue2', 
                      na.value = 'grey50', space = "Lab",
                      lim = c(min(DF$T), max(DF$T)))
gg

But I would like to emphasize the graduations in change at the lower end of the spectrum (say changes between 7 and 5). Is there a way in ggplot I can saturate the higher values so they are all represented by a single (or similar looking) red color, leaving most of the gradient between red and blue to represent the changes between 7 and 5?

2

2 Answers

3
votes

While @Z.lin answer and @Axeman comment addresses the question on how to squish higher values and emphasize difference in the lower values as the OP requested, I would suggest to the OP a different way to approach the problem. I tend to disfavor the requested approach of squishing high values as it's deceptive in portraying the real range of the data visually.

I will propose an alternate solution, which is to log transform your values so that your gradient scale still accurately describes your data range. Given your data range, a log 2 transformation seems adequate, e.g.:

log2(6)
[1] 2.584963
log2(12)
[1] 3.584963
log2(24)
[1] 4.584963

ggplot(data = DF, aes(x = x, y=D, height = 1.1, width = 1.3, fill = log2(TT)))+
  geom_tile() +  
  scale_fill_gradient(high = "firebrick2", low = 'dodgerblue2', 
                      na.value = 'grey50', space = "Lab",
                      lim = c(log2(min(DF$T)), log2(max(DF$T))))

enter image description here

2
votes

Setting everything larger than 7 outside your fill limits (which will assign na.value to them) & picking a slightly darker shade of red for your na.value should do the job:

ggplot(DF,
       aes(x = x, y = D, fill = TT)) +
  geom_tile() +
  scale_fill_gradient(high = "firebrick2",
                      low = "dodgerblue2",
                      na.value = "firebrick3", # red for NA values
                      lim = c(min(DF$TT), 7))  # every TT value larger than 7 will be NA

plot

Note: I named the column TT instead of T, as T is shorthand for TRUE in R. Less confusing that way.