Search code examples
rplotgislattice

map with panel plots


I am following the excellent example here. Everything works until the grid plotting,

library("lattice")
spplot(sp_grd, "id", colorkey=FALSE,
       panel = function(...) {
         panel.gridplot(..., border="black", col.regions="white")
         sp.polygons(shp)
         sp.points(poi, cex=1.5)
         panel.text(..., col="red")
       })

When I attempt this plotting, I get the error,

'Error using packet 1 formal argument "col.regions" matched by multiple actual arguments'.

Any ideas for fixes? Basically I don't want the panels to be filled in with colours, as it defaults to do.

EDIT: Reproducible example modified from link.

### read shapefile
library("rgdal")
library("lattice")
library("rworldmap")
shp <- getMap(resolution="low")

### define coordinates and convert to SpatialPointsDataFrame
poi <- data.frame(x=c(15, 25, 35, 100),
                  y=c(-15, 25, -35, -50),
                  id="A", stringsAsFactors=F)
coordinates(poi) <- ~ x + y
proj4string(poi) <- proj4string(shp)

### define SpatialGrid object
bb <- bbox(shp)
cs <- c(10, 10)
cc <- bb[, 1] + (cs/2)  # cell offset
cd <- ceiling(diff(t(bb))/cs)  # number of cells per direction
grd <- GridTopology(cellcentre.offset=cc, cellsize=cs, cells.dim=cd)

sp_grd <- SpatialGridDataFrame(grd,
                               data=data.frame(id=1:prod(cd)),
                               proj4string=CRS(proj4string(shp)))
# does work
spplot(sp_grd, "id",
       panel = function(...) {
         panel.gridplot(..., border="black")
         sp.polygons(shp)
         sp.points(poi, cex=1.5)
         panel.text(...)
       })

# does not work
spplot(sp_grd, "id",
       panel = function(...) {
         panel.gridplot(..., border="black", col.regions="white")
         sp.polygons(shp)
         sp.points(poi, cex=1.5)
         panel.text(...)
       })

Solution

  • You're getting that error message because panel.gridplot() is being passed two different arguments named col.regions. You've supplied one explicitly, and the other is being (by default) passed on through the dots (...) argument of your panel function.

    The solution is to add col.regions as a formal argument to your panel function. That way, it'll capture the col.regions argument coming from outside (i.e. from spplot()), removing it from the list of otherwise unmatched arguments that get soaked up by .... Your call to panel.gridplot() will then only have one argument named col.regions=, and will work as you expected it to.

    This will do the trick:

    spplot(sp_grd, "id", colorkey=FALSE,
           panel = function(..., col.regions) {
             panel.gridplot(..., border="black", col.regions="white")
             sp.polygons(shp)
             sp.points(poi, cex=1.5)
             panel.text(...)
    })