Search code examples
rggplot2rangeheatmapgeom

R ggplot scale_fill_manual using colors for values within a range


I'm just hoping to clean up my code and learn a thing or two. I feel like I'm making this more difficult than it should be. I have a range of data from 0-9 and I would like to specify a color for values in that range. For example:

0-3 green
4-6 yellow
7-9 red

This is the only way I was able to make it work. I feel like there should be a way to specify ranges in the breaks. i.e. 0-3 = green, etc.

ggplot() +
  geom_raster(data = data, aes(x = samples, y = organism, fill = as.factor(value))) +
  scale_fill_manual(values=c("green", "green", "green","green", "yellow","yellow","yellow", "red","red", "red"), breaks=c(0,1,2,3,4,5,6,7,8,9))

The following code works fine, but whenever I try to create a range within the breaks I get the error:

breaks=c(0-3,4-6,7-9)
Error: Insufficient values in manual scale. 10 needed but only 3 provided.

I hope this is fairly self explanatory. I can provide a sample data set (below) if needed. Thank you for your time!

samples,organism,value
a,z,0
b,z,1
c,z,2
d,z,3
e,z,4
f,z,5
g,z,6
h,z,7
i,z,8
j,z,9

Solution

  • I don't have your data, but I made some that I think looks like yours:

    set.seed(123)
    data <- expand.grid(samples = 1:5, organism = LETTERS[1:4])
    data$value <- sample(0:9, 20, replace = TRUE)
    

    With this data, I get a different error running your code:

    ggplot() +
      geom_raster(data = data, aes(x = samples, y = organism, fill = value)) +
      scale_fill_manual(values=c("green", "green", "green", "green", "yellow", "yellow", "yellow", "red", "red", "red"), 
                        breaks=c(0,1,2,3,4,5,6,7,8,9))
    Error: Continuous value supplied to discrete scale
    

    If I convert value to a factor, I get no error. I would need your data to help diagnose the error.

    ggplot() +
      geom_raster(data = data, aes(x = samples, y = organism, fill = factor(value))) +
      scale_fill_manual(values=c("green", "green", "green", "green", "yellow", "yellow", "yellow", "red", "red", "red"), 
                        breaks=c(0,1,2,3,4,5,6,7,8,9))
    

    enter image description here

    Using my data, here is a simpler way to do this (especially if value is continuous):

    ggplot() +
      geom_raster(data = data, aes(x = samples, y = organism, 
                                   fill = cut(value, breaks = c(0, 3, 6, 9)))) +
      scale_fill_manual(name = "value", 
                        values = c("green", "yellow", "red"),
                        labels = c("0-3", "4-6", "7-9"))
    

    enter image description here