4

I am using the sp package in R to plot sampled points along a river. However, I would like to zoom in to a sampled area of the entire river, and plot this zoomed area on the full length of the river. Using the spplot function is useful, as I have various variables per point. To "zoom" in, I can simple change the ylim and xlim arguments when using the spplot function.

Using the meuse dataset as an example

library(sp)
library(lattice) 
data(meuse)
coordinates(meuse)=~x+y 
FUll.study<-spplot(meuse)            #Gives the full study area
ZOOM<-spplot(meuse, xlim=c(170000,  181000), ylim=c(329714,333611))   #Random area to zoom in.

The results look like this:

enter image description here

However the desired result is something like this:

enter image description here I am trying to find a way to add the ZOOM to an area on the Full.study map.I suspect because spplot is dependent on lattice it may not be possible. In that case, I would have to create a map for each variable independently, and add the respective zoomed area, probably through par(new=TRUE), but this is just a thought. I would still have to figure out how to specify the location and adjust the size of the of zoomed area. Any suggestions would be welcomed. Thanks in advance.

  • I'm not clear on what you mean by "add the ZOOM to an area on the Full.study". Do you mean you just want to put the two plots next to each other? Or do you mean some sort of overlay? A clearer description of your desired result would be helpful. – Matthew Plourde Nov 4 '14 at 19:46
  • @ Matthew, thanks .. I added figures to show the result I am looking for. – user2507608 Nov 5 '14 at 23:46
6

Here is a suggestion using ggplot. I use ggplotGrob to combine the full and zoomed map and grid.arrange from the gridExtra add-on to combine the maps for different variables. There are many adjustments that can be made, of course.

library(sp)
library(ggplot2)
library(grid) # for unit
library(gridExtra) # for grid.arrange

# zoom bounding box
xlim <- c(179500,181000); ylim <- c(332000,332500)

# size of zoomed area - offset from top left corner of main plot: 
x_offs <- 1000 ; y_offs <- 1300

# settings for full plot
fulltheme <- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
            panel.background = element_blank(), 
            axis.text.x=element_blank(), axis.text.y=element_blank(),
            axis.ticks=element_blank(),
            axis.title.x=element_blank(), axis.title.y=element_blank())

# settings for zoom plot
zoomtheme <- theme(legend.position="none", axis.line=element_blank(),axis.text.x=element_blank(),
            axis.text.y=element_blank(),axis.ticks=element_blank(),
            axis.title.x=element_blank(),axis.title.y=element_blank(),
            panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
            panel.background = element_rect(color='red', fill="white"),
            plot.margin = unit(c(0,0,-6,-6),"mm"))


############## point example  #############
data(meuse)

# variables to plot
vars <- names(meuse)[3:10]

plotlist <- list()

for (i in vars) {
  # full plot
  p.full <- ggplot(meuse, aes_string(x = "x", y = "y", color=i)) + 
    geom_point() + fulltheme
  # zoomed plot
  p.zoom <- ggplot(meuse, aes_string(x = "x", y = "y", color=i)) + 
    geom_point() + coord_cartesian(xlim=xlim, ylim=ylim) + zoomtheme
  # put them together
  g <- ggplotGrob(p.zoom)
  plotlist[[length(plotlist) + 1]] <- p.full + 
    annotation_custom(grob = g, xmin = min(meuse$x), xmax = min(meuse$x) + x_offs, ymin = max(meuse$y) - y_offs, ymax = max(meuse$y))
}

# plot
do.call(grid.arrange,  c(plotlist, ncol=4))

enter image description here

Similarly, ggplot can handle rasters.

############################################
############## raster example  #############

library(raster)

r <- raster(system.file("external/test.grd", package="raster"))
s <- stack(r, r*2, log(r))
names(s) <- c('meuse', 'meuse2', 'meuseLog')
meuseRast <- data.frame(rasterToPoints(s))

rastvars <- names(meuseRast)[-c(1:2)]
plotrast <- list()

for (i in rastvars) {
   p.fullrast <- ggplot(meuseRast, aes_string(x = "x", y = "y", fill = i)) + 
      geom_raster() + fulltheme

   p.zoomrast <- ggplot(meuseRast, aes_string(x = "x", y = "y", fill = i)) + 
      geom_raster() + coord_cartesian(xlim=xlim, ylim=ylim) + zoomtheme

   g <- ggplotGrob(p.zoomrast)
   plotrast[[length(plotrast) + 1]] <- p.fullrast + 
     annotation_custom(grob = g, xmin = min(meuseRast$x), xmax = min(meuseRast$x) + x_offs, ymin = max(meuseRast$y) - y_offs, ymax = max(meuseRast$y))
}

# plot
do.call(grid.arrange,  c(plotrast, nrow=1))

enter image description here

  • @ cengel, thanks for this solution. It is perfect for point data, but I will also have data in the form of rasters. – user2507608 Nov 7 '14 at 23:04
  • @user2507608 ggplot can do the same with rasters. I have extended the code above with a raster example. – cengel Nov 8 '14 at 2:45
  • It works great on the point data. However I keep getting an error when trying to reproduce the raster graphs: Error in as.environment(where) : 'where' is missing Any idea why this could be. Thanks again though. – user2507608 Nov 9 '14 at 8:33
  • @user2507608: My apologies, I added the second example rather quickly. Instead of aes_string("x", "y".... it should be aes_string(x = "x", y = "y"..... I changed this now. Let me know if this still does not work. – cengel Nov 10 '14 at 0:16
0

You can use the maptools::elide function to translate coordinates of a Spatial*object. If you combine the result with the sp.layout argument of spplot or with the latticeExtra::layer function, you will get what you need:

library(sp)
library(maptools)
library(raster)
library(lattice)
library(latticeExtra)

data(meuse)
coordinates(meuse)=~x+y 

ZOOM <- crop(meuse, extent(180000,  181000, 330000, 331500))

displaced <- elide(ZOOM, shift = c(-1200, 2000))

spplot(meuse["zinc"], scales = list(draw = TRUE)) +
    layer({
        sp.points(ZOOM, col = 'black')
        sp.points(displaced, col = '')
    })

elide

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.