[R-sig-Geo] Multiple legends in spplot

Edzer Pebesma edzer.pebesma at uni-muenster.de
Wed Dec 22 12:01:50 CET 2010


Lee,

looking at sp:::SpatialPolygons2Grob, you can exactly see what this
function wants and does with it. As a (second) legend involves not only
polygons, but also points, symbols, and text, it will not do the job.

An ad-hoc solution to this would be, building on your well-prepared
example and the code present in package sp:

mapLegendGrob2 <- function(obj, widths = unit(1, "cm"), heights =
unit(1, "cm"), fill = "black", just = "right", labels) {
    grb1 = SpatialPointsLegend(obj, fill = fill)
    grb2 = TextLegend(labels)
    key.layout <- grid.layout(nrow = 1, ncol = 1, widths = widths,
                    heights = heights, respect = TRUE, just = just)
    key.gf <- frameGrob(layout = key.layout)
#   key.gf <- placeGrob(key.gf,
#                 rectGrob(gp = gpar(fill = "transparent", col = NULL)),
#                 row = NULL, col = NULL)
    key.gf <- placeGrob(key.gf, grb1, row = 1, col = 1)
    key.gf <- placeGrob(key.gf, grb2, row = 1, col = 1)
    key.gf
}

TextLegend = function(labels, dist = 0.5) {
    x = rep(dist, length(labels))
    y = 1:length(labels)
    textGrob(labels, x, y, just = "left")
}
SpatialPointsLegend = function(pch, fill) {
    x = rep(0, length(pch))
    y = 1:length(pch)
    pointsGrob(x=x, y=y, pch=pch, gp = gpar(fill = fill))
}
spplot(spdfMeuse,
    sp.layout = list("sp.points", meuse, pch = as.integer(meuse $soil)),
    legend = list(inside = list(fun = mapLegendGrob2(1:3, fill=1:3,

    labels=c("a","b","c")), x = 1, y = 0.1, corner = c(0,0)))
)

I'm not very familiar with the functions in package grid, so there might
be lots of room for improvement. A more generic solution would be very
welcome, but this might get you somewhat further.

On 12/22/2010 05:44 AM, Lee Hachadoorian wrote:
> Trying to produce spplot with a point layer on top of a polygon layer. 
> Looks like this can be accomplished using plot() (see for example http://
> www.asdar-book.org/code.php?chapter=2&figure=7), but I want to use spplot 
> for the typical reasons (i.e, to produce several polygon maps showing 
> related attributes using the same quantitative classes).
> 
> That problem statement might be enough to point me to an example 
> somewhere, since I assume I'm not the first person who has wanted to do 
> this, but I haven't been able to find anything in the help or the 
> archives. Apologies if I'm missing something obvious.
> 
> More specifically, I would like something that looks like this figure 
> 
> http://r-spatial.sourceforge.net/gallery/#fig04.R
> 
> except instead of a north arrow, the right should have a colorkey for the 
> polygon object. Using standard data:
> 
> library(sp)
> library(lattice)
> 
> #CREATE SpatialPolygonsDataFrame OF RIVERBED
> data(meuse.riv)
> meuse.lst = list(Polygons(list(Polygon(meuse.riv)), "meusee.riv"))
> spdfMeuse = SpatialPolygonsDataFrame(
> 	SpatialPolygons(meuse.lst),
> 	data.frame(anything = 1, row.names = "meusee.riv")
> )
> 
> #CREATE SpatialPoints OF SOIL SAMPLES
> data(meuse)
> coordinates(meuse) = c("x", "y")
> 
> #THIS PLOTS POLYGONS AND POINTS WITH A colorkey FOR THE POLYGONS
> spplot(spdfMeuse,
> 	sp.layout = list("sp.points", meuse, pch = as.integer(meuse$soil))
> )
> 
> #THIS PLOTS POLYGONS AND POINTS WITH A LEGEND FOR THE POINTS
> spplot(meuse, "soil", 
> 	key.space = list(x = 0.1, y = 0.93, corner = c(0,1)),
> 	sp.layout = list("sp.polygons", spdfMeuse, fill = "lightblue")
> )
> 
> So I can combine both layers, but I haven't been able to figure out how 
> to get both legends. Figure 4 from the R-spatial gallery (referenced 
> above) uses the legend argument to add a North arrow. Since xyplot() 
> specifies that the legend argument is necessary to produce multiple keys, 
> I'm assuming the answer must make use of it. But trying to adapt the code 
> for Figure 4 as:
> 
> spplot(spdfMeuse,
> 	sp.layout = list("sp.points", meuse, pch = as.integer(meuse
> $soil)),
> 	legend = list(inside = list(fun = mapLegendGrob(meuse, "soil"), x 
> = 1, y = 0.1, corner = c(0,0)))
> )
> 
> yields:
> 
> Error in SpatialPolygons2Grob(obj, fill) : 
>   object is not of class SpatialPolygons
> Calls: spplot ... .local -> append -> mapLegendGrob -> 
> SpatialPolygons2Grob
> 
> sessionInfo() below the sig.
> 
> Regards, 
> Lee Hachadoorian
> PhD Student, Geography
> Program in Earth & Environmental Sciences
> CUNY Graduate Center
> 
>> sessionInfo()
> R version 2.12.1 (2010-12-16)
> Platform: x86_64-pc-linux-gnu (64-bit)
> 
> locale:
>  [1] LC_CTYPE=en_US.utf8          LC_NUMERIC=C                
>  [3] LC_TIME=en_US.utf8           LC_COLLATE=en_US.utf8       
>  [5] LC_MONETARY=en_US.utf8       LC_MESSAGES=en_US.utf8      
>  [7] LC_PAPER=en_US.utf8          LC_NAME=en_US.utf8          
>  [9] LC_ADDRESS=en_US.utf8        LC_TELEPHONE=en_US.utf8     
> [11] LC_MEASUREMENT=en_US.utf8    LC_IDENTIFICATION=en_US.utf8
> 
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base     
> 
> other attached packages:
> [1] lattice_0.19-13    RColorBrewer_1.0-2 RSQLite_0.9-2      
> sp_0.9-66         
> [5] RPostgreSQL_0.1-6  DBI_0.2-5          rkward_0.5.4      
> 
> loaded via a namespace (and not attached):
> [1] grid_2.12.1  tools_2.12.1
> 
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo at r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo

-- 
Edzer Pebesma
Institute for Geoinformatics (ifgi), University of Münster
Weseler Straße 253, 48151 Münster, Germany. Phone: +49 251
8333081, Fax: +49 251 8339763  http://ifgi.uni-muenster.de
http://www.52north.org/geostatistics      e.pebesma at wwu.de



More information about the R-sig-Geo mailing list