2

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

Abhishek
  • 407
  • 3
  • 18

1 Answers1

2

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)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Thanks for solution. Actually, I didnt get what you meant here :"Note however that with facets this simple solution will not work for more general cases.". – Abhishek Mar 18 '20 at 07:28
  • 2
    `fct_reorder`reorders over the whole dataset. But with facetting sometimes we want to reorder within each facet. However, this is probably no issue at all with stacked bar charts as in your example. Nonetheless it is good to know that `tidytext` package provides a solution for such cases called `reorder_within`. – stefan Mar 18 '20 at 07:42
  • I've tried the `tidytext` solution, I must say it got very ugly in my case generating as many unique factors as my dataset had rows (making my plots untractable). I think in some cases skipping the facetting and making individual `ggplot` obejcts and stitching them together with e.g., `cowplot` might be a better solution. (Comment mainly intended for other readers that came here with similar problem) – Baraliuh Jan 22 '22 at 16:40
  • @Baraliuh. Hm. Would be interesting to see what's going wrong. But yes. There are probably cases where `cowplot` or `patchwork` would be the easier or "better" way to go. – stefan Jan 23 '22 at 18:49