Position geom_text in the middle of each bar segment in a geom_col stacked barchart

gosz picture gosz · Nov 21, 2016 · Viewed 20.4k times · Source

I would like to position the corresponding value labels in a geom_col stacked barchart in the middle of each bar segment.

However, my naive attempt fails.

library(ggplot2) # Version: ggplot2 2.2

dta <- data.frame(group  = c("A","A","A",
                             "B","B","B"),
                  sector = c("x","y","z",
                             "x","y","z"),
                  value  = c(10,20,70,
                             30,20,50))

ggplot(data = dta) +
  geom_col(aes(x = group, y = value, fill = sector)) +
  geom_text(position="stack",
            aes(x = group, y = value, label = value)) 

Obviously, setting y=value/2 for geom_text does not help, either. Besides, the text is positioned in the wrong order (reversed).

Any (elegant) ideas how to solve this?

Answer

aosmith picture aosmith · Nov 21, 2016

You need to have a variable mapped to an aesthetic to represent the groups in geom_text. For you, this is your "sector" variable. You can use it with the group aesthetic in geom_text.

Then use position_stack with vjust to center the labels.

ggplot(data = dta) +
    geom_col(aes(x = group, y = value, fill = sector)) +
    geom_text(aes(x = group, y = value, label = value, group = sector),
                  position = position_stack(vjust = .5))

You could save some typing by setting your aesthetics globally. Then fill would be used as the grouping variable for geom_text and you can skip group.

ggplot(data = dta, aes(x = group, y = value, fill = sector)) +
    geom_col() +
    geom_text(aes(label = value),
              position = position_stack(vjust = .5))

enter image description here