Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Legend in ggplot when aes() color and shape are not specified

Tags:

r

ggplot2

I am a relative newcomer to ggplot, and have made the figure below with the data and code included here…

The data is here

Data <- structure(list(IndID = structure(1:17, .Label = c("AA", "BB", 
"CC", "DD", "EE", "FF", "GG", "HH", "II", "JJ", "KK", "LL", "MM", 
"NN", "OO", "PP", "QQ"), class = "factor"), Avg = c(7.95, 10.483, 
5.951, 7.359, 10.465, 10.745, 14.402, 81.417, 67.087, 4.254, 
34.393, 47.324, 60.713, 75.446, 64.527, 28.779, 54.764), AvgSE = c(1.685, 
2.949, 1.097, 2.607, 4.256, 3.539, 1.702, 3.314, 0.714, 0.302, 
1.154, 1.827, 0.573, 1.292, 1.955, 1.341, 1.949), OBS = c(7.667, 
10, 8, 7.5, 14, 10.333, 12, 91, 53, 7, 29, 36.5, 43, 61, 61, 
24, 38)), .Names = c("IndID", "Avg", "AvgSE", "OBS"), class = "data.frame", row.names = c(NA, 
-17L))

And looks like this

> head(Data)
  IndID    Avg AvgSE    OBS
1    AA  7.950 1.685  7.667
2    BB 10.483 2.949 10.000
3    CC  5.951 1.097  8.000
4    DD  7.359 2.607  7.500
5    EE 10.465 4.256 14.000
6    FF 10.745 3.539 10.333

My code for the plot is here

ggplot(Data, aes(x=IndID, y=Avg))+
    geom_point()+
    geom_errorbar(aes(ymin=Avg-AvgSE, ymax=Avg+AvgSE))+
    geom_point(aes(y=OBS),color="red", pch = 8) +
    theme(axis.text.x=element_text(angle=30, hjust=1))

enter image description here

I have plotted two different sets of points. I do not have a factor to specify in the aes() argument as a color or shape. Most SO posts I have seen use these arguments after which a legend appears by default. As far as I can tell (after seeing many posts and using the R Graphics Cookbook), building a legend like in the base R functions is less straight forward.

Is the best option to change the data structure as suggested here http://stackoverflow.com/questions/17713919/r-ggplot-2-geom-points-how-to-add-a-legend using melt()?

Or is there another way to create a legend?

In my figure aboveI simply want a legend for each set of points. One for the black (Avg) pts and another for the OBS points.

Any suggestions would be appreciated!

like image 397
B. Davis Avatar asked Nov 13 '13 04:11

B. Davis


Video Answer


1 Answers

I think you really are better off reshaping your data, but here's one way of doing it. You need to map colour in aes() to make a legend. You can map it to a text string:

p <- ggplot(Data, aes(x=IndID, y=Avg))+
  geom_point(aes(color = "Avg"))+
  geom_errorbar(aes(ymin=Avg-AvgSE, ymax=Avg+AvgSE))+
  geom_point(aes(y=OBS, color = "OBS"), pch = 8, show_guide = T) +
  theme(axis.text.x=element_text(angle=30, hjust=1))

enter image description here

To get the colours the way you want, use scale_colour_manual(), and then you can override the shape of the legend using guides():

p + scale_colour_manual(values = c("black", "red")) + 
  guides(colour = guide_legend(override.aes = list(shape = c(16, 8))))

enter image description here

like image 82
alexwhan Avatar answered Nov 15 '22 08:11

alexwhan