Home > Software engineering >  Staggering labels or adding only selected labels on ggplot stacked bar chart
Staggering labels or adding only selected labels on ggplot stacked bar chart

Time:02-25

I am plotting a series of Likert scale questions as stacked bar charts. They need to be labelled but some of the segments are two small and get overlaps like the example below (with sample code below it). Is there a clever way to either only label sections that are big enough to fit the label or a way to stagger how the labels are presented?

enter image description here

q1a<-rep(c("A", "B", "C", "D"), c(2, 5,45,45))
q1b<-rep(c("A", "B", "C", "D"), c(45,45,2, 5))
data<-data.frame(q1a,q1b)

data %>%
  select(q1a:q1b) %>%
  pivot_longer(cols = everything(), names_to = "Question") %>%
  filter(!is.na(value)) %>%
  count(Question, value) %>%
  group_by(Question) %>%
  mutate(Pct = n / sum(n)) %>%
  ggplot(aes(fill = value, x = Pct, y = fct_rev(Question)))  
  geom_bar(position = "fill", stat = "identity")  
  geom_text(aes(label = paste0(sprintf("%1.0f", Pct * 100), "%")), position = position_stack(vjust = 0.5), size = 3)  
  scale_fill_brewer(palette = "Blues")  
  theme_bw()  
  scale_x_continuous(labels = scales::percent)  
  labs(title = "Question 1", y = "Question", x = "Percentage")  
  theme(legend.title = element_blank())

CodePudding user response:

If I were you, I'll only display labels for Pct greater than 5% using if_else() in geom_text(aes()). If it's less than 5%, display nothing.

Also, since your geom_bar position is fill, you should also use position = position_fill() in geom_text to align the position.

library(tidyverse)

data %>%
  select(q1a:q1b) %>%
  pivot_longer(cols = everything(), names_to = "Question") %>%
  filter(!is.na(value)) %>%
  dplyr::count(Question, value) %>%
  group_by(Question) %>%
  mutate(Pct = n / sum(n)) %>%
  ggplot(aes(fill = value, x = Pct, y = fct_rev(Question)))  
  geom_bar(position = "fill", stat = "identity")  
  geom_text(aes(label = if_else(Pct > 0.05, paste0(sprintf("%1.0f", Pct * 100), "%"), NULL)), 
            position = position_fill(vjust = 0.5), size = 3)  
  scale_fill_brewer(palette = "Blues")  
  theme_bw()  
  scale_x_continuous(labels = scales::percent)  
  labs(title = "Question 1", y = "Question", x = "Percentage")  
  theme(legend.title = element_blank())

labelPCT

  • Related