A.Benson
A.Benson

Reputation: 479

Gradient colour fill a barplot in ggplot2

I'd like to gradient fill a ggplot2 bar plot based on the values of Y, but I'd like to manually set the colours. This example is almost what I need, but it sets the limits of the colour palette based on the values of Y, whereas I want to set these manually based on a biological stress threshold

Here's some sample code based on the linked example.

 d <- data.frame(x = 1:4, y= c (0.1, 0.3, 1, 0.6))
    
    # interpolate values from zero to y and create corresponding number of x values
    vals <- lapply(d$y, function(y) seq(0, y, by = 0.01))
    y <- unlist(vals)
    mid <- rep(d$x, lengths(vals))
    d2 <- data.frame(x = mid - 0.4,
                     xend = mid + 0.4,
                     y = y,
                     yend = y)
    
    ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
      geom_segment(size = 2) +
      scale_color_gradient2(low = "green4", mid = "yellow", high = "red", 
                            midpoint = max(d2$y)/2) +
      coord_cartesian(ylim = c(0 , 2))

enter image description here

I'd like the red to appear when the Y value is equal to 2, rather than the maximum value of Y in the data frame.

Upvotes: 1

Views: 1514

Answers (2)

phalteman
phalteman

Reputation: 3542

If you know a priori what the values are that you'd like to be red (in your case, 2), you can just set the midpoint at half of that (1).

Your example, but with an extra data point to illustrate:

# d <- data.frame(x = 1:4, y= c(0.1, 0.3, 1, 0.6))
d <- data.frame(x = 1:5, y= c(0.1, 0.3, 1, 0.6, 2.0))
vals <- lapply(d$y, function(y) seq(0, y, by = 0.01))
y <- unlist(vals)
mid <- rep(d$x, lengths(vals))
d2 <- data.frame(x = mid - 0.4, xend = mid + 0.4, y = y, yend = y)

ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
  geom_segment(size = 2) +
  scale_color_gradient2(low = "green4", 
                        mid = "yellow", 
                        high = "red", 
                        midpoint = 1) + # changed here
  coord_cartesian(ylim = c(0 , 2))

enter image description here

As noted in the comments on the other answer, you won't see red in your original data - rerun the code here with your original dataset to see the result.

Upvotes: 1

Karthik Thrikkadeeri
Karthik Thrikkadeeri

Reputation: 356

Does this work? Just switched to scale_color_gradientn which allows us to use the values = call where we specify three values for the respective colours. (And a couple of other small changes.)

    
    ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
      geom_segment(size = 2) +
      scale_y_continuous(limits = c(0, 2)) +
      scale_color_gradientn(colours = c("green4", "yellow", "red"), 
                            values = c("0", max(d2$y)/2, "2")) 

Upvotes: 0

Related Questions