Home > Net >  Reordering bars in ggplot
Reordering bars in ggplot

Time:04-26

i have created a bar chart using ggplot2. However i want to be able to change the order of the bars in a specific order, i.e. not by value or ordered alphabetically as ggplot does automatically. This is my code:

ggplot(data = data1, aes(x = Virus.hpi, y = ct, fill = Virus.hpi))  
  scale_fill_manual(values = c("BTV-8 0hpsi" = "purple", "BTV-8 72hpsi" = "purple", "BTV-1 0hpsi" = "blue", "BTV-1 72hpsi" = "blue"))  
  stat_summary(fun = mean, geom = "bar")  
  stat_summary(fun.data = mean_cl_normal, geom = "errorbar", width = 0.3)  
  geom_point(data = data1, aes(x = Virus.hpi, y = ct, fill = Virus.hpi))  
  scale_y_continuous(breaks = seq(0, 40, 10), labels = rev(seq(0, 40, 10)))

The is the bar chart I get with this code:

enter image description here

However I want the bars ordered "BTV-8 0hpsi", "BTV-8 72hpsi", "BTV-1 0hpsi", BTV-1 72hpsi"

I have tried to use the reorder function but i can't seem to get it to work. Below is my code with the reorder function.

ggplot(data=data1, aes(x = reorder(BTV-8 0hpsi, BTV-8 72hpsi, BTV-1 0hpsi, BTV-1 72hpsi, mean), y=ct, fill=Virus.hpi))   scale_fill_manual(values = c("BTV-8 0hpsi" = "purple", "BTV-8 72hpsi" = "purple", "BTV-1 0hpsi" = "blue", "BTV-1 72hpsi" = "blue"))   stat_summary(fun = mean, geom = "bar")   stat_summary(fun.data = mean_cl_normal, geom = "errorbar", width = 0.3)   geom_point(data=data1, aes(x = Virus.hpi, y=ct, fill=Virus.hpi))   scale_y_continuous(breaks = seq(0, 40, 10), labels = rev(seq(0, 40, 10)))

CodePudding user response:

it's better if you can provide a small reproducible example (including the data) like the one below so someone can paste, run and improve your example.

You could set the factor levels of your names in the order you want. In my example I've changed the default alphabetical order to an explicit order.

Or if you need something more sophisticated, you could look at the forcats package in the tidyverse. In the commented line, I've reordered by the mean value.

library(tidyverse)

tribble(
  ~colour, ~value,
  "red", 1,
  "blue", 2,
  "green", 2,
  "red", 2,
  "blue", 1,
  "green", 3
) |> 
  mutate(colour = factor(colour, levels = c("green", "red", "blue"))) |> 
  # mutate(colour = fct_reorder(colour, value, mean)) |> 
  ggplot(aes(colour, value))  
  geom_boxplot()

Created on 2022-04-25 by the reprex package (v2.0.1)

CodePudding user response:

Carl's answer is excellent! An alternative (that's usually less convenient) is to set the limits of the scale in question. Something like:

library(tidyverse)

df <- tribble(
  ~colour, ~value,
  "red", 1,
  "blue", 2,
  "green", 2,
  "red", 2,
  "blue", 1,
  "green", 3
)


df |>
  ggplot(aes(colour, value))  
  geom_boxplot()

df |>
  ggplot(aes(colour, value))  
  geom_boxplot()  
  scale_x_discrete(limits = c("green", "red", "blue"))
  • Related