Plotting a map with a zoomed mini map
Asked Answered
H

1

5

Does anyone know how to plot a map with a zoomed region adjacent to it similar to this:

enter image description here

A close answer can be found here:

R - Map Zoom Function, making the plot a circle rather than a square

But that solution doesn't show which region is zoomed in! I want something like the above picture in which the zoomed region is also indicated by those yellow lines. Is this possible in R and preferably with ggplot?

Holiness answered 3/7, 2021 at 17:6 Comment(1)
A place to start: upgo.lab.mcgill.ca/2019/12/13/making-beautiful-mapsSearching
J
6

Here's one (shoddy) way of doing this. I'm still a ggplot amateur... I had trouble drawing lines in cowplot between the two ggplot objects, so I assigned a new coordinate system for the resulting plot and manually defined the start and endpoints for lines. If anyone has suggestions for how to improve this, particularly for assigning the leader line coordinates programmatically, I'm all ears.

Inspiration from https://r-spatial.org/r/2018/10/25/ggplot2-sf-3.html and https://geocompr.github.io/post/2019/ggplot2-inset-maps/

library(sf)
library(spData)
library(ggplot2)
library(cowplot)
library(rcartocolor)

data("us_states", package = "spData")
north_carolina = read_sf(system.file("shape/nc.shp", package = "sf"))

us_states_2163 = st_transform(us_states, crs = 2163)
north_carolina_2163 = st_transform(north_carolina, crs = 2163)

north_carolina_2163_bb = st_as_sfc(st_bbox(north_carolina_2163))
mainbox <- st_bbox(north_carolina_2163)

# inset panel
inset = ggplot() + 
  geom_sf(data = us_states_2163, fill = "white") + 
  geom_sf(data = north_carolina_2163_bb, fill = NA, color = "yellow", size = 1.2) +
  theme_void()

# main panel
main = ggplot() + 
  geom_sf(data = north_carolina_2163, aes(fill = BIR74)) +
  scale_fill_carto_c(palette = "Mint") +
  geom_sf(data = north_carolina_2163_bb, fill = NA, color = "yellow", size = 1.2) +
  theme_void() +
  theme(legend.position = "none")

# map
gg_inset_map1 = cowplot::ggdraw() +
  coord_equal(xlim = c(0, 20), ylim = c(0, 20), expand = FALSE) +
  annotation_custom(ggplotGrob(inset), xmin = 0, xmax = 10, ymin = 10, ymax = 20) +
  annotation_custom(ggplotGrob(main), xmin = 0, xmax = 20, ymin = 0, ymax = 10) +
  geom_segment(aes(x = 8.9, xend = 19, y = 14.4, yend = 9.2), color = "yellow", size = 1.2) +
  geom_segment(aes(x = 7.5, xend = 1, y = 14.4, yend = 9.2), color = "yellow", size = 1.2)

ggplot map inset indicator lines

E: I ran into this question and answer and thought it was relevant here. This is one approach to using the data within the grob to define the location of the lines. However, as the author of the answer points out, this is a "fiddly...one off solution." The answer I submitted is similar in that regard... and a lot less work than sifting through grob attributes...

Janitress answered 4/7, 2021 at 14:36 Comment(2)
Hi Skaqqs, did you assign the geom_segment parameters through trial and error or what was the way you determined the values to use?Fosque
Yes, I just used trial and error in this one. In my edit, you'll see an example where the lines are drawn dynamically, or at least somewhat, but like I quote in the edit, it's not completely hands off.Janitress

© 2022 - 2024 — McMap. All rights reserved.