OP, try to provide a full representative example in the future. Regardless, here's your plot pretty much replicated:
library(ggplot2)
df <- data.frame(
value=c(12, 17, 14, 46, 41, 66, 14, 14, 14, 27, 28, 7),
category=rep(LETTERS[1:4], each=3),
gender=rep(c("Male", "Female", "Other"), 4)
)
ggplot(df, aes(x=gender, y=value)) +
geom_col(aes(fill=category), position=position_stack(vjust=0.5, reverse = TRUE)) +
geom_text(
aes(label=paste(value,"%")), size=5,
position=position_stack(vjust=0.5)) +
scale_fill_viridis_d()
To apply the different color based on a criteria, you can just specify that criteria directly to the color=
aesthetic in geom_text()
. Here, I'm just going to use an ifelse()
function to define when to change the color. This works, but doing it this way means that we're calculating on the fly, rather than mapping the result to our original data. Since the color is selected in a way that is not tied to a column in our data, you need to define this color outside of the aes()
function. As such, the geom_text()
function is modified accordingly:
geom_text(
aes(label=paste(value,"%")), size=5,
color=ifelse(df$category=="A", 'white', 'black'),
position=position_stack(vjust=0.5))
Once again note - I define color=
outside of aes()
. The other way to do this would be to map the color of text to category
, then define the colors manually with scale_color_manual()
. It's actually more straightforward here to just use ifelse()
outside aes()
. (plus, position_stack()
is very wonky when working with text geoms...).