Search code examples
rggplot2bar-chartlegendlegend-properties

Add horizontal lines to stacked barplot in ggplot2 in R, and show in legend


I have a stacked barplot, something like the example below.

I want to add one or two sets of horizontal lines (specifying colour and line type) across each bar, at different values for each bar, and add these to the legend.

Titanic.df <- as.data.frame(Titanic)

Titanic.ag <- aggregate( Freq ~ Sex + Class + Age, data=Titanic.df, sum, subset = Survived == "Yes")

bars <- rep(c(0.5, NA, 0.7, NA, 0.6, NA, 0.9, NA), 2)

ggplot(Titanic.ag, aes(x = Class, y = Freq, fill = Sex)) + 
  geom_bar(position = "fill", stat = "identity") + 
  facet_grid(~Age) +
  geom_errorbar(aes(y = bars, ymin = bars, ymax = bars,  col = "Ref1")) + 
  scale_fill_manual(values = c("darkgreen", "darkblue") ) + 
  labs(col = "Reference",
       fill= "",
       y = "Proportion",
       x = "Class")

titanic stacked bar plot with horizontal lines

I have tried using geom_errorbar() as suggested on several questions, but I am stuck with two things:

If I add a vector of values for the error bars, then ggplot expects the same length as in the dataframe (eg 16 in Titanic.ag), but there are only 8 bars as they are stacked. This is why I have used NAs in bars above. Is there an alternative?

More importantly, I want to control colour and line type, but if I add these to geom_bar(), I lose my legend. e.g.

  geom_errorbar(aes(y = bars, ymin=bars, ymax=bars,  col = "Ref1"), col = "red", linetype = 2)

Is geom_segment() an alternative?

Edited typos, clarified different values of horziontal lines.


Solution

  • The answer above doesn't produce a legend. It does change the linetype and colour, but I also showed this in my original question. After some searching I've found a way to add a legend, so I've posted here.

    library(ggplot2)
    
    Titanic.df <- as.data.frame(Titanic)
    
    Titanic.ag <- aggregate( Freq ~ Sex + Class + Age, data=Titanic.df, sum, subset = Survived == "Yes")
    
    bars <- rep(c(0.5, NA, 0.7, NA, 0.6, NA, 0.9, NA), 2)
    
    ggplot(Titanic.ag, aes(x = Class, y = Freq, fill = Sex)) + 
      geom_bar(position = "fill", stat = "identity") + 
      facet_grid(~Age) +
      geom_errorbar(aes(y = bars, ymin = bars, ymax = bars,  col = "Ref1"), linetype = 2, size = 1) + 
      scale_fill_manual(values = c("darkgreen", "darkblue") ) + 
    
      scale_colour_manual(name='', values=c("Ref1" = "darkred"), guide ="legend") +
      guides(col = guide_legend(override.aes = list(linetype=2), title = "Reference")) + 
    
      labs(fill= "",
           y = "Proportion",
           x = "Class")
    

    This can be adapted to add a further geom_errorbar().

    I still get the warning due to the workaround with the the NAs in the geom_errorbar() vector for y, ymin and ymax, this gets more complicated with more facets, but it works.