rggplot2geom-map

Plotting subregions of Great Britain in world map using ggplot2


I am trying to draw a world map where selected countries are filled in different colours. Specifically, I want to separately identify the subregions of particular regions (eg, for the UK: England, Wales and Scotland).

I found this answer to a related question which helpfully shows how to replace regions with subregions and use the geom_map command which matches the entries in map$region.

Ploting subregions in wordmap with ggplot2

However, for say the UK, I am struggling to work out how to separately identify “England” since it is not explicitly a subregion in the world database used by map_data. In addition, while the region replacement works for highlighting Great Britain I can’t get it to do the same for subregions that make up Great Britain (eg. Wales).

Here is my code:

library(ggplot2)
library(tidyverse)
library(maps)
library(mapdata)

# Basic map

ggplot()+geom_map(data=world_map,map=world_map,aes(x=long,y=lat,group=group,map_id=region),fill="white")+coord_fixed(1.3)
# Replace selected UK regions with subregions
world_map$region[which(world_map$subregion == "Great Britain")] <- "Great Britain"
world_map$region[which(world_map$subregion == "Wales")] <- "Wales"

# Collect countries into groups

df2<-data.frame(region=c('Austria', 'Norway', 'New Zealand', 'Portugal', 'Saudi Arabia', 'South Africa', 'Switzerland', 'United Arab Emirates'), value=c(1,1,1,1,1,1,1,1), stringsAsFactors=FALSE)
df3<-data.frame(region=c('Germany', 'Netherlands', 'Spain'), value=c(2,2,2), stringsAsFactors=FALSE)
df5<-data.frame(region=c('Australia', 'Canada', 'Great Britain', 'USA'), value=c(3,3,3,3), stringsAsFactors=FALSE)
df7<-data.frame(region=c('Australia', 'Canada', 'Wales', 'USA'), value=c(3,3,3,3),stringsAsFactors=FALSE)

# Plot world map (with Great Britain)

ggplot()+geom_map(data=world_map,map=world_map,aes(x=long,y=lat,group=group,map_id=region),fill="white")+coord_fixed(1.3)+xlab("")+ylab("")+geom_map(data=df2,map=world_map,aes(fill=value,map_id=region))+geom_map(data=df3,map=world_map,aes(fill=value,map_id=region))+geom_map(data=df5,map=world_map,aes(fill=value,map_id=region))

# Plot world map (Wales rather than Great Britain)

ggplot()+geom_map(data=world_map,map=world_map,aes(x=long,y=lat,group=group,map_id=region),fill="white")+coord_fixed(1.3)+xlab("")+ylab("")+geom_map(data=df2,map=world_map,aes(fill=value,map_id=region))+geom_map(data=df3,map=world_map,aes(fill=value,map_id=region))+geom_map(data=df7,map=world_map,aes(fill=value,map_id=region))

Solution

  • You need better quality map data. I recommend the rnaturalearth package. You also should switch over to geom_sf() instead of geom_map().

    In the example below, I'm downloading a world map and a map of just the UK and plot the two on top of each other. You could also subset the data frames to extract specific countries, regions, etc. A couple more explanatory comments follow below.

    library(ggplot2)   # use development version for coord limits in unprojected coordinates
    library(sf)        # for manipulation of simple features objects
    #> Linking to GEOS 3.8.1, GDAL 3.1.1, PROJ 6.3.1
    library(rnaturalearth) # for map data
    
    world_sf <- ne_countries(returnclass = "sf", scale = "large")
    uk_sf <- ne_states(country = "united kingdom", returnclass = "sf")
    
    ggplot() + 
      geom_sf(data = world_sf, size = 0.2) +
      geom_sf(data = uk_sf, aes(fill = geonunit), color = NA) +
      theme_minimal() +
      coord_sf(crs = 27700, xlim = c(-20, 20), ylim = c(45, 60)) +
      scale_fill_brewer(type = "qual")
    

    Created on 2020-10-17 by the reprex package (v0.3.0)

    Explanatory comments: