Is it possible to place the spplot (spplot polygons) legend within the map, in lower left corner, like this?
The closest I've been able to get is this (I am not posting my data, I just use the example data instead, so in this case, try to place the legend in top left part of the map):
data(meuse.grid)
gridded(meuse.grid)=~x+y
spplot(meuse.grid[,'dist'],
colorkey = list(space = "left", height = 0.5)
)
But the legend is in the middle of the page and is outside of the map. Unfortunatelly, colorkey
argument doesn't support "bottomleft", or x, y, or corner arguments (see ?levelplot
). I also tried to use key.space
argument, but it seems to only work when plotting SpatialPoints*
but it seems ignored for SpatialPolygons*
(or SpatialPixelsDataFrame like in the example above).
Since the key is a grob of its own it is perfectly possible to extract it from the plot object and draw it separately where ever you please.
library(grid)
# Separate plot and key
s <- spplot(meuse.grid[,'dist'],
colorkey = list(space = "left", height = 0.5)
)
key <- draw.colorkey(s$legend[[1]]$args$key)
s$legend <- NULL # Otherwise we'd get two keys
# Modify key
key$framevp$x <- unit(0.15, "npc")
key$framevp$y <- unit(0.68, "npc")
# Plot
s
grid.draw(key)
The complicating issue here is that, although the colorkey=
argument
is treated very much like the legend=
argument, it doesn't quite support
the full suite of positioning options that legend=
does. Whereas legends can be directly placed at "left"
, "right"
, "top"
, "bottom"
, and "inside"
the plot, colorkey=
only supports the first four of those.
A fairly clean workaround is to extract the colorkey argument list prepared by one call to spplot()
, and to pass that in to a second spplot()
call via its legend=
argument. colorkey=
"knows" how to prepare a colorkey object, and legend=
knows how to draw arbitrary objects inside of plots, so we can combine the two to get what we want:
library(sp)
library(grid)
library(lattice)
data(meuse.grid)
gridded(meuse.grid)=~x+y
## Call spplot() once as a way to construct a list of arguments
## to draw.color.key
SP <- spplot(meuse.grid[,'dist'],
colorkey = list(space = "left", height = 0.4)
)
args <- SP$legend$left$args$key
## Prepare list of arguments needed by `legend=` argument (as described in ?xyplot)
legendArgs <- list(fun = draw.colorkey,
args = list(key = args),
corner = c(0.05,.75))
## Call spplot() again, this time passing in to legend the arguments
## needed to print a color key
spplot(meuse.grid[,'dist'], colorkey = FALSE,
legend = list(inside = legendArgs))
Note: colorkey=
's lack of support for an "inside" option appears to be
less a design choice than just a matter of the package authors' not yet having gotten around to implementing the requisite code. As evidence of that, see the documentation for colorkey=
in ?lattice::levelplot
(to which one is directed by `?sp::spplot):
colorkey: logical specifying whether a color key is to be drawn
alongside the plot, or a list describing the color key. The
list may contain the following components:
‘space’: location of the colorkey, can be one of ‘"left"’,
‘"right"’, ‘"top"’ and ‘"bottom"’. Defaults to
‘"right"’.
‘x’, ‘y’: location, currently unused
‘corner’: Interacts with x, y; currently unimplemented