morningfin
morningfin

Reputation: 339

ggplot2 draw graph with respect to a specific order

If duplicated, please point me to the original question.

I would like to draw a figure in R using ggplot2, and the following codes show what I would like to achieve.

require(ggplot2)
require(data.table)

set.seed(1)

dat <- data.table(time = rep(c(1:40), times = 5),
                  value = runif(200), 
                  team = rep(c("A","B","C","D","E"), each = 40))
dat[, value := value / sum(value), by = .(time)]

ggplot(dat, aes(x = time, y = value, group=team, fill=team)) +
geom_area(position = "fill") +
scale_fill_manual(values = c("red","blue","green","pink","yellow"),
                  breaks = c("D", "B", "E", "A", "C"),
                  labels = c("D", "B", "E", "A", "C"))

ggplot2 output:

enter image description here

As you can see, the order of the figure does not match the order of the legend. It is the order of A, B, C, D, E, but not D, B, E, A, C. I would like to draw the figure with pink at the top, then blue, then yellow, then red, then green (DBEAC). How can I achieve this?

Thanks in advance!

Upvotes: 1

Views: 547

Answers (1)

mnel
mnel

Reputation: 115382

This is pretty much a duplicate of ggplot2: Changing the order of stacks on a bar graph,

geom_area appears to stack the areas in the order in which they first appear in the data.

Ordering dat in the appropriate order appears to solve your problem

# create order you want
my_order <- c("D", "B", "E", "A", "C")
# reversed to get correct ordering in data table
dat[, order := match(team, rev(my_order))]
# sort the data.table
setorder(dat, time, order)
# make the  plot
ggplot(dat, aes(x = time, y = value, fill=team))+
  geom_area(position = "fill") +
  scale_fill_manual(values = c("red","blue","green","pink","yellow"),
                    breaks = my_order ,
                    labels = my_order )

enter image description here

Upvotes: 1

Related Questions