rggplot2aestheticsgeom-col

how to add lines over a column bar graph where the lines pass by the middle-top of the bars considering bars with position='dodge'?


Here I provide an example of what I have tried:

df <- data.frame(a = rep(c(1:12), each = 2),
                 b = c("yes", "no"),
                 c = sample(x = 1:200, size = 24))

ggplot(df, aes(x = a, y = c)) + 
  geom_col(aes(fill = b), position = 'dodge') +
  scale_x_continuous(breaks = min(a):max(a)) +
  geom_line(aes(x = a, y = c, group = b), stat = "identity")

So basically what I want to obtain is two bars for each xtick, with a line for each bar set passing by the top-center of each matching bar. I would want these two lines to have colours corresponding to the bar set they match.

I have seen a question posted here for C language. It had some similarities to this question but it was not much of a help.

If anyone knows how to achieve this I would be thankful :)


Solution

  • The key is to set position = position_dodge() in both geom_col and geom_line.

    If you set the line color as the same color as the bar, it's very hard to visualise the lines. Here I manually set "no" to "black" and "yes" to "firebrick" by scale_color_manual. Remove the code scale_color_manual(values = c("no" = "black", "yes" = "firebrick"), name = "line") to align the colors with the bars.

    library(ggplot2)
    df <- data.frame(a = rep(c(1:12), each = 2),
                     b = c("yes", "no"),
                     c = sample(x = 1:200, size = 24))
    
    ggplot(df, aes(x = a, y = c, group = b, fill = b)) + 
      geom_col(position = position_dodge(width = 1)) +
      geom_line(aes(col = b), position = position_dodge(width = 1)) +
      scale_color_manual(values = c("no" = "black", "yes" = "firebrick"), name = "line")
    

    Created on 2022-05-05 by the reprex package (v2.0.1)