1

I am creating a taxanomic bar chart using ggplot but I need to change the layout of the stacked segments. This is my code to create the plot:

ggplot(full_genus_new, aes(x=as.factor(Var2), y=value, fill=Var1)) +
    geom_bar(stat="identity", position = "fill", aes(order = -value)) +
    scale_x_discrete() +
    ylab("Relative Microbial Activity") +
    facet_grid(cols=vars(PEDIS), scales = "free_x", space = "free_x") +
    theme_classic() +
    scale_fill_manual(values = Cb64k) +
    scale_y_continuous(labels=percent_format()) +
    theme(legend.position = "bottom", legend.text = element_text(size=8)) +
    guides(fill=guide_legend(title="Taxa")) +
    xlab("Patient") +
    theme(legend.key.size = unit(0.5,'cm'))

Which produces the following:

enter image description here

How can I reorder the stacked segments based on size so that the larger segments start at the bottom and decrease in size until the top of the y axis is reached?

mrad
  • 173
  • 1
  • 11
  • 1
    Can you share a [minimal reproducible example](https://stackoverflow.com/a/5963610/13210554) that contains some sample data so we can help reproduce your issue? – Dan Adams Nov 22 '21 at 20:42
  • You can coerce the order of the groups by making that variable a `factor`. One easy way to set the levels according to relative abundance is with `forcats::fct_infreq`. However, the order will be the same in each x group (patient). I don't think there's a way to set a different order for each bar. – Dan Adams Nov 22 '21 at 21:08
  • @Dan how would I incorporate fct_infreq to my code above? – mrad Nov 22 '21 at 21:57
  • If you share a reproducible bit of data to go with that code I'll show you what I mean. I suggest something like `dput(head(full_genus_new, 25))` – Dan Adams Nov 23 '21 at 00:56

1 Answers1

0

We can manually stack them with rectangles ordered by size:

library(ggplot2)
library(dplyr)

#example data
d <- mtcars %>% 
  group_by(am, cyl) %>% 
  summarise(s = sum(mpg)) %>% 
  mutate(s_pc = s/sum(s) * 100) %>% 
  arrange(am, -s_pc) %>% 
  group_by(am) %>% 
  mutate(ymin = cumsum(lag(s_pc, default = 0)), 
         ymax = cumsum(s_pc),
         xmin = am - 0.4,
         xmax = am + 0.4, 
         fill = factor(cyl))

#use rectangle
ggplot(d, aes(xmin = xmin, xmax = xmax,
              ymin = ymin, ymax = ymax, fill = fill)) +
  geom_rect() +
  theme_minimal()

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209