Is it possible to exclude areas of maps made with sf and tmap?

Viewed 134

I have created a map of Europe using a shape file downloaded from Eurostat. The file also includes several European administered areas such as French Guiana. I would like to exclude these areas. Is that possible?

Here is a picture of the map, and here is my r code:

require(readxl)
library(sf)
library(tmap)
library(tmaptools)

options(scipen = 999)

data1 <- read_excel("National Data.1-kopi.xlsx")
mydata <- subset(data1, TIME == 2007)


mymap <- st_read("NUTS_RG_20M_2021_3035.shp", stringsAsFactors = FALSE)
str(mymap)

map_and_data <- inner_join(mymap, mydata)

tm_shape(map_and_data) +
  tm_polygons("POP25", id = "NUTS_ID", palette = "Blues")
  
2 Answers

Yes, you can. There is an option in tm_shape called bbox that is the one you should use to specify the limits of your map.

One important thing to remember (the tricky part) is that the box should be in the same unit system than the shape. If your shape is in longitude/latitude, use degrees, but in your case (crs=EPSG:3035), that is quite common for Europe, I use c(2377294, 1313597, 7453440, 5628510):

library(sf)
library(tmap)
library(tmaptools)
# Use giscoR, same source of map
library(giscoR)

mymap <- gisco_get_nuts(
  year = 2021,
  resolution = 20, epsg = 3035, nuts_level = 0
)


# Lets just pretend this is your data
set.seed(1241)
POP25 <- sample(1:50000, nrow(mymap))
mydata <- data.frame(
  NUTS_ID = mymap$NUTS_ID,
  POP25 = POP25
)

map_and_data <- inner_join(mymap, mydata)

# You need to pass the bbox argument. For Europe EPSG:3035
# this work
box <- c(2377294, 1313597, 7453440, 5628510)
class(box) <- "bbox"


tm_shape(map_and_data, bbox = box) +
  tm_polygons("POP25", id = "NUTS_ID", palette = "Blues")



enter image description here

I feel your pain, as I was facing exactly the same issue when preparing data for a blog post https://www.jla-data.net/eng/breadbaskets-of-europe/

At the end I resolved the issue in a hacky way - I filtered out problematic areas exceeding a certain distance from Bern (which makes a nice center for "civilized Europe" - I was happy to leave the bulk of Russia out, but needed the part around Königsberg in).

So consider this piece of code:

library(sf)
library(tmap)
library(dplyr)

# download shapefiles from GISCO API
europe <- giscoR::gisco_get_countries(resolution = "10",
                                      region = "Europe")


# Overseas France, Azores + Canaries, and don't get me started on East Prussia!
troublemakers <- subset(europe, CNTR_ID %in% c("FR", "PT", "ES", "RU"))

buffer <- tidygeocoder::geo("Bern", quiet = T) %>% 
  st_as_sf(coords = c("long", "lat"), crs = 4326) %>% 
  st_buffer(units::as_units(1750, "km")) %>% 
  st_geometry() # don't need the address column anymore

# remove the bits too far from Bern (roughly midway between Cadiz and Königsberg)
troublemakers <- troublemakers %>% 
  st_intersection(buffer) 

# administrative regions in equal area projection
europe <- europe %>% 
  filter(!CNTR_ID %in% c("RU", "SJ", "FR", "PT", "ES")) %>% 
  rbind(troublemakers) %>% 
  st_transform(3035) # equal area Lambert / "European Albers"

# apply it in a {tmap} fashion...
tm_shape(europe) +
  tm_polygons()

enter image description here

Related