0

I have the following content in mydata:

Class       Category
"One"       "A"
"One"       "A"
"Two"       "A"
"Two"       "A"
"Three"     "B"
"Three"     "B"
"One"       "C"
"Two"       "C"

I use ggplot2:

ggplot(mydata) +
  aes(x = Category, fill = Class) +
  geom_bar() 

I get this result:

this

I notice that the "Class" items appear alphabetically. But I want the option to order them as follows:

  1. ad hoc, so choose exact order
  2. In order of appearance in data, so in this case, One, Two, Three
  3. In reverse order of appearance in data: Three, Two, One

Answers gratefully appreciated.

Clarification

In case of doubt, here is the full working example of the above data:

Class <- c("One", "One", "Two", "Two", "Three", "Three", "One", "Two", "Four")
Category <- c("A", "A", "A", "A", "B", "B", "C", "C", "C")

mydata <-  data.frame(Class, Category)

ggplot(mydata) +
  aes(x = Category, fill = Class) +
  geom_bar() 

The Class key that is generated to the right is in the order:

Four, One, Three, Two

I want to have control over the order of the items in the key produced. (The colors are less important.)

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
Kaveh1000
  • 153
  • 1
  • 11
  • 1
    Possible duplicate of [How to control ordering of stacked bar chart using identity on ggplot2](https://stackoverflow.com/questions/32345923/how-to-control-ordering-of-stacked-bar-chart-using-identity-on-ggplot2) – Dan Sep 04 '18 at 18:21

2 Answers2

0

You can specify the order of legend items with the the breaks parameter in scale_fill_discrete():

p <- ggplot(mydata) +
  aes(x = Category, fill = Class) +
  geom_bar() 

p + scale_fill_discrete(breaks = c("One", "Two", "Three", "Four"))
p + scale_fill_discrete(breaks = c("Four", "Three", "Two", "One"))

plot

This leaves the underlying data & colour assignments unchanged.

Edit: To change the column stack order, you can assign the factor levels for Class before plotting it. Note that if you take this option, you won't need to manually specify the breaks again for the legend, as they'll follow the factor levels by default.

library(dplyr)

# alternative 1: does not change the underlying data frame
ggplot(mydata %>%
         mutate(Class = factor(Class,
                               levels = c("One", "Two", "Three", "Four")))) +
  aes(x = Category, fill = Class) +
  geom_bar() 

# alternative 2: changes the underlying data frame    
mydata2 <- mydata %>%
  mutate(Class = factor(Class,
                        levels = c("One", "Two", "Three", "Four")))
ggplot(mydata2) +
  aes(x = Category, fill = Class) +
  geom_bar() 
Z.Lin
  • 28,055
  • 6
  • 54
  • 94
  • Thank you. That answers my question. Am I allowed a follow up question? If so, what if I want to change the order of the data in the columns too, so the data appear in the same order as the key? – Kaveh1000 Sep 05 '18 at 12:12
  • Thank you so much for your time. It is going to take a while for me to digest these invaluable answers. I have clicked the up arrow but will not show till I have more credits. ;-) – Kaveh1000 Sep 05 '18 at 21:38
-1

Let's say you want the order to be Three, Two, One, so you need to use:

setattr(mydata$Class,"levels",c("Three","Two","One"))

First and then run your ggplot code. Please mark this as the correct answer if you are satisfied with the solution. thanks :)

Shirin Yavari
  • 626
  • 4
  • 6
  • This is not correct. This will [reassign the actual levels](https://stackoverflow.com/questions/14634964/how-does-one-change-the-levels-of-a-factor-column-in-a-data-table), so that "Three" now corresponds with the first level, which alters the data. – Anonymous coward Sep 04 '18 at 19:39
  • I disagree with your comment! Unless I'm mistaking, in his example 3 doesn't necessarily have to be bigger than 1, meaning it's a categorical variable and not an ordinal variable. – Shirin Yavari Sep 04 '18 at 19:46
  • If `Class` is not a factor, that is correct, but if `Class` is a factor, "One" turns into "Three". – Anonymous coward Sep 04 '18 at 19:55
  • @shirin I tried your code but I get the same result. Please see my clarification in my original posting. Thanks all. – Kaveh1000 Sep 05 '18 at 07:37