insetplot is an R package to create ggplot2 maps with inset maps easily and flexibly. It handles spatial configuration, aspect ratios, and plot composition automatically.
Quick start
Approach 1: Reuse one plot (simplest)
Use the same plot for the main map and all insets — let insetplot handle sizing and positioning.
library(insetplot) library(sf) library(ggplot2) # Load data nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE) # Configure insets: one main + one inset config_insetmap( bbox = st_bbox(nc), specs = list( inset_spec(main = TRUE), inset_spec( xmin = -84, xmax = -75, ymin = 33, ymax = 37, loc = "left bottom", scale_factor = 0.5 ) ) ) # Compose with_inset( ggplot(nc, aes(fill = AREA)) + geom_sf() + scale_fill_viridis_c() + theme_void() )
Approach 2: Custom plot per subplot
Provide specific plots for the main and inset maps.
base_plot <- ggplot(nc, aes(fill = AREA)) + geom_sf() + scale_fill_viridis_c() + theme_void() main_plot <- base_plot + ggtitle("Full North Carolina") inset_plot <- base_plot + ggtitle("Detail Region") config_insetmap( bbox = st_bbox(nc), specs = list( inset_spec(main = TRUE, plot = main_plot), inset_spec( xmin = -84, xmax = -75, ymin = 33, ymax = 37, loc = "left bottom", scale_factor = 0.5, plot = inset_plot ) ) ) with_inset() # plot argument optional when each spec has its own plot
Installation
To install the released version from CRAN:
install.packages("insetplot")To install the development version from GitHub:
devtools::install_github("fncokg/insetplot")
Documentation
Full documentation and more examples are available at insetplot package site.
Fast overview of main functions
-
inset_spec()— Define bbox, position, and size for each subplot- bbox:
xmin, xmax, ymin, ymax - position:
loc(e.g., "left bottom") orloc_left/loc_bottomin [0, 1] - size: prefer
scale_factor; or provide one ofwidth/height plot: optional custom ggplot objectmain: exactly one spec must setmain = TRUE
- bbox:
-
config_insetmap()— Build and store configurationspecs: list ofinset_spec(), requiredbbox: overall bounding box (sf bbox or similar), optional (all specs must have fullly defined bboxes if omitted)to_crs: target Coordinate Reference System, optional, by default "EPSG:4326"from_crs: source CRS for non-sf inputs, optional, by default "EPSG:4326"border_args: forwarded tomap_border()for inset borders, optional
-
with_inset()— Compose main plot with insetsplot: single ggplot or list per spec.as_is: return the input plot as-is (skip inset composition).return_details: returnlist(full, subplots, subplot_layouts, main_ratio)
-
ggsave_inset()— Save with the correct aspect ratio- Provide one of
widthorheight; the other is computed frommain_ratio - Optional
ratio_scalefor small adjustments (e.g., legends)
- Provide one of
-
map_border()— Small theme to draw a rectangular border around plots
Further examples
Custom positioning and sizing
config_insetmap( bbox = st_bbox(nc), specs = list( inset_spec(main = TRUE), inset_spec( xmin = -84, xmax = -75, ymin = 33, ymax = 37, loc_left = 0.05, loc_bottom = 0.05, # Use width only; height auto-calculated to preserve aspect ratio width = 0.25 ) ) ) with_inset(base_plot)
Pass custom plots after configuration
config_insetmap( bbox = st_bbox(nc), specs = list( inset_spec(main = TRUE), inset_spec( xmin = -84, xmax = -75, ymin = 33, ymax = 37, loc = "left bottom", scale_factor = 0.5, ) ) ) with_inset(list(main_plot, inset_plot))
Save with correct aspect ratio
ggsave_inset( "map_with_insets.png", # `height` auto-calculated from `main_ratio` width = 12, dpi = 300 )
Debugging with detailed output
result <- with_inset(plot = my_plot, .return_details = TRUE) # result$full, result$subplots, result$subplot_layouts, result$main_ratio