2

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?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Amin Shn
  • 532
  • 2
  • 11

1 Answers1

4

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...

Skaqqs
  • 4,010
  • 1
  • 7
  • 21