Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordering of multiple legends/guides (what is the automatic logic & how to change it?)

Tags:

I stumbled onto this weird behavior with ggplot2s ordering of legends and just can't figure out what the logic behind the automatic placement of the legends is:

My aim: In a plot with multiple scales I want to arrange them in a different (thematic) order than the automatic one. But I couldn't find a command in opts() or guides() to do this for me. And just to be clear: I don't want to change the items within the legends, that works fine, but the arrangement of multiple complete legends.

So first I assumed they were ordered by type, i.e. scale, colour etc. But that is not the case, their position changes (see below).

Alphabetical order? No.

    library(ggplot2) ## v0.9

    ## Scale_colour on top
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class) +
    scale_size(name = "A") + scale_colour_discrete(name = "B")

    ## Reverse names --> scale_colour on bottom
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class) +
    scale_size(name = "B") + scale_colour_discrete(name = "A")

    ## Change name B to C -->  scale_colour on bottom
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class) +
    scale_size(name = "C") + scale_colour_discrete(name = "A")

    ## Change name B to D -->  scale_colour on top
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class) +
    scale_size(name = "D") + scale_colour_discrete(name = "A")

Further positions of scale_colour (for exchanged scale_size name)

  • "E": bottom
  • "F" - "L": top
  • "M" - "N": bottom

and it continues to appear on top an at the bottom.

Factorial order? No.

    ## From top to bottom: C - B - A
    fname <- factor(c("A","B","C"), levels = c("A","B","C"))
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class, alpha = cyl) +
    scale_size(name = fname[1]) + scale_colour_discrete(name = fname[2]) + scale_alpha(name=fname[3])

    ## From top to bottom: B - C - A
    fname <- factor(c("A","B","C"), levels = c("C","B","A"))
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class, alpha = cyl) +
    scale_size(name = fname[1]) + scale_colour_discrete(name = fname[2]) + scale_alpha(name=fname[3])

    ## From top to bottom: B - C - A
    fname <- factor(c("A","B","C"), levels = c("B","C","A"))
    qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class, alpha = cyl)+
    scale_size(name = fname[1]) + scale_colour_discrete(name = fname[2]) + scale_alpha(name=fname[3])

Length of title? No. I'll stop for now with example code, but that one also yielded fluctuating orders independent of character length.

Any ideas?

like image 442
bleutner Avatar asked Apr 05 '12 20:04

bleutner


1 Answers

As I mentioned in the comment above, there is no way to control and predict the position of legend box. I wasn't aware of this problem. Thank you for making clear this.

Maybe some people need to control the legend box, here I put a quick fix:

# 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")

and then you can use order argument for guide_legend (and also guide_colorbar),

# specify the order of the legend.
qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class, alpha = cyl)+
 guides(size = guide_legend(order = 1), colour = guide_legend(order = 2), alpha = guide_legend(order = 3))

qplot(data = mpg,x = displ, y = cty, size = hwy, colour = class, alpha = cyl)+
 guides(size = guide_legend(order = 3), colour = guide_legend(order = 1), alpha = guide_legend(order = 2))

order argument should be a positive integer. The legends are arranged along the order. Note that this is a quick fix so the interface may be changed in the next official version of ggplot2.

like image 151
kohske Avatar answered Jan 06 '23 11:01

kohske