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 do I make it so the "other" group is at the bottom of the stack rather than in the middle so that the image looks cleaner?

This is how the data frame looks that I am working with, it is a tall form structure with Var2 being the patients:

enter image description here

mrad
  • 173
  • 1
  • 11

3 Answers3

2

Instead of fill=Var1 use fill=factor(Var1, levels = c(setdiff(Var1, "Other"), "Other")).

Here is an example using the palmerpenguins dataset:

library(tidyverse)
library(palmerpenguins)

penguins %>%
  na.omit() %>%
  ggplot(aes(x=as.factor(species), y=body_mass_g, fill=factor(year))) +
  geom_bar(stat="identity", position = "fill")

penguins %>%
  na.omit() %>%
  ggplot(aes(x=as.factor(species), y=body_mass_g, fill=factor(year, levels = c(setdiff(year, 2008), 2008)))) +
  geom_bar(stat="identity", position = "fill") +
  labs(fill = "Year")

Created on 2021-11-22 by the reprex package (v2.0.1)

jared_mamrot
  • 22,354
  • 4
  • 21
  • 46
  • I will give this a go. Alternatively is there a way I can order the stacks so they are in decreasing or increasing size? Rather than mixed up? – mrad Nov 22 '21 at 06:22
  • Hi this worked and the "other" section appears at the bottom of the figure, as in where 2008 it is in your examples. Is there a way so I can flip it so that the "other" segment is instead at the top of the stacks? – mrad Nov 22 '21 at 21:43
  • Yes, to put "Other" at the start, use `fill=factor(Var1, levels = c("Other", setdiff(Var1, "Other")))` instead of `fill=factor(Var1, levels = c(setdiff(Var1, "Other"), "Other"))` – jared_mamrot Nov 22 '21 at 22:48
  • That did it thank you so much! – mrad Nov 22 '21 at 22:56
  • You're welcome @mrad. Out of interest, did the answers at https://stackoverflow.com/questions/32345923/how-to-control-ordering-of-stacked-bar-chart-using-identity-on-ggplot2 solve your problem? Or was it too difficult to translate the answers to your situation? – jared_mamrot Nov 22 '21 at 23:01
1

I'm not sure if Var1 is a factor or not. It's not appropriate to post your data as an image.

If it's factor, let's define x, y as

x <- levels(full_genus_new$Var1)
y <- c(x[x!= "Other"], "Other")

Then at the first part of ggplot part, try

ggplot(full_genus_new, aes(x=as.factor(Var2), y=value, fill= factor(Var1, levels = y))) +...
Park
  • 14,771
  • 6
  • 10
  • 29
  • Hi there, should the "!" point be in the second line of code? I got an error including it. When running it without the "!" then trying to plot as you suggested I get this error: Error in aes(x = as.factor(Var2), y = value, fill = factor(Var1, levels = y)) + : non-numeric argument to binary operator – mrad Nov 22 '21 at 22:29
0

You can use the mutate and factor argument to create levels (a hierarchy) to the observations. At the moment, the stacked bar chart is ordering the observations in alphabetic order (so "Other" is appearing somewhere in the middle). If you create the hierarchy so that "Other" appears at the end, then you can get it to appear at the bottom of the graph.

Here's an example. You'll see that the first plot will show the "Other" proportion before "X". In the second, the factored/reordered one, will show "Other" at the end.

library(tidyverse)

df <- tibble(
  category1 = c("One"),
  category2 = c("A", "B", "C", "Other", "X"),
  proportion = c(20, 20,40,10, 10)
)

df %>% 
  ggplot(., aes(x = category1, y = proportion, fill = category2)) +
  geom_bar(stat="identity")

df %>% 
  mutate(category_reordered = factor(category2, levels = c("A", "B", "C", "X", "Other"))) %>% 
  ggplot(., aes(x = category1, y = proportion, fill = category_reordered)) +
  geom_bar(stat="identity")
jdsimkin04
  • 131
  • 1
  • 5