Change order of legends

3,304 views
Skip to first unread message

Eduardo Ibanez

unread,
Oct 30, 2012, 6:54:04 PM10/30/12
to ggp...@googlegroups.com
Hi,

I am creating a number of plots that utilize two legends (fill and size). The order that the legends appear seems somewhat arbitrary and sometimes fill appears on top and size below it, and viceversa.

Is there a quick way of determine the order of the legend? In the example below (borrowed from Cookbook for R), can the color legend be on the bottom?

Thanks,
Eduardo


# Specify colour and shape
lp1 <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, shape=time, colour=sex)) + geom_line() + geom_point()

lp1 + scale_colour_discrete(name = "Payer") +
      scale_shape_discrete(name = "Time")
 
lp1 + scale_shape_discrete(name = "Time") +
  scale_colour_discrete(name = "Payer")

Roman Luštrik

unread,
Oct 30, 2012, 6:55:20 PM10/30/12
to Eduardo Ibanez, ggp...@googlegroups.com
Levels of the factor determine the order. Reorder factor levels and you're good to go.


Cheers,
Roman




--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2



--
In God we trust, all others bring data.

Kimiko Huang

unread,
Oct 30, 2012, 7:50:09 PM10/30/12
to Eduardo Ibanez, ggp...@googlegroups.com
pio_data.sub$Category <- factor(pio_data.sub$Category, levels = c('PATIENTS','INTERVENTIONS','OUTCOMES'))

HTH
Kimiko

Eduardo Ibanez

unread,
Oct 31, 2012, 9:24:18 AM10/31/12
to ggp...@googlegroups.com, Eduardo Ibanez
Roman, Kimiko:

Thanks for your answers, but I'm not looking to change the order of the levels. I am looking to change the order of the legends themselves, as in the Time/shape legend goes before Payer/color.

I copied my example below again, since I didn't include the data creation.

Thanks,
Eduardo




df1 <- data.frame(sex        = factor(c("Female","Female","Male","Male")),
                  time       = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
                  total_bill = c(13.53, 16.81, 16.24, 17.42))

Brandon Hurr

unread,
Oct 31, 2012, 9:34:40 AM10/31/12
to Eduardo Ibanez, ggplot2
I don't really know how to do that, but I wonder if it is simply based upon the alphabetical order of the scale name. Color before Shape. I'm sure there's a way to do what you want, but it might take some hacking or someone has written in a way to do that (a metaphorical backdoor). 

> lp2<-lp1 + scale_shape_discrete(name = "Time") +
+   scale_colour_discrete(name = "Payer")

> ggplot_build(lp2)
$data
$data[[1]]
  shape  colour x     y group PANEL
1    16 #F8766D 1 13.53     1     1
2    17 #F8766D 2 16.81     1     1
3    16 #00BFC4 1 16.24     2     1
4    17 #00BFC4 2 17.42     2     1

Eduardo Ibanez

unread,
Oct 31, 2012, 9:43:53 AM10/31/12
to ggp...@googlegroups.com, Eduardo Ibanez
Thanks, Brandon.

I am asking the question because I have have a function that creates a plot with fill and size scales. I used that function within a ddply call to create 4 plots and the order changes in one of them.

I will try that ggplot_build command to see if they are any different internally.

Thanks,
Eduardo

Kimiko Huang

unread,
Oct 31, 2012, 10:14:32 AM10/31/12
to Eduardo Ibanez, ggp...@googlegroups.com
Try it.

I have tried it. It's OK.



# A different data set

# run this code before calling ggplot2 function
guides_merge <- function(gdefs) {
gdefs <- lapply(gdefs, function(g) { g$hash <- paste(g$order, g$hash, sep = "z"); g})
tapply(gdefs, sapply(gdefs, function(g)g$hash), function(gs)Reduce(guide_merge, gs))
}
environment(guides_merge) <- environment(ggplot)
assignInNamespace("guides_merge", guides_merge, pos = "package:ggplot2")

df1 <- data.frame(sex        = factor(c("Female","Female","Male","Male")),
time       = factor(c("Lunch","Dinner","Lunch","Dinner"), levels=c("Lunch","Dinner")),
total_bill = c(13.53, 16.81, 16.24, 17.42))
lp1 <- ggplot(data=df1, aes(x=time, y=total_bill, group=sex, shape=sex, colour=sex)) + geom_line() + geom_point()
lp1

# Here's what happens if you just specify colour
lp1 + scale_colour_discrete(name  ="Payer",
breaks=c("Female", "Male"),
labels=c("Woman", "Man")) + guides(size = guide_legend(order = 1), colour = guide_legend(order = 2), alpha = guide_legend(order = 3))

:)


Eduardo Ibanez

unread,
Oct 31, 2012, 10:29:59 AM10/31/12
to ggp...@googlegroups.com, Eduardo Ibanez
Fantastic! Thank you so much, I tried to search for it but I only run into "how do I change the order of the legend entries" type of answers.

Brian Diggs

unread,
Nov 1, 2012, 1:33:39 PM11/1/12
to Eduardo Ibanez, ggplot2
On 10/31/2012 7:29 AM, Eduardo Ibanez wrote:
> Fantastic! Thank you so much, I tried to search for it but I only run into
> "how do I change the order of the legend entries" type of answers.

As described in
http://stackoverflow.com/questions/11393123/controlling-ggplot2-legend-display-order,
you no longer need to supply that newer guides_merge function and assign
it into the ggplot2 namespace. As of 0.9.2, that has been merged into
the code.
>> On Wed, Oct 31, 2012 at 9:43 PM, Eduardo Ibanez <edu.i...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org<javascript:>
>>> To post: email ggp...-/JYPxA39Uh5...@public.gmane.org <javascript:>
>>> To unsubscribe: email ggplot2+u...-/JYPxA39Uh5...@public.gmane.org <javascript:>
>>> More options: http://groups.google.com/group/ggplot2
>>>
>>
>>
>


--
Brian S. Diggs, PhD
Senior Research Associate, Department of Surgery
Oregon Health & Science University
Reply all
Reply to author
Forward
0 new messages