mapinsetr
Map insets are small zoom-in or zoom-out maps that focus on particular
territories within a general map. mapinsetr provides a set of
functions that helps to create such insets.
You can install mapinsetr from the r-universe.
install.packages("mapinsetr", repos = "https://riatelab.r-universe.dev")
The aim of this example is to create a base map of Algeria’s
municipalities with an inset on the Algiers wilaya.
Here are the few steps of the base map creation process:
The geodata package offers an access to the GADM
database through the gadm() function. The ISO3
code of Algeria is DZA and we will need 2 levels of administrative
data (0 for the state and 2 for the municipalities).
Basemaps (SpatVector, terra objects) are downloaded unprojected in
WGS84. We have to transform them into simple feature collections (sf
objects) and project them in a valid projection (the EPSG code 30791
stands for “Nord Sahara 1959 / Voirol Unifie Nord”).
library(geodata)
#> Loading required package: terra
#> terra 1.8.29
library(sf)
#> Linking to GEOS 3.13.1, GDAL 3.10.2, PROJ 9.5.1; sf_use_s2() is TRUE
library(mapsf)
# download data from gadm.org
adm0 <- st_as_sf(gadm(country = "DZA", level = 0, path = tempdir()))
adm0 <- st_transform(adm0, "EPSG:30791")
adm2 <- st_as_sf(gadm(country = "DZA", level = 2, path = tempdir()))
adm2 <- st_transform(adm2, "EPSG:30791")
# plot
mf_map(adm0, lwd = 2)
mf_map(adm2, add = TRUE, col = "grey80", lwd = 0.2)

Our goal is to extract Alger municipalities. To extract those
municipalities we will use a mask.
This mask has to be an sf object. The create_mask function create a
mask based on a bbox, an sf or sfc extent or an interactively
defined rectangle.
In this example we use a mask defined by Algiers wilaya extent + a 2 km
buffer.
library(mapinsetr)
alger_extent <- st_buffer(adm2[adm2$NAME_1=="Alger", ],dist = 2000)
box_alger <- create_mask(bb = alger_extent)
mf_map(adm0, lwd = 2)
mf_map(adm2, add = TRUE, col = "grey80", lwd = 0.2)
mf_map(box_alger, border = "red", col = NA, add = TRUE, lwd = 2)

Alternatively, one can define the mask interactively on the plot :
library(mapinsetr)
mf_map(adm0, lwd = 2)
mf_map(adm2, add = TRUE, col = "grey80", lwd = 0.2)
box_alger_interactive <- create_mask(interactive = TRUE, add=TRUE,
prj = st_crs(adm0))

The move_and_resize function extracts polygons or multipolygons (x)
within a mask (mask), moves them to coordinates (xy, bottom left
corner of the inset) and resizes them according to a factor (k).
zoom_alger <- move_and_resize(x = adm2, mask = box_alger, xy = c(-1000000, -100000), k = 15)
box <- move_and_resize(x = box_alger, mask = box_alger, xy = c(-1000000, -100000), k = 15)
mf_map(adm0, lwd = 2)
mf_map(adm2, add = TRUE, col = "grey80", lwd = 0.2)
mf_map(box_alger, border = "red", col = NA, add = TRUE, lwd = 2)
mf_map(zoom_alger, add = TRUE, col = "grey80", lwd = 0.2)
mf_map(box, border = "red", col = NA, lwd = 1, add = TRUE)

We currently have 2 sf objects, the next step is to merge them in a
single one. inset_rbinder merge the initial basemap and the inset.
adm2final <- inset_rbinder(list(adm2, zoom_alger))
mf_map(adm2final, col = "grey80", lwd = 0.2)
mf_title("Final basemap with inset!")

The following example build a map of Municipalities types.
library(mapsf)
mf_map(adm2final, var = "TYPE_2", type = "typo",
leg_title = "Commune Type", border = "white",
lwd = 0.1, pal = "Set 3",
leg_pos = "left")
mf_map(adm0, lwd = 2, add = TRUE, col = NA)
mf_map(box_alger, border = "red", col = NA, add = TRUE, lwd = 2)
mf_map(box, border = "red", col = NA, lwd = 2, add = TRUE)
mf_title("Commune Types in Algeria with a Zoom on Algiers Region")
mf_credits("GADM 4.1, 2025")
mf_scale(200)
mf_arrow(pos = "topright")
