0

I am an absolute beginner in ggplot2. I got frustrated with ggplot2 and started reading Wickham's awesome book. He says that "a scale is required for every aesthetic used on the plot.".

So, I did the following:

Try 1:

 huron <- data.frame(year = 1875:1972, level = as.numeric(LakeHuron))
   ggplot(huron, aes(year)) +
     geom_line(aes(y = level + 5, color = "y+5")) +
     scale_color_manual(values = c("orange")) +
     geom_line(aes(y = level - 5, color = "y-5")) +
     scale_color_manual(values = "blue") 

Upon running this, I get an error saying " insufficient value of colors provided."

I googled this and found the following thread on SO : ggplot2 Error: Insufficient values in manual scale. In original post, it makes sense why he/she added extra colors. However, I am not sure why this would be the case in my example because I have two layers, each with its own aesthetic.

Try 2

This code will work: (as in I can see two line plots in two different color and a legend--this is my objective)

ggplot(huron, aes(year)) +
     geom_line(aes(y = level + 5, color = "y+5")) +
     scale_color_manual(values = c("orange", "blue")) + #Added another color here.
     geom_line(aes(y = level - 5, color = "y-5")) 

Surprisingly, the above code shows something weird--I have got two aesthetics and only one scale.

Question 1: This is quite surprising because as we can see that there are two geoms but only one scale. Correct? I know Wickham cannot be wrong. So, what am I missing?

Question 2: Also, out of curiosity, if I have multiple geoms each with one aesthetic as in above case, and with one scale tied to each, how will ggplot know which scale ties back to which geom? As in, how would ggplot2 know whether layer1 goes with scale with color = red and layer2 goes with color = blue?

I'd sincerely appreciate your thoughts. Thanks in advance.


Community
  • 1
  • 1
watchtower
  • 4,140
  • 14
  • 50
  • 92
  • 1
    You have one aesthetic there. That you add two it with a second call to aes doesn't change that you define only the (one) color aesthetic mapping. There can only be one color scale in a ggplot2 plot. – Roland Aug 26 '16 at 06:02
  • @Roland Thanks for your help. So, if I understand you correctly--there can be at max ONLY one color scale for however number of aesthetics I have. However, what if I would want to change the color of different aesthetics--say in this example: `ggplot(mpg, aes(displ, hwy)) + geom_point(aes(colour = class)) + geom_smooth(method = "lm", se = FALSE, color = "red")` Here, I have different colors for two aesthetics. Isn't it? – watchtower Aug 26 '16 at 06:19
  • 1
    In this example you have one aesthetic mapping (`class` is mapped to color, and only this will result in a legend). Within `geom_smooth` you don't use `aes` and only define a "manual" color. – Roland Aug 26 '16 at 06:30
  • @Roland I see. Thanks. I think I am getting it. I got rid of aesthetic in above example because it wasn't solving any purpose: a) I couldn't get the color of `lm` line to red b) I didn't see the legend. Here's the code with `aes()`: `ggplot(mpg, aes(displ, hwy)) + geom_point(aes(colour = class)) + geom_smooth(method = "lm", se = FALSE, aes(color = "red"))` Do you think you can guide me what I can do to get the legend for lm and color changed to "red" instead of the default color. I am clueless. – watchtower Aug 26 '16 at 06:40

1 Answers1

2

To answer the specific question in the comments:

If you want to force specific colors, you need to use scale_color_manual. As the name suggests, this needs some manual work.

library(ggplot2)

#default colors
#http://stackoverflow.com/a/8197703/1412059
gg_color_hue <- function(n) {
  hues = seq(15, 375, length = n + 1)
  hcl(h = hues, l = 65, c = 100)[1:n]
}

ggplot(mpg, aes(displ, hwy)) + 
  geom_point(aes(colour = class)) + 
  geom_smooth(method = "lm", se = FALSE, aes(color = "model")) +
  scale_color_manual(values = setNames(c(gg_color_hue(length(unique(mpg$class))), "red"),
                                       c(unique(mpg$class), "model")))

resulting plot

However, I would use an additional aesthetic for the line type.

ggplot(mpg, aes(displ, hwy)) + 
  geom_point(aes(colour = class)) + 
  geom_smooth(method = "lm", se = FALSE, aes(linetype = "model"), color = "red")

second resulting plot

Roland
  • 127,288
  • 10
  • 191
  • 288
  • Awesome. I thought of using override.aes to display the legends: `ptry<-ggplot(mpg, aes(displ, hwy)) + geom_point(aes(colour = class)) + geom_smooth(method = "lm", se = FALSE, aes(color = "lm") ) + scale_color_manual("Direction",values = c("lm" = "purple", "2seater" = "green", "compact" = "blue", "midsize"="yellow", "minivan" = "magenta", "pickup" ="orange", "subcompact"="cyan", "suv"="red"))` Then, I'd override legends: `ptry + guides(guide_legend(override.aes = list(linetype = c(rep("blank",2),"solid",rep("solid",5))),shape = c(rep(16, 2), NA, rep(16, 5))))` . This doesn't work. – watchtower Aug 26 '16 at 07:28
  • @Roland--can you please help me understand what's wrong with my code above in the comments section? I'm sorry if the code isn't clear. I can add it with the question above. Please let me know. – watchtower Aug 26 '16 at 07:29
  • If you have a new question, please ask a new question. I have no idea what your are trying to achieve and thus don't know what "doesn't work" means. – Roland Aug 26 '16 at 07:32
  • @Roland--Sorry for being unclear. I ran out of space in comments section. I am trying to achieve the same graph like yours i.e. have separate legends for the line and factor colors. Using the first section of the code, I was able to show legend for colors and lm line. However, there are a few issues a) the legend is ordered alphabetically unlike yours. b) dots have a line and are not solid. c) lm line has a dot in the legend. Let me add my code above--what I was trying to do. It's the same question as above. – watchtower Aug 26 '16 at 07:35
  • 1
    This is turning into a chameleon question. I'll have to disengage. Ask a (new) focused, specific question with a clear and complete problem description if you need further help. – Roland Aug 26 '16 at 07:39
  • Sure, Roland. I will post another question. – watchtower Aug 26 '16 at 07:40
  • @Roland...This might be a dumb question, but I cleared all environment variables and was able to replicate the second plot in your post by just running the last three lines of the code. i.e. `ggplot(mpg, aes(displ, hwy)) + geom_point(aes(colour = class)) + geom_smooth(method = "lm", se = FALSE, aes(linetype = "model"), color = "red")` Can you please explain why you solved this problem in two parts? I didn't quite understand why you have written "I would use an additional aesthetic for the line type." I'd appreciate your thoughts. – watchtower Aug 26 '16 at 08:02
  • @ss0208535 If you are using color for the inside the` aes()` for the points and for smooth line then both will be in one legend because you can have only one legend for colors in ggplot2. Using linetype and color with different names makes two separate legends. – Didzis Elferts Aug 26 '16 at 08:08