I'm trying to have a rectangular "zoom in" into my chart. So far, I can create the chart itself and a smaller version, but I haven't figured out how to zoom in rectangularly.
library(sf)
library(dplyr)
library(tmap)
Get shape files for Germany [55 MB]. In Germany zip codes are called Postleitzahlen (PLZ).
germany <- read_sf("data/OSM_PLZ.shp")
Create some arbitrary groups:
germany <- germany %>%
mutate(plz_groups = case_when(
substr(plz, 1, 1) == "1" ~ "Group A",
substr(plz, 2, 2) == "2" ~ "Group B",
substr(plz, 3, 3) == "2" ~ "Group C",
TRUE ~ "Group X" # rest
))
Make plot filling by PLZ:
map_de <- tm_shape(germany) +
tm_fill(col = "plz_groups")
map_de
germany_zoomin <- germany %>%
filter(substr(plz, 1, 1) == "4")
map_zoomin <- tm_shape(germany_zoomin) +
tm_fill(col = "plz_groups")
So I can create a zoomed in chart, but this is NOT what I want:
map_zoomin
print(map_de, vp = grid::viewport(0.8, 0.185, width = 0.2, height = 0.45))
# tmap_save("test.png")
Instead, I would like to specify the location, e.g. the PLZ of Cologne (50667) and draw a rectangular box around it.
Do you mean something like the following? For Cologne I created some dummy values and added the postal codes as text to show where the reference postal code is located. Furthermore, I added a small rectangle that shows the zoom-in area in the Germany main map (only visible as small black polygon):
library(tidyverse)
library(sf)
library(tmap)
library(tmaptools)
germany <- read_sf("data/OSM_PLZ.shp")
germany <- germany %>%
mutate(plz_groups = case_when(
substr(plz, 1, 1) == "1" ~ "Group A",
substr(plz, 2, 2) == "2" ~ "Group B",
substr(plz, 3, 3) == "2" ~ "Group C",
TRUE ~ "Group X" # rest
))
# take reference postal code in cologne
cologne_plz_target <- germany %>%
filter(plz == "50667")
# get content within bounding box defined around target postal code
cologne_bbox = st_as_sfc(bb(st_bbox(cologne_plz_target), ext = 5))
# convert bounding box to spatial object
cologne_rect <- bb_poly(cologne_bbox)
map_de <- tm_shape(germany) +
tm_fill(col = "plz_groups") +
tm_shape(cologne_rect) + # add zoom in area to main map
tm_polygons(col = "black")
# all cologne postal codes with dummy values
cologne_plz_all <- germany %>%
filter(ort == "Köln") %>%
mutate(plz_groups = case_when(
str_detect(plz, "^508") ~ "Group A",
str_detect(plz, "^507") ~ "Group B",
str_detect(plz, "^509") ~ "Group C",
TRUE ~ "Group X" # rest
))
map_cologne <- tm_shape(germany, bbox = cologne_bbox) +
tm_polygons() +
tm_shape(cologne_plz_all) +
tm_fill(col = "plz_groups",
legend.show = F) +
tm_borders() +
tm_text(text = "plz") # just to show where target plz is located
map_cologne
print(map_de, vp = grid::viewport(0.825, 0.25, width = 0.2, height = 0.45))