Custom placement of spplot legend in the map

心已入冬 提交于 2019-12-05 03:33:17

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!