Finding country centres to annotate map plot

997 views
Skip to first unread message

Kristoffer Magnusson

unread,
May 3, 2012, 10:07:07 AM5/3/12
to ggplot2
Hello,

I'm plotting a world map in ggplot like this:

reg <- map_data("world")

ggplot(reg, aes(long, lat, group=group)) + geom_polygon(show_guide=F)

And my question is, does anyone know where I can find centered long &
lat for the world countries? I wan't to use them both to add country
names and to create a bubble plot.

Best regards,
Kristoffer Magnusson

Allan Just

unread,
May 3, 2012, 1:12:34 PM5/3/12
to ggp...@googlegroups.com
Hi Kristoffer,
  you can pull out the centroid of the largest polygon used in representing each country for a solution that would work in other applications. The key here is to convert to SpatialPolygons and then extract the stored coordinates which are calculated as part of the object definition. Example code below.
 - Allan
R 2.15.0 x86_64-pc-mingw32/x64 (64-bit); ggplot2_0.9.0  maptools_0.8-14   sp_0.9-98

library(ggplot2)
library(maptools)


reg <- map_data("world")
 
P1 <- ggplot(reg, aes(long, lat)) +
    geom_polygon(aes(group = group), show_guide=F)

worldmap <- map('world', fill=TRUE, col="transparent", plot=FALSE)
world_sp <- map2SpatialPolygons(worldmap, IDs=IDs,
    proj4string=CRS("+proj=longlat +datum=wgs84"))
# coordinates pulls out the centroid of
#the largest (area) polygon for a country
world.label <- data.frame(
    country = names(world_sp),
    coordinates(world_sp))
head(world.label)
# plot with labels
P1 + geom_text(aes(X1, X2, label = country), data = world.label)

Allan Just

unread,
May 3, 2012, 1:17:23 PM5/3/12
to ggp...@googlegroups.com
On review, I had dropped a line of code to pull out IDs. Try this:


library(ggplot2)
library(maptools)
reg <- map_data("world")
 
P1 <- ggplot(reg, aes(long, lat)) +
    geom_polygon(aes(group = group), show_guide=F)

worldmap <- map('world', fill=TRUE, col="transparent", plot=FALSE)
IDs <- sapply(strsplit(worldmap$names, ":"), function(x) x[1])

world_sp <- map2SpatialPolygons(worldmap, IDs=IDs,
    proj4string=CRS("+proj=longlat +datum=wgs84"))
# coordinates pulls out the centroid of
#the largest (area) polygon for a country
world.label <- data.frame(
    country = names(world_sp),
    coordinates(world_sp))
head(world.label)
P1 + geom_text(aes(X1, X2, label = country), data = world.label)


Allan Just

unread,
May 3, 2012, 3:29:01 PM5/3/12
to ggp...@googlegroups.com
It was noted (offline) that the world object pointed to from the package maps is based on 1980s data and has outdated administrative names like USSR.
It is a bit more work but a quick google search suggests you can download updated data from here:
http://www.gadm.org/  or here: http://www.naturalearthdata.com/
After downloading and extracting the 1:110M cultural vectors shapefile from Natural Earth (free for use), you can convert the ESRI Shapefile to a SpatialPolygonsDataFrame and pull centroids and labels into a dataframe as below. For tips on bringing the Natural Earth polygons themselves into ggplot see:
https://github.com/hadley/ggplot2/wiki/plotting-polygon-shapefiles
-Allan

library(rgdal)
##assuming shapefile is in your working directory
## 4 files "ne_110m_admin_0_countries" with
## .dbf, .prj, .shp, and .shx extensions
#setwd("your path to shapefile here")
natearth110m <- readOGR(dsn = ".",
    layer =  "ne_110m_admin_0_countries")
natearth.label <- data.frame(
    country = natearth110m$NAME,
    coordinates(natearth110m))
head(natearth.label)

# use base graphics to check out labels
plot(natearth110m)
with(natearth.label, text(X1, X2, country))
# For a guide on using polygon shapefiles in ggplot2 see:
# https://github.com/hadley/ggplot2/wiki/plotting-polygon-shapefiles

Kristoffer Magnusson

unread,
May 4, 2012, 5:34:23 AM5/4/12
to Allan Just, ggp...@googlegroups.com
Thanks for your help again! I didn't use Rgdal though (I'm on Mac OS, should've mentioned that), but it worked just as well with readShapePoly from maptools and fortify. Like this:

# shapefile from Natural Earth
x <- readShapePoly("ne_110m_admin_0_countries", proj4string=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
map.df = fortify(x, region = "NAME")

Then I could both use it to get centroids (like you described) and to plot the world map with ggplot2. 

/ Kristoffer

--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Reply all
Reply to author
Forward
0 new messages