geom_text() labels don't honor the position argument

I want to add custom label colors to a bar plot. By adding a colour aes inside a geom_text() layer, the position alignment of the labels gets loss.

Is something I'm missing? It's a bug?

library(dplyr, warn.conflicts = FALSE)
library(ggplot2)

df <- mtcars %>% 
  count(across(c(cyl, gear), as.factor)) %>% 
  mutate(text_colour = if_else(gear == 3, 'white', 'blue'))

g <- ggplot(data = df,
            aes(x = cyl, y = n, fill = gear)) +
  geom_col()

# Reference
g + geom_text(aes(label = n),
              position = position_stack(vjust = 0.5))

# Expected output: Labels at the same position as previous plot.
# The labels don't respect the position argument.
g + geom_text(aes(label = n,
                  colour = text_colour),
              position = position_stack(vjust = 0.5))
# Here should go a `scale_colour_identity()` scale. It's not necessary to show my problem.

Created on 2021-01-11 by the reprex package (v0.3.0)

add group=gear to the main aes() of your ggplot, this should restore the preferred positioning of your labels.
also you can wrap text_colour with I() to treat the contents as values to use like

 colour = I(text_colour)

in your geom_text.

Thanks @nirgrahamuk.

As I understand it, by adding the color aes(), that layer frees himself of the main aesthetics. I could have fixed it by adding also "fill = gear" again in geom_text().

g + geom_text(aes(label = n,
                  fill = gear,
                  colour = I(text_colour)),
              position = position_stack(vjust = 0.5))

The I () tip is great!

1 Like