'How can I add a legend for error bars in ggplot?
I have been trying to amend what I thought was a straightforward legend on my GGPlot for a day now and not making much progress (I have searched extensively on Stackexchange and can't see an obvious parallel).
Put simply: I am showing a revenue vs forecast bar chart where horizontal lines represent the forecast. I've managed to get the horizontal bars with a zero-width error bar. The columns are captured in the legend, but I can't figure out how to add a legend for the error bars:
Here is a reproducible example. I've added the full aesthetic settings I need in my final image, in case they are causing some clash I am missing:
df = data.frame(Team=c("Dunder Mifflin","Saber","Wernham Hogg",
"OsCorp","Queen Industries","Stark Industries"),
Industry=c("Paper","Paper","Paper",
"Tech","Tech","Tech"),
Revenue=c(20,100,10,
50,150,200),
Forecast=c(30,120,5,
70,120,120))
g1 = ggplot(df) +
geom_col(aes(x=Team,y = Revenue,fill=Industry)) +
geom_errorbar(aes(x=Team,y=Forecast, ymax=Forecast, ymin=Forecast)) +
# Everything from here probably irrelevant aesthetic settings,
# included in case there is some clash I am unaware of
scale_fill_hue(c = 40) +
facet_grid(cols = vars(Industry),
scales = "free_x",
space = "free_x",
switch="x") +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.line = element_line(),
strip.placement = "outside",
strip.text.x = element_text(size=10),
strip.background.x = element_rect(colour = "grey", fill = "white"),
text=element_text(family="Roboto",face="bold"))
print(g1)
Solution 1:[1]
Try this trick. You can use geom_line()
, pass a zero value and adding the option color='forecast'
. That will create a legend similar to that expected. Here the code:
library(ggplot2)
#Plot
ggplot(df) +
geom_col(aes(x=Team,y = Revenue,fill=Industry)) +
geom_line(aes(x=Team,y=0,color='forecast',group=1))+
geom_errorbar(aes(x=Team,y=Forecast, ymax=Forecast, ymin=Forecast)) +
# Everything from here probably irrelevant aesthetic settings,
# included in case there is some clash I am unaware of
scale_fill_hue(c = 40) +
scale_color_manual(values='black')+
facet_grid(cols = vars(Industry),
scales = "free_x",
space = "free_x",
switch="x") +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.line = element_line(),
strip.placement = "outside",
strip.text.x = element_text(size=10),
strip.background.x = element_rect(colour = "grey", fill = "white"),
text=element_text(family="Roboto",face="bold"))+
labs(color='')
Output:
Solution 2:[2]
You could use coord_cartesian to limit the axes and change the line so that it's below y=0, so something like this:
ggplot(df) +
geom_col(aes(x=Team,y = Revenue,fill=Industry)) +
geom_line(aes(x=Team,y=-10,color='forecast',group=1))+
geom_errorbar(aes(x=Team,y=Forecast, ymax=Forecast, ymin=Forecast)) +
scale_fill_hue(c = 40) +
scale_color_manual(values='black')+
facet_grid(cols = vars(Industry),
scales = "free_x",
space = "free_x",
switch="x") +
theme_bw() +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
axis.line = element_line(),
strip.placement = "outside",
strip.text.x = element_text(size=10),
strip.background.x = element_rect(colour = "grey", fill = "white"),
text=element_text(family="Roboto",face="bold"))+
labs(color='')+
coord_cartesian(ylim=c(0,200))
#assuming 200 is your ymax
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | strugglebus |