I'm creating a map with two layers- a heatmap (geom_tile) with biome data and layering a map of the different regions on top. I've got a list countries in each region and I got R to display a map with just the outer borders of the regions in different colors. BUT- because the borders are shared they only show one color, making some regions kind of hard to see. Is there a way to make both colors visible at the borders?
NOTE: I have my own list of countries and subregions that's not easily listed here so i'm using one innate to the data
Here is the map:
library(rnaturalearthdata)
library(dplyr)
library(ggplot2)
library(sf)
data1<-ne_countries(scale=50)
crs_target<-st_crs ("+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84")
data2<-data1%>%
sf::st_transform(crs=crs_target)
africa<-subset(data2,continent=='Africa')
westA<-africa%>%
group_by(region_wb)%>%
summarise()
ggplot()+
#geom_tile(data=test_cou,aes(x=x,y=y,fill=Biome))+ #My biome data- not relavant
geom_sf(data=westA,fill=NA,aes(colour=region_wb),linewidth=1.1)+
scale_color_manual(values=c('chocolate3','red3','purple3','maroon3','blue3'))+
#scale_fill_manual(values=viridis(12))+
guides(color=guide_legend(position='bottom',direction='horizontal')
)
Here is my current map- you can see how the red region (Middle Africa) is hard to see because of the blue and purple colors next to it. Any ideas? enter image description here
Here's two of a number of potential solutions, both will require some trial and error. First, some points:
summarise()
or summarise(geometry = st_union(geometry))
, internal polygon 'holes' were generated. Not sure why your repex does not show this, but it may be due to different package versions. Either way, I have used the nngeo
package function st_remove_holes()
to correct this.There are other options, such as using st_intersection()
to get the shared borders and then st_cast()
ing them to LINESTRING, but the ne_countries(scale = 50)
data requires a lot of cleaning to get a satisfactory result. So let's keep it simple:
Load packages and generate data:
library(dplyr)
library(nngeo) # Remove internal 'holes', also loads the sf package
library(rnaturalearth)
library(ggplot2)
westA <- ne_countries(scale = 50) %>%
st_transform("+proj=moll +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84") %>%
filter(continent == "Africa") %>%
group_by(subregion) %>%
summarise(geometry = st_union(geometry)) %>%
st_make_valid() %>%
st_remove_holes() %>%
ungroup()
Method 1: Dashed lines
linewidth = 1.1
ggplot() +
geom_sf(data = westA,
aes(colour = subregion),
fill = NA,
linewidth = 1.1) +
geom_sf(data = westA,
aes(colour = subregion),
fill = NA,
linewidth = 1.1,
linetype = "dashed") +
scale_color_manual(name = "Subregions",
values=c("chocolate3", "red3", "purple3", "maroon3", "blue3")) +
guides(color = guide_legend(position = "bottom",
direction = "horizontal",
title.position = "top"))
Method 1 result:
Method 2: Negative buffer as suggested by @VinceGreg
linewidth = 1.1
, external boundaries appear thinner. A lot of trial and error to find a good buffer distance to match desired linewidthwestA1 <- st_buffer(westA, -16000)
ggplot() +
geom_sf(data = westA,
aes(colour = subregion),
fill = NA,
linewidth = 0.65) +
geom_sf(data = westA1,
aes(colour = subregion),
fill = NA,
linewidth = .65) +
scale_color_manual(name = "Subregions",
values=c("chocolate3", "red3", "purple3", "maroon3", "blue3")) +
guides(color = guide_legend(position = "bottom",
direction = "horizontal",
title.position = "top"))
Method 2 result: