34

I am trying to plot data points with three different colors for three value ranges. For example:

library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + geom_point(aes(colour = qsec))

The above produces:

enter image description here

Now, I would like to modify this so that qseq values <17 are black, values between 17 and 19 are yellow and values above 19 are red. I've tried various approaches, but none of them seems to work:

  • Taken from here

      ggplot(mtcars, aes(wt, mpg)) + geom_point(aes(fill = qsec)) + 
      scale_fill_gradient(colours = c("black","yellow","red"), 
      breaks=c(0,17,19), labels = format(c("0","17","19")))
    

This produces:

enter image description here

So, the colorbar seems correct but the colors are not actually applied.

I realize I will probably need to use some kind of discrete scale instead of scale_fill_gradientn but my attempts to use scale_color_manual() fail:

ggplot(mtcars, aes(wt, mpg)) + geom_point(aes(color = factor(qsec))) + 
scale_color_manual(values=c("black", "yellow","red")
Error: Insufficient values in manual scale. 30 needed but only 4 provided.

I am guessing I will somehow have to use cut() or factor() but I can't seem to figure out how. Any suggestions?

Ivo
  • 3,890
  • 5
  • 22
  • 53
terdon
  • 3,260
  • 5
  • 33
  • 57

1 Answers1

49

You need to cut your values into intervals:

library(ggplot2)
ggplot(mtcars, aes(wt, mpg)) + 
  geom_point(aes(colour = cut(qsec, c(-Inf, 17, 19, Inf))),
             size = 5) +
  scale_color_manual(name = "qsec",
                     values = c("(-Inf,17]" = "black",
                                  "(17,19]" = "yellow",
                                  "(19, Inf]" = "red"),
                     labels = c("<= 17", "17 < qsec <= 19", "> 19"))

resulting plot

Roland
  • 127,288
  • 10
  • 191
  • 288
  • Hi @roland Would this scale_color_manual setting run with geom_line? – pacomet Jan 27 '16 at 12:29
  • A color scale is applied to all geoms for which a color is mapped. – Roland Jan 27 '16 at 12:39
  • I've tried to adapt your code to my data but could not succeed. What I need is to color a single geom_line() depending on the values of y. This image (https://www.dropbox.com/s/du6fjvr71vybhuu/Rplot.png?dl=0) shows what I'm looking for. Maybe I should open a question. – pacomet Jan 27 '16 at 13:58
  • 1
    Yes, you should. It doesn't seem that `geom_line` is the correct geom for your task. Maybe `geom_segment`? – Roland Jan 27 '16 at 14:02
  • Don't think `geom_segment` would run. The plot comes from `geom_smooth` Gonna ask the question. Thanks – pacomet Jan 27 '16 at 14:10