Search code examples
rggplot2bar-chartaxis-labels

Multirow axis labels with nested grouping variables for staked plots with horizontal bars and values added


I want to flip the orientation of a staked bar plot so that the Sales variable is on the x-axis, and the Year and categories (Clothing, Electronics, and Food) are on the y-axis. Additionally, I would like to display the sales value numbers for each of the staked bars.

enter image description here

Here is some dummy code

data2 <- read.table(text = "Product Category Year Sales
               A Clothing 2017 100
               A Clothing 2018 120
               A Electronics 2017 150
               A Electronics 2018 200
               A Food 2017 50
               A Food 2018 80
               B Clothing 2017 80
               B Clothing 2018 90
               B Electronics 2017 100
               B Electronics 2018 120
               B Food 2017 70
               B Food 2018 100", header=TRUE)

p2 <- ggplot()
p2 + geom_bar(data = data2, aes(x = Year, y = Sales, fill = Product), stat = "identity") +
  facet_wrap(vars(Category), strip.position = "bottom", scales = "free_x") +
  geom_text(size = 3, position = position_stack(vjust = 0.5)) +
  theme(panel.spacing = unit(0, "lines"),
        strip.background = element_blank(),
        axis.line = element_line(colour = "grey"),
        panel.grid.major.y = element_line(colour = "grey"),
        strip.placement = "outside",
        axis.text.x = element_text(angle = 90, hjust = 1),
        axis.title.x = element_blank(),
        panel.background = element_rect(fill = 'white', colour = 'white'))

I have tried using coord_flip, but the category variables remain at the bottom.

Any help would be greatly appreciated.


Solution

  • To put your categories on the left set ncol=1 in facet_wrap and strip.position="left". For the years map factor(y) on y and Sales on x. And to get your labels map on the label aes in geom_text:

    library(ggplot2)
    
    ggplot(data2, aes(y = factor(Year), x = Sales, fill = Product)) + 
      geom_col() +
      geom_text(aes(label = Sales), size = 3, position = position_stack(vjust = 0.5)) +
      facet_wrap(vars(Category), strip.position = "left", ncol = 1) +
      theme(
        panel.spacing = unit(0, "lines"),
        strip.background = element_blank(),
        axis.line = element_line(colour = "grey"),
        panel.grid.major.x = element_line(colour = "grey"),
        strip.placement = "outside",
        panel.background = element_rect(fill = "white", colour = "white")
      ) +
      labs(y = NULL)
    

    enter image description here