Search code examples
rggplot2geom-textgeom-col

How to align geom_text labels above dodged geom_col


I can't seem to find a way to get the text labels on this (dodged) geom_col to line up according to their respective columns.

I have tried numerous suggestions solutions on SO and other sites, and this is the closest I could get:

enter image description here

How do I fix this?

Code:

ggplot(leads[leads$key_as_string <= max(leads$key_as_string) - 1, ], aes(fill = type)) +
  geom_col(aes(x = key_as_string, y = doc_count),
           colour = "black",
           position = position_dodge(1)) +
  scale_y_continuous(limits = c(0, max(leads$doc_count))) +
  geom_text(aes(x = key_as_string, y = doc_count, label = doc_count, group = key_as_string),
            hjust = 0.5,
            vjust = -0.5,
            size = 3,
            colour = "black",
            position = position_dodge(1)) +
  theme(panel.grid.minor.x = element_blank(),
        panel.grid.major.x = element_blank(),
        axis.text = element_text(colour = "black"))

Solution

  • As per my comment, group = key_as_string is the culprit here. The code is essentially telling ggplot to keep both labels with the same key_as_string value in the same group, negating the dodge command.

    Illustration with the diamonds dataset below. We can see that removing the group aesthetic mapping changes the labels' positions:

    p <- ggplot(diamonds %>%
                  filter(cut %in% c("Fair", "Good")) %>%
                  group_by(cut, clarity) %>%
                  summarise(carat = mean(carat)), 
                aes(clarity, carat, fill = cut, label = round(carat, 2))) + 
      geom_col(position = position_dodge(1))
    
    gridExtra::grid.arrange(
      p + geom_text(position = position_dodge(1), aes(group = clarity)),
      p + geom_text(position = position_dodge(1)),
      ncol = 1
    )
    

    plot