Home > Net >  How can I stack labels vertically above ggplot2 bar graph?
How can I stack labels vertically above ggplot2 bar graph?

Time:08-20

I have generated a bar graph with labels on top of the bars and above the standard error bars. However, I would like to rotate the labels so that they stack vertically instead of horizontally. How can I do this?

Here is the data to make the example reproducible:

example <- data.frame(var = c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3),
                      resp = c(1,2,3,4,5,6,7,8,2,4,5,10,3,3,2,9,8,7,6,5,4,3,2,3))

Here is what I have tried:

library(dplyr)
library(ggplot2)

# Convert to factor
example$var <- as.factor(example$var)

# Group by variable means
example_mean <- example %>% 
  group_by(var) %>% 
  summarise(mean = mean(resp), .groups = 'drop')

# Add mean separation labels
example_mean$mean_sep <- c("aasdf","dfdsa","adfdsa")

# Function for standard error of the mean
sem <- function(x) sd(x)/sqrt(length(x))

# Aggregate standard error over variables
example_sem <- example %>% 
  group_by(var) %>% 
  summarise(sem = sem(resp), .groups = 'drop')

# Generate bar graph
ggplot(example_mean, aes(x = var, y = mean)) 
  geom_bar(stat="identity", width = 0.4, position = "dodge", col = "black", fill = "maroon") 
  geom_errorbar(aes(ymin = mean, ymax = mean   example_sem$sem), width = 0.2, position = position_dodge(0.6)) 
  xlab("var") ylab("response") 
  theme(plot.title=element_text(hjust=0.5, size = 20),
        axis.text = element_text(size = 15),
        axis.title = element_text(size = 15)) 
  ggtitle("Custom Title") 
  geom_text(aes(label=mean_sep, y=mean   example_sem$sem), vjust = -0.9, size = 6)  
  ylim(0, 8)

The following graph is produced: enter image description here

I need to rotate the labels so that they appear vertically stacked, such as this:

enter image description here

How can I do this?

CodePudding user response:

You could insert a new line between each character. It could for instance be done using purrr. I.e.

geom_text(aes(label  = purrr::map(strsplit(mean_sep, ""),
                                  ~ paste(., collapse = "\n")),
              y      = mean   example_sem$sem
              ),
          vjust      = -0.1,
          lineheight = 0.7,
          size       = 6)

You might want to adjust the lineheight vjust as well as ylim..

Without purrr: sapply(strsplit(mean_sep, ""), \(x) paste(x, collapse = "\n"))

Output:

enter image description here

  • Related