user1
user1

Reputation: 33

How can I fix this strange behavior of legend in ggplot2?

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!

Upvotes: 2

Views: 611

Answers (2)

DavidC
DavidC

Reputation: 1441

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))

Upvotes: 2

Ananta
Ananta

Reputation: 3711

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))

Upvotes: 0

Related Questions