Search code examples
rggplot2bar-chartstacked-chart

How to sort stacks within each ggplot's facets?


Please help us sort the stacks in ascending order ! i.e. left facet seems to be in order but right side is not really sorted because 1.7 should have come at the right end. (please refer screenshot)

similar but not exact queries How to control ordering of stacked bar chart using identity on ggplot2 Order Stacked Bar Graph in ggplot reorder each facet ascending for a ggplot stacked bar graph

df = data.frame(cat = c(rep("A",9),rep("B",11)),
                grp = c(rep("C",3),rep("D",3),rep("F",3), rep("C",3),rep("D",3),rep("E",2),rep("F",3)),
                yrs = c(rep(c("2017","2018","2019"),5),"2017","2019","2017","2018","2019"),
                per = c(2.4,2.5,3.2,
                15.3,17,16.7,
                82.4,80.5,80.1,
                8.6,9.6,15.2,
                36.2,42.2,40.4,
                1.7,1.1,53.4,
                48.2,43.4))

df %>% 
  ggplot(aes(x = "scale",y = per, fill = grp)) +
  # geom_bar(stat="identity") +
  geom_col() +
  geom_text(aes(label= round(per,1)), 
            position=position_stack(vjust=0.5), size= 3) +
  facet_grid(vars(yrs),vars(cat)) +
  coord_flip() +
  theme_bw() +
  xlab("") +
  ylab("") +
  ggtitle("How to sort ") +
  theme(legend.position="bottom",
        legend.title = element_blank(),
        plot.title = element_text(hjust = 0.5),
        axis.text = element_blank(),
        axis.ticks = element_blank())

ets


Solution

  • By default the bars are ordered alphabetically according to grp. To order by per we can achive this for your case by reordering grp using e.g. fct_reorder from forcats. Note however that with facets this simple solution will not work for more general cases.

    library(ggplot2)
    library(dplyr)
    library(forcats)
    
    df <- data.frame(cat = c(rep("A",9),rep("B",11)),
                   grp = c(rep("C",3),rep("D",3),rep("F",3), rep("C",3),rep("D",3),rep("E",2),rep("F",3)),
                   yrs = c(rep(c("2017","2018","2019"),5),"2017","2019","2017","2018","2019"),
                   per = c(2.4,2.5,3.2,
                           15.3,17,16.7,
                           82.4,80.5,80.1,
                           8.6,9.6,15.2,
                           36.2,42.2,40.4,
                           1.7,1.1,53.4,
                           48.2,43.4))
    
    df %>% 
      ggplot(aes(x = "scale", y = per, fill = fct_reorder(grp, per))) +
      # geom_bar(stat="identity") +
      geom_col() +
      geom_text(aes(label= round(per,1)), 
                position=position_stack(vjust=0.5), size= 3) +
      facet_grid(vars(yrs),vars(cat)) +
      coord_flip() +
      theme_bw() +
      xlab("") +
      ylab("") +
      ggtitle("How to sort ") +
      theme(legend.position="bottom",
            legend.title = element_blank(),
            plot.title = element_text(hjust = 0.5),
            axis.text = element_blank(),
            axis.ticks = element_blank())
    

    Created on 2020-03-17 by the reprex package (v0.3.0)