0

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!

morningfin
  • 329
  • 2
  • 10
  • If you leave out the scale_manual, the orders are the same. – IRTFM Jan 25 '17 at 01:33
  • Or, if the order is important for some reason. re-order the factor variable. Something like `df$team <- factor(df$team, levels = c("D", "B", "E", "A", "C"))`. Then graph it. – lmo Jan 25 '17 at 01:35
  • 1
    If you leave out the `breaks` argument to scale_manual, the order is also as you desire. I can almost never tell whether such anomalies are bugs or intended behavior because the help pages for ggplot2 functions seldom tell me enough about the acceptable values of parameters or their effects. – IRTFM Jan 25 '17 at 01:37
  • Leave out the breaks just give the right order, but the plot is still the same, which means the plot itself is wrong. – morningfin Jan 25 '17 at 02:09

1 Answers1

1

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

Community
  • 1
  • 1
mnel
  • 113,303
  • 27
  • 265
  • 254