order aesthetic with geom_area

1,478 views
Skip to first unread message

Matt Frost

unread,
Dec 3, 2009, 4:25:02 PM12/3/09
to ggplot2
Is it possible to use the order aesthetic to change the stacking
sequence of areas in a geom_area plot?
I'm plotting shares of a total over time, grouping by a factor. I can
reorder the factor levels (their order changes in the legend) but not
the ribbons in the geom_area plot.
Any example code of aes(order=...) in action would be great.

Hadley Wickham

unread,
Dec 3, 2009, 8:41:04 PM12/3/09
to Matt Frost, ggplot2
Could you please provide a small reproducible example? It really saves
me time when looking into a problem.

Hadley
> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> To post to this group, send email to ggp...@googlegroups.com
> To unsubscribe from this group, send email to
> ggplot2+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/ggplot2

--
http://had.co.nz/

Matt Frost

unread,
Dec 4, 2009, 11:09:02 AM12/4/09
to ggplot2
Hadley,
Thanks for the help.
Let's say I have a record of how many pandas, kittens, and whales I've
eaten in a year:

d <- melt(data.frame(week = sequence(52), "panda","kitten","whale"), c
("week"))[-2]
d$eaten<-rpois(52*3, 2) #because using the poisson distribution makes
it Science.
ggplot(d, aes(x=week, y=eaten, group=value)) + geom_area(aes
(fill=value))

Right now, the colored bands on the chart are ordered "panda, kitten,
whale" from bottom to top. What if I want the areas to be drawn in a
different order, with whales on the bottom band, for instance?

NB: In the real application, I'm showing percent of a total, but it's
trickier to calculate those sample values.

Matt

On Dec 3, 8:41 pm, Hadley Wickham <had...@rice.edu> wrote:
> Could you please provide a small reproducible example? It really saves
> me time when looking into a problem.
>
> Hadley
>

James Howison

unread,
Dec 4, 2009, 1:00:10 PM12/4/09
to ggplot2
This is a pretty frequently asked question, did you search the list
archives?

add in this

d$value <- factor(d$value, levels=c("whale", "kitten", "panda"))

the order that the vector for levels is given will be the order used
(you don't need ordered=T).

If you need that to be dynamic (ie according to counts or something),
then I think you'll need to calculate that yourself.

I wonder if adding an optional (and over-riding) "group-level-order"
variable to aes might help document this? I know it's the "wrong"
place (the data frame is the "right" place to declare this info), but
clearly this is something that confuses people.

--J

Matt Frost

unread,
Dec 4, 2009, 2:07:50 PM12/4/09
to ggplot2
James,
Yes, I've tried exactly that, and several variations thereupon. But if
you run this code, you'll see that while the factors get resorted in
the legend, and the colors are shuffled, their respective bands get
stacked in the same order.

d <- melt(data.frame(week = sequence(52), "panda","kitten","whale"), c
("week"))[-2]
d$eaten<-rpois(52*3, 2) #because using the poisson distribution makes
it Science.
p1 <- ggplot(d, aes(x=week, y=eaten, group=value)) + geom_area(aes
(fill=value))
d$value <- factor(d$value, levels=c("whale", "kitten", "panda"))
p2 <- ggplot(d, aes(x=week, y=eaten, group=value)) + geom_area(aes
(fill=value))

grid.newpage()
pushViewport(viewport(layout=grid.layout(2,1)))
vplayout<-function(x,y)
viewport(layout.pos.row=x,layout.pos.col=y)
print(p1,vp=vplayout(1,1))
print(p2,vp=vplayout(2,1))



On Dec 4, 1:00 pm, James Howison <ja...@freelancepropaganda.com>
wrote:

hadley wickham

unread,
Dec 4, 2009, 2:19:31 PM12/4/09
to Matt Frost, ggplot2
There's two issues at stake here:

* the order in which the labels appear on the legend, controlled by the scale

* the order in which the areas are stacked, controlled by the order
in which the values appear in the data, and putatively the order
aesthetic. However, there are a few bugs which I'm still working on.
See http://github.com/hadley/ggplot2/issues/labels/data#issue/33 and
http://github.com/hadley/ggplot2/issues/labels/data#issue/34

Regards,

Hadley

Matt Frost

unread,
Dec 4, 2009, 2:29:42 PM12/4/09
to ggplot2
Thanks, Hadley. I wasn't sure how far along the order aesthetic was.

Am I right to think that, with everything eventually fixed) I could
add a new attribute called stackorder with values ("1_whale",
"2_kitten", "3_panda") and call it like this?

ggplot(d, aes(x=week, y=eaten, group=value, order = stackorder)) +
geom_area(aes (fill=value))

That would seem to require a delicate correspondence between the
group= field and the order= field, so it's probably too good to be
true.

Matt



On Dec 4, 2:19 pm, hadley wickham <h.wick...@gmail.com> wrote:
> There's two issues at stake here:
>
>  * the order in which the labels appear on the legend, controlled by the scale
>
>  * the order in which the areas are stacked, controlled by the order
> in which the values appear in the data, and putatively the order
> aesthetic.  However, there are a few bugs which I'm still working on.
>  Seehttp://github.com/hadley/ggplot2/issues/labels/data#issue/33andhttp://github.com/hadley/ggplot2/issues/labels/data#issue/34

hadley wickham

unread,
Dec 4, 2009, 2:33:36 PM12/4/09
to Matt Frost, ggplot2
Hi Matt,

Yeah, the groups defined by group and by order need to match. For
most cases setting them to the same variable and using factor
reordering should work.

Hadley
http://had.co.nz/

James Howison

unread,
Dec 4, 2009, 2:39:01 PM12/4/09
to ggplot2
Apologies, I tried it and it worked, but on more experimentation that
seems to have been merely luck.

hadley wickham

unread,
Dec 8, 2009, 12:34:07 PM12/8/09
to Matt Frost, ggplot2
On Fri, Dec 4, 2009 at 1:29 PM, Matt Frost <mwf...@gmail.com> wrote:
> Thanks, Hadley. I wasn't sure how far along the order aesthetic was.
>
> Am I right to think that, with everything eventually fixed) I could
> add a new attribute called stackorder with values ("1_whale",
> "2_kitten", "3_panda") and call it like this?
>
> ggplot(d, aes(x=week, y=eaten, group=value, order = stackorder)) +
> geom_area(aes (fill=value))

That will now work in the development version (hopefully to be
uploaded to cran later today).

Alternatively you can do:

d <- melt(data.frame(week = sequence(52), "panda","kitten","whale"),
c("week"))[-2]
d$eaten<-rpois(52*3, 2)
base <- ggplot(d, aes(week, eaten, group=value)) +
geom_area(aes(fill=value))

base
base + aes(order = as.numeric(value))
base + aes(order = -as.numeric(value))

Hadley


--
http://had.co.nz/
Reply all
Reply to author
Forward
0 new messages