I am trying to make a plot to show the returns of various securities in a portfolio in a bar plot and then superimpose points over the bars indicating exposure to those securiti
ggplot generates legends only when you create an aesthetic mapping inside aes. This is usually done by mapping a data column to an aesthetic, like fill, shape, or color. Here we don't actually want to map avg_weight to an aesthetic, so we'll use shape as a "dummy" aesthetic, just to get the legend.
First, set a seed for data reproducibility:
# Set a seed for reproducibility
set.seed(4)
out<-data.frame(security=c("A", "B", "C", "D", "A", "B", "C", "D"),
avg_weight=c(0.1,0.2,0.3,0.4, 0.1, 0.2, 0.3, 0.4),
return_type=c(rep("systematic",4), rep("idiosyncratic",4)), return=cumsum(rnorm(8,0,0.1)))
In the code below, we add a "dummy" shape aesthetic to geom_point so that a shape legend will be generated. Then in labs we set shape=NULL so that the shape legend won't have a title.
ggplot(data=out, aes(x=security)) +
geom_bar(stat="identity", aes(y=return, fill=return_type, group=return_type), position="dodge") +
geom_point(aes(y=avg_weight, shape="Exposure")) +
ggtitle("Systematic and Idiosyncratic Returns") +
theme(axis.text.x=element_text(angle=70, hjust=1)) +
labs(x="Security Description", y="Return", shape=NULL) +
theme_classic()