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))
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:
To use ne_states()
, you also need the package rnaturalearthhires. You can install it via: install.packages("rnaturalearthhires", repos = "http://packages.ropensci.org", type = "source")
In coord_sf()
call, the argument crs = 27700
sets the projection. I picked one that is usually used for the UK, but it may not be the right one for you if you want to show a larger portion of the world: https://epsg.io/27700
In coord_sf()
, I'm setting the limits in longitude and latitude. This works only with the development version of ggplot2. If you're running the latest version from CRAN, you need to specify limits in projected coordinates. To get a sense of what those numbers might be, start with the projected bounds from the epsg.io website and modify until you have the right region shown. To install the latest development version of ggplot2, run: remotes::install_github("tidyverse/ggplot2")