1

I'm using ggplot to create a map using the Robinson projection. Ultimately, I'll be plotting individual countries, but I need to provide continent boundaries as a background layer (since some countries will not be plotted). I can successfully plot the two layers of my data (continents + countries) with one of mapproj's built-in projections:

Working map, wrong projection

However, when I convert the shapefile's CRS to Robinson, I get strange artifacts in the continents. Here's a minimal working example:

library(dplyr)
library(ggplot2)
library(rgdal)

# Get Natural Earth shapefiles
download.file(url="http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/ne_110m_admin_0_countries.zip", "ne_110m_admin_0_countries.zip", "auto")
unzip("ne_110m_admin_0_countries.zip")
file.remove("ne_110m_admin_0_countries.zip")

# Load and fortify regular data
world <- readOGR(".", "ne_110m_admin_0_countries")
continents.regular <- fortify(world, region="continent")

# Convert to Robinson and fortify
world.robinson <- spTransform(world, CRS("+proj=robin"))
continents.robinson <- fortify(world.robinson, region="continent")

# Continents to plot
all.continents <- data_frame(id = unique(as.character(continents.regular$id)))

# This works
map.regular <- ggplot(data=all.continents, aes(map_id=id)) +
  geom_map(map=continents.regular, colour="grey50", fill="white", size=0.4) + 
  expand_limits(x=continents.regular$long, y=continents.regular$lat) + 
  coord_equal()
map.regular

Working

# This has weird artifacts
map.robinson <- ggplot(data=all.continents, aes(map_id=id)) +
  geom_map(map=continents.robinson, colour="grey50", fill="white", size=0.4) + 
  expand_limits(x=continents.robinson$long, y=continents.robinson$lat) + 
  coord_equal()
map.robinson

Phantom borders

What's the best way to convert these shapefiles to a Robinson projection without getting all the strange artifacts?

UPDATE: Following iant♦'s suggestion to use the Natural Earth land shapefiles, everything works nicely now. I think I was trying to make the political data do too much work.

# Get Natural Earth *land* shapefiles
download.file(url="http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/physical/ne_110m_land.zip", "ne_110m_land.zip", "auto")
unzip("ne_110m_land.zip")
file.remove("ne_110m_land.zip")

# Load and fortify regular data
world.land <- readOGR(".", "ne_110m_land")
land.robinson <- spTransform(world.land, CRS("+proj=robin"))
continents.simple <- fortify(land.robinson)

# Continents to plot
all.continents <- data_frame(id = unique(as.character(continents.simple$id)))

# Everything works now
map.fixed <- ggplot(data=all.continents, aes(map_id=id)) +
  geom_map(map=continents.simple, colour="grey50", fill="white", size=0.4) + 
  expand_limits(x=continents.simple$long, y=continents.simple$lat) + 
  coord_equal()
map.fixed

Fixed

  • aren't they lakes and rivers becoming visible? – Ian Turton Aug 5 '15 at 15:25
  • That's what I initially thought, but there's no Nile or Amazon, plus they don't exist in the default Mercator plot – Andrew Aug 5 '15 at 15:36
2

Looking at the NaturalEarth data page for countries offers you the choice of boundaries with and without lakes which leads me to think you have the one with lakes (but it's hard to tell). For what you are doing you may be better off with the Coastline or Land from the physical set.

  • That fixed it. I think the countries shapefile was trying to do too much—by extracting continents, I was really essentially merging all the countries. The weird artifacts might just be unaccounted for space between countries, like where border definitions are just a tiny bit off. The land file is far simpler and works great. Thanks! – Andrew Aug 5 '15 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.