I am trying to reorder categories in a ggplot bar chart by the size of the variables, with the biggest categories first, followed by increasingly minor ones. I've tried playing with the order in a few ways but only seem to be able to set the order manually which isn't very helpful for big data sets.
For example: Let's say I have the following data:
mydata <- read.table(header=TRUE, text="
shop fruit varieties km_away
shop1 apple 0 12
shop1 banana 0 12
shop1 pear 2 12
shop1 melon 1 12
shop1 orange 1 12
shop1 peach 3 12
shop1 apricot 6 12
shop1 lime 1 12
shop2 apple 1 1
shop2 banana 0 1
shop2 pear 2 1
shop2 melon 2 1
shop2 orange 5 1
shop2 peach 4 1
shop2 apricot 11 1
shop2 lime 0 1
shop3 apple 0 2
shop3 banana 1 2
shop3 pear 2 2
shop3 melon 1 2
shop3 orange 4 2
shop3 peach 1 2
shop3 apricot 11 2
shop3 lime 1 2
shop4 apple 0 5
shop4 banana 0 5
shop4 pear 3 5
shop4 melon 2 5
shop4 orange 6 5
shop4 peach 1 5
shop4 apricot 9 5
shop4 lime 0 5
")
I can usefully visualise it like this:
library(ggplot2)
library(RColorBrewer)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
But how do I tell ggplot to plot the apricots first, then the oranges, etc? This will make it much easier to visually compare different categories across shops.
You can first obtain a vector of the categories, ordered by your quantity of interest:
fruit_levels <- names(sort(tapply(mydata$varieties, mydata$fruit, sum)))
Then, in your call to ggplot
, map fill
to a factor variable with the corresponding levels:
p <- ggplot(data = mydata,
aes(x=reorder(shop, km_away), y=varieties,
fill=factor(fruit, levels = fruit_levels)))+
geom_bar(stat="identity") + coord_flip()+
scale_fill_brewer(name = "fruit", palette="Accent")
p
Output:
Update. A more direct route is to re-order the factor levels in your original dataframe, and call ggplot
as in your original code:
mydata$fruit <- reorder(mydata$fruit, mydata$varieties, sum)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
Update 2. On older versions of ggplot2
(pre version 2), try specifying the order
aesthetic:
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away),
y=varieties,
fill=fruit, order=fruit)) +
geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
And if you want to reverse the ordering, add a negative sign in front of the ordering variable:
reorder(mydata$fruit, -mydata$varieties, sum)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With