Search code examples
rggplot2rasterr-sfterra

How to zoom in on multiple points of a map and include them all in separate panels?


I have multiple polygons and a raster that make up my map. I would like to "zoom" into each of these polygons in order to better visualize the raster information within each of the polygons. I figure i can eventually use some combination of facet_grid and ggdraw for the final map, but for now I need help creating the "zoomed in" portion of the map.

Example:

#Raster layer
library(terra)
library(raster)
library(sf)

f <- system.file("ex/elev.tif", package="terra")
r <- rast(f)

#polygons
v <- vect(system.file("ex/lux.shp", package="terra"))
v <- v[c(1:10)] 

#Base plot
ggplot() +
  geom_raster(data = r, aes(x = x, y = y, fill = elev)) +
  geom_sf(data = v, fill = NA, col = "red") 

I know both the raster and terra packages have a zoom function, but i'm unable to use it with ggplot. Any guidance would be welcome, thanks!


Solution

  • I couldn't get your example data to work, however you can zoom in on portions of a ggplot using either:

    your_plot+
       coord_cartesian(
          xlim = c(xmin, xmax), 
          ylim = c(ymin, ymax)
       )
    

    or

    your_plot+
       xlim(xmin, xmax)+
       ylim(ymin, ymax)
    

    or

    your_plot+
       scale_x_continuous(limits = c(xmin, xmax))+
       scale_y_continuous(limits = c(ymin, ymax))
    

    Be aware that the latter 2 examples actually 'cut off' data points outside the 'zoomed' area, so for example lines or polygons which extend beyond the zoomed area will look different. coord_cartesian doesn't cut points off, and in this instance is probably what you want. This is explained nicely in the ggplot2 cheatsheet found here

    enter image description here

    Additionally, if you are plotting an sf object using geom_sf(), you can also use coord_sf(), which is designed to handle spatial data, and also does not 'cut off' data which extends outside the plot area.

    your_plot+
       coord_sf(
          xlim = c(xmin, xmax), 
          ylim = c(ymin, ymax)
       )
    

    One tip: make sure the min value is less than the max value when specifying the limits. This might sound obvious, but for example here in Australia our latitudes (y values) are all negative. Therefore, it's easy to accidently confuse the 'smaller' number with the 'larger' number.

    One way to arrange your individual zoomed plots into one is by using cowplot::plot_grid (cowplot documentation here). As a very basic example, you simply provide it with ggplot objects you want to arrange together (see documentation)

    plot_grid(p1, p2, p3, p4)