Alex Ruiz
Alex Ruiz

Reputation: 139

Position argument of geom_text to set different tags

I want three tags in each of my stacked bars. One I want it to be at the top of each bar saying the total number of observations per treatment variable (x axis). The other two tags I want them showing the number of observations per gender, to be somehwere in the middle of each Gender option within each treatment variable.

I have problems with the geom_text code, since I don't know what position I should try. I have input different options, but when I do, my graph is distorted like this.

enter image description here

This is the code I am using

Data1 %>% 
  count(Treatment, Gender) %>% 
  ggplot(aes(Treatment, n))+ 
  geom_col(aes(fill = Gender), position = "fill")+
  ggtitle("Gender")+
  ylab("Fraction")+
  theme(axis.text.x = element_text(angle = 90, vjust=0.3, hjust=1))+
  scale_fill_manual("Gender", 
                    values = c("Female" = "pink", "Male" = "light blue",
                               "Other"="coral", "Prefer not to answer"="violet"))+
  geom_text(aes(label=n), position=position_stack(vjust=0.5))

If I have read correctly other posts, position_stack should put the numbers inside each bar.

Upvotes: 1

Views: 947

Answers (1)

Rui Barradas
Rui Barradas

Reputation: 76470

If the cols are plotted with position = "fill" then geom_text must call the same position_fill.
In this example I will use a subset of the built-in dataset mtcars, transformed below.

library(ggplot2)
library(dplyr)

Data1 %>% 
  count(Treatment, Gender) %>%
  ggplot(aes(x = Treatment, y = n, fill = Gender)) + 
  geom_col(position = "fill") +
  ggtitle("Gender") +
  ylab("Fraction") +
  theme(axis.text.x = element_text(angle = 90, vjust=0.3, hjust=1)) +
  scale_fill_manual("Gender", 
                    values = c("Female" = "pink", "Male" = "light blue",
                               "Other"="coral", "Prefer not to answer"="violet")) +
  geom_text(aes(label = n), position = position_fill(vjust=0.5))

enter image description here

To put the bars totals on top of them, the following code also computes the totals per Treatment and keeps only the first per group of Treatment, assigning NA to the other elements of SumN.

Data1 %>% 
  count(Treatment, Gender) %>%
  group_by(Treatment) %>% 
  mutate(SumN = sum(n),
         SumN = c(SumN[1], rep(NA, length(SumN) - 1))) %>%
  ungroup() %>%
  ggplot(aes(x = Treatment, y = n, fill = Gender)) + 
  geom_col(position = "fill") +
  ggtitle("Gender") +
  ylab("Fraction") +
  theme(axis.text.x = element_text(angle = 90, vjust=0.3, hjust=1)) +
  scale_fill_manual("Gender", 
                    values = c("Female" = "pink", "Male" = "light blue",
                               "Other"="coral", "Prefer not to answer"="violet")) +
  geom_text(aes(label = n), position = position_fill(vjust=0.5)) +
  geom_text(aes(y = 1.1, label = SumN), position = position_fill(vjust = 1.2))

enter image description here

Data example.

Data1 <- mtcars[mtcars$carb %in% 1:4, c("cyl", "carb")]
names(Data1) <- c("Treatment", "Gender")
Data1$Treatment <- factor(Data1$Treatment)
Data1$Gender <- factor(Data1$Gender, 
                       labels = c("Female", "Male", "Other", "Prefer not to answer"))

Upvotes: 1

Related Questions