[R] ggplot legend consolidation

Te, Kaom Kaom.Te at schwab.com
Mon Sep 10 18:46:24 CEST 2007


Hi Hadley,

I just tried out your suggestion, but it does not look like the
get_legends function is working correctly. Instead of returning a grob
back to me it returns NULL.

Here is my modified code and the results of running it.

Any help would be appreciated. I believe that once I can get the legend
in grob form then I can figure out how to deconstruct it myself. 

Thanks,
Kaom

> p.legend <- get_legends(p)
> grid.draw(p.legend)
Error in grid.draw(p.legend) : no applicable method for "grid.draw"
> p.legend
NULL
>

-------------------------------------------- BEGIN CODE
## Obtained from http://pastie.textmate.org/95755
get_legends <- function(plot) {
  if (length(plot$layers) == 0) stop("No layers to plot", call.=FALSE)
  
  # Apply function to layer and matching data
  dlapply <- function(f) mapply(f, data, layers, SIMPLIFY=FALSE)

  plot <- plot_clone(plot)
  layers <- plot$layers
  scales <- plot$scales
  facet <- plot$facet

  cs <- plot$coordinates

  # Evaluate aesthetics
  data <- lapply(layers, function(x) x$make_aesthetics(plot))
  
  # Facet
  data <- mapply(function(d, p) facet$stamp_data(d), data, layers,
SIMPLIFY=FALSE)
  # Transform scales where possible.  Also need to train so statisics
  # (e.g. stat_smooth) have access to info
  data <- dlapply(function(d, p) p$scales_transform(d, scales))
  dlapply(function(d, p) p$scales_train(d, scales))

  # Apply statistics
  data <- dlapply(function(d, p) p$calc_statistics(d, scales))
  data <- dlapply(function(d, p) p$map_statistics(d, plot))

  # Adjust position before scaling
  data <- dlapply(function(d, p) p$adjust_position(d, scales, "before"))
  # Transform, train and map scales
  # data <- dlapply(function(d, p) p$scales_transform(d, scales))
  dlapply(function(d, p) p$scales_train(d, scales, adjust=TRUE))
  data <- dlapply(function(d, p) p$scales_map(d, scales))

  # Adjust position after scaling
  data <- dlapply(function(d, p) p$adjust_position(d, scales, "after"))
  scales <- scales$minus(plot$scales$get_scales(c("x", "y", "z")))

  legends(scales, FALSE)
}


library(ggplot2)
data(mtcars)
 
grid.newpage()

hide_colour <- scale_colour_continuous()
hide_colour$legend <- FALSE

pushViewport(viewport(layout = grid.layout(2, 2)))
 
p <- ggplot(data = mtcars) +
  geom_point(mapping = aes(x = hp, y = mpg, colour = cyl)) +
  hide_colour

pushViewport(viewport(layout.pos.col = 1,
                      layout.pos.row = 1))
 
print(p, vp = current.viewport())
upViewport()
 
p <- ggplot(data = mtcars) +
  geom_point(mapping = aes(x = drat, y = disp, colour = cyl)) +
  hide_colour
 

pushViewport(viewport(layout.pos.col = 2,
                      layout.pos.row = 1))
 
print(p, vp = current.viewport())
upViewport()
 
p <- ggplot(data = mtcars) +
  geom_point(mapping = aes(x = qsec, y = mpg, colour = cyl)) +
  hide_colour
 
pushViewport(viewport(layout.pos.col = 1,
                      layout.pos.row = 2))
 
print(p, vp = current.viewport())
upViewport()

pushViewport(viewport(layout.pos.col = 2,
                      layout.pos.row = 2))
grid.rect()

p.legend <- get_legends(p)
grid.draw(p.legend) 
----------------------------------------------END CODE



-----Original Message-----
From: hadley wickham [mailto:h.wickham at gmail.com] 
Sent: Monday, September 10, 2007 7:58 AM
To: Te, Kaom
Cc: r-help at stat.math.ethz.ch
Subject: Re: [R] ggplot legend consolidation

> I have recently been introduced to the ggplot package by Hadley 
> Wickham and must say I am quite impressed so far at how easy it is to 
> make attractive plots, but one thing I am struggling over is how to 
> consolidate legends.

It's not currently possible to consolidate them (although in the distant
future that would be something nice to have), but you can turn them off:

hide_colour <- scale_colour_continuous() hide_colour$legend <- FALSE

p <- ggplot(data = mtcars) +
  geom_point(mapping = aes(x = hp, y = mpg, colour = cyl)) +
  hide_colour

You'll also need to twiddle your viewports a little so that you still
have space for the viewport, since space will not be allocated
automatically anymore.

The next thing is to extract the grob for the legend itself - this is a
little tricker, because there's currently no way to get at the scales
after they have been "trained" with the data.  Load get_legends from
http://pastie.textmate.org/95755, and then you can do:

grid.newpage(); grid.draw(get_legends(p))

If you're not familiar enough with grid to stitch all of these pieces
together, please let me know, but this should be enough to get you
started.

Hadley



More information about the R-help mailing list