How can I change the color of a shared border between countries using sf?
Asked Answered
I

1

5

I would like to change the color of a shared color to a different color, let's say red. So far, I am plotting the German federal state Bavaria and touching Austrian states. I get the data from https://gadm.org/download_country.html -

Germany Level 2 - https://biogeo.ucdavis.edu/data/gadm3.6/Rsf/gadm36_DEU_2_sf.rds

Germany Level 1 - https://biogeo.ucdavis.edu/data/gadm3.6/Rsf/gadm36_DEU_1_sf.rds

Austria Level 2 - https://biogeo.ucdavis.edu/data/gadm3.6/Rsf/gadm36_AUT_2_sf.rds

Austria Level 1 - https://biogeo.ucdavis.edu/data/gadm3.6/Rsf/gadm36_AUT_1_sf.rds

library("sf")
library("raster")
library("dplyr")
library("spData")
library("spDataLarge")
library("ggplot2")
library("patchwork")
library(tmap)    # for static and interactive maps
library(ggpattern)

data_aut <- readRDS("~/plot_at_ger/data/gadm36_AUT_2_sf.rds")
data_ger <- readRDS("~/plot_at_ger/data/gadm36_DEU_2_sf.rds")
data_aut_high <- readRDS("~/plot_at_ger/data/gadm36_AUT_1_sf.rds")
data_aut_high <- data_aut_high[which(data_aut_high$NAME_1=='Salzburg' | data_aut_high$NAME_1=='Oberösterreich' | data_aut_high$NAME_1=='Tirol' | data_aut_high$NAME_1=='Vorarlberg'), ]
data_ger_high <- readRDS("~/plot_at_ger/data/gadm36_DEU_1_sf.rds")
data_ger_high <- data_ger_high[which(data_ger_high$NAME_1=='Bayern'), ]

ggplot() +
  geom_sf(data = ger_selected_data_bavaria, fill = NA) +
  geom_sf(data = aut_selected_data_rel, fill = NA) +
  geom_sf(data = data_aut_high, fill = NA, size = 1, color = "grey35") +
  geom_sf(data = data_ger_high, fill = NA, size = 1, color = "black") 

This produces the following figure:

Bavaria-Austria Bordering States

Is there a way to change the color of the shared border?

Thanks!

Interlard answered 14/12, 2021 at 13:20 Comment(6)
Kevin, welcome to SO. This seems generally an interesting question, would you care trying to make it reproducible (both for us to help you and for future generations, to help them understand the problem and its solution)Buggy
check stackoverflow.com/help/minimal-reproducible-example and #5963769Buggy
Thanks for your comment! I added more information, hope that helps!Interlard
@Buggy I looked at the linked comments and I tried using dput, but shapefiles contain a large amount of information. In general, is linking the original database superior in this case? I know that most people won't download the files and providing data in my question would be superior, but I am not sure what the best solution would be in this case.Interlard
You tried! Check @JindraLacko's answer for an alternative way to make the question reproducible. (Sometimes one needs to take a different approach to do that)Buggy
Yes, definitely a superior solution, haven't heard about the {giscoR} package. Thanks!Interlard
T
6

Drawing a shared border is kind of tricky in context of {sf} > 1.0, as it uses the s2 dependency for spherical operations, and the s2 library introduced a new concept of semi-closed polygons (which was not there in the GEOS years).

See https://r-spatial.github.io/s2/reference/s2_options.html#model for more information.

Anyhow, consider this piece of code, built on {giscoR} package to access EU NUTS regions, and sf::st_intersection() to find the shared border. Note the use of model = "closed" (i.e. all polygons contain their entire boundaries) which may not be immediately obvious, and is necessary for the code to work as intended.

library(dplyr)
library(ggplot2)
library(giscoR)
library(sf)

bavaria <- gisco_get_nuts(country = "DE",
                          nuts_level = "1") %>% 
  filter(NUTS_NAME == "BAYERN")

austria <- gisco_get_nuts(country = "AT",
                          nuts_level = "2")

shared_border <- st_intersection(bavaria,
                                 austria,
                                 model = "closed") # this line is important!

ggplot() +
  geom_sf(data = bavaria, fill = NA, color = "gray40") +
  geom_sf(data = austria, fill = NA, color = "gray40") +
  geom_sf(data = shared_border, fill = NA, color = "red")

shared border / Bayern & Austria

Tyburn answered 14/12, 2021 at 13:46 Comment(3)
Great! That works! I tried the intersection solution but I did not include the crucial model = "closed" option! Thanks!Interlard
I knew it! :) the dust is still setting on the s2 version, and while it has some nice & welcomed consequences it does have its ... surprises :)Tyburn
You can set sf::sf_use_s2(FALSE) to turn off s2 and avoid some of the issues of that transitionThiele

© 2022 - 2024 — McMap. All rights reserved.