2

The solution to this previous question works fine (How can I make a legend in ggplot2 with one point entry and one line entry?) except when you change the label for the legend.

Here's what I mean. Some data:

library(ggplot2)
names <- c(1,1,1,2,2,2,3,3,3)
xvals <- c(1:9)
yvals <- c(1,2,3,10,11,12,15,16,17)
pvals <- c(1.1,2.1,3.1,11,12,13,14,15,16)
ex_data <- data.frame(names,xvals,yvals,pvals)
ex_data$names <- factor(ex_data$names)

This works fine:

ggplot(ex_data, aes(x=xvals, group=names)) 
   + geom_point(aes(y=yvals, shape='data', linetype='data')) 
   + geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) 
   + scale_shape_manual('', values=c(19, NA)) 
   + scale_linetype_manual('', values=c(0, 1))

But this doesn't (chart is empty):

ggplot(ex_data, aes(x=xvals, group=names)) 
   + geom_point(aes(y=yvals, shape='spreads', linetype='spreads')) 
   + geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) 
   + scale_shape_manual('', values=c(19, NA)) 
   + scale_linetype_manual('', values=c(0, 1))

(only difference is word data changed to spreads). Note that I can change data to abc and it works fine. Any clues? Thanks!

Community
  • 1
  • 1
user1
  • 33
  • 7
  • 1
    This is quite complicated situation. The reason is the order of shape aes for point and line. With 'data', 'data' appears before 'fitted', so 'data' is associated with value 19, and 'fitted' with `NA`. If 'data' is replaced by something that appears after 'fitted' dictionarily, than the association will be reversed, so you can not see any output. – kohske Dec 25 '13 at 04:19
  • Alphabetical order... Got it! Thanks – user1 Dec 25 '13 at 04:29

2 Answers2

2

The reason one of those works and the other doesn't is because when values is an unnammed vector, they "will be matched in order (usually alphabetical) with the limits of the scale" (http://docs.ggplot2.org/0.9.3.1/scale_manual.html). You changed which order is alphabetical.

So this works:

ggplot(ex_data, aes(x=xvals, group=names)) + 
  geom_point(aes(y=yvals, shape='spreads', linetype='spreads')) + 
  geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) + 
  scale_shape_manual('', values=c(NA, 19)) + 
  scale_linetype_manual('', values=c(1, 0))

Putting your values back in the original order but as named vectors also works (and seems safer / clearer):

ggplot(ex_data, aes(x=xvals, group=names)) + 
  geom_point(aes(y=yvals, shape='spreads', linetype='spreads')) + 
  geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) + 
  scale_shape_manual('', values=c("spreads"=19, "fitted"=NA)) + 
  scale_linetype_manual('', values=c("spreads"=0, "fitted"=1))
DavidC
  • 1,409
  • 10
  • 25
0

I don't know why that does not work. But if you just want Spread in label, the following solution works

ggplot(ex_data, aes(x=xvals, group=names)) + 
  geom_point(aes(y=yvals, shape='abc', linetype='abc')) + 
  geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) + 
  scale_shape_manual('', labels=c("Spread", "Fitted"),values=c(19, NA)) + 
  scale_linetype_manual('', labels=c("Spread", "Fitted"), values=c(0, 1))
Ananta
  • 3,671
  • 3
  • 22
  • 26