Reputation: 151
I am trying to create a legend when using ggplot2 and geom_point. I have a dataframe that looks like this
d <- data.frame(variable = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J"),
value = rnorm(10, 3),
Schoolave = rnorm(10, 3),
districtave = rnorm(10, 3),
max = rnorm(10, 3),
min = rnorm(10, 3))
I want to make a plot that looks like this.
plot <- ggplot(data = d, aes(x = variable, y = value)) + geom_errorbar(ymax = d$max, ymin = d$min)
plot <- plot + coord_flip()
plot <- plot + geom_point(data = d, aes(x = variable, y = value),
shape = 1, size = 5)
plot <- plot + geom_point(data = d, aes(x = variable, y = districtave), shape = 0, size = 4)
plot <- plot + geom_point(data = d, aes(x = variable, y = Schoolave), shape = 2, size = 3)
plot <- plot + theme_bw() + theme(legend.position= "bottom")
plot
I would like a legend that tells them the circle for your average score. The triangle is the average score for your school. The square is the average for the district. I have looked for a way to do this can't find a way. Any help would be appreciated.
Upvotes: 3
Views: 3812
Reputation: 146224
ggplot
likes tidy data, which means you have to melt your data into long format.
library(reshape2)
d.points = melt(d[, c("variable", "value", "Schoolave", "districtave")],
id = "variable",
variable.name = "type")
Now your data has a single column that we'll map to shape
, so the auto legend will work.
And there's no need to add to the same plot and save it every single line, just add it all at once.
And please don't specify the data$column
inside of aes()
! It will cause problems if you ever want to facet or do more advanced plots. You specify the data upfront, so you don't have to say it again inside aes()
. And do use aes()
for all your aesthetic mappings, like the min and max of the errorbar.
plot <- ggplot(data = d, aes(x = variable, y = value)) +
geom_errorbar(aes(ymax = max, ymin = min)) +
coord_flip() +
geom_point(data = d.points,
aes(x = variable, y = value, shape = type),
size = 5) +
scale_shape_manual(values = 1:3, name = "") +
theme_bw() +
theme(legend.position= "bottom")
plot
If you want nicer labels, you can specify them in the shape scale. On a horizontal legend, I like to add in a little white space, something like this:
scale_shape_manual(values = 1:3, name = "",
labels = c("Individual Average ", "School Average ", "District Average ")) +
Upvotes: 5