Unable to get my world map working

ggplot2
geom_map

#1

Hi.

I’m having some trouble creating a world map with countries filled according to some variable with geom_map.

I want to create some world maps with country filled to reflect analysis outcomes. Country names are formatted differently in different places, so my analysis outcomes have a 3-letter ISO code associated with them. This code is also available in the high definition world map data from the rworldxtra package.

So I can set up my map data.frame thus:

library(rworldmap)
library(rworldxtra)
library(ggplot2)

# high resolution so that I have all the islands I need and 3-letter ISO codes
world_map<-getMap(resolution="high")
robinson_world_map <- spTransform( world_map,
  CRS("+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs" ) )
# Convert to DF with 3-letter abbreviation as region id
#  -- this will link to my real data
robinson_world_map_df <- fortify(robinson_world_map,region="ISO_A3")

If I just plot this with ggplot and geom_map, with no fill, it works fine (except for Warning: Ignoring unknown aesthetics: x, y):

ggworld <- ggplot() +
  geom_map( data=robinson_world_map_df,
            map=robinson_world_map_df,
            mapping=aes(map_id=id,x=long,y=lat),
            fill=NA,
            size=0.15,
            colour="black" ) +
  coord_fixed()

I would then use theme to make it a plain bakground with no axes, grid or borders.

For this example I use a dummy data data.frame:

data_df <- data.frame(id=unique(robinson_world_map_df$id))
data_df$value=rnorm(nrow(data_df))

I then try to plot my map with a fill based on data_df$value, ie with different data and map options to geom_map:

ggworld2 <- ggplot() +
   geom_map( data=data_df,
             map=robinson_world_map_df,
             mapping=aes( map_id=id,x=long,y=lat,fill=value),
             size=0.15,
             colour="black" ) +
   coord_fixed()

This gives the same warning about unknown aesthetics, but when I print ggworld2 I get an error message Error in eval(expr, envir, enclos) : object ‘long’ not found.

I’m currently using these versions of the software:

> R.version.string
[1] "R version 3.3.2 (2016-10-31)"
> installed.packages()[c("ggplot2","rworldmap","rworldxtra"),"Version"]
   ggplot2  rworldmap rworldxtra
   "2.2.1"    "1.3-6"     "1.01"

Any suggestions to fix my problem appreciated.

Any other suggestions/observations that would improve this (eg coord_proj on the ggplot call rather than spTransform before fortify) or might just be interesting are also welcome. Provided I can get them to work.

Ron.


#2

You don’t need to include the x and y aesthetics, as geom_map can automatically pick them up from the map. If you look at the second example in help(geom_map):

crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
crimesm <- reshape2::melt(crimes, id = 1)
if (require(maps)) {
  states_map <- map_data("state")
  ggplot(crimes, aes(map_id = state)) +
    geom_map(aes(fill = Murder), map = states_map) +
    expand_limits(x = states_map$long, y = states_map$lat)

You can see that the x=long, y=lat has been omitted to no adverse effect. In fact, including them is what causes the error. I resolved it by following the above example and modifying your code to:

ggworld2 <- ggplot() +
  geom_map( data=data_df,
            map=robinson_world_map_df,
            mapping=aes( map_id=id,fill=value),
            size=0.15,
            colour="black" ) +
  expand_limits(x = robinson_world_map_df$long, y = robinson_world_map_df$lat)+
  coord_fixed()

This seems to give what you were going for:
image

The key lies in the expand_limits call because, without x and y defined, the default limits do not show the whole map. You could, of course, also set xlim and ylim to the required extent.

I’m using the same package versions as you.


#3

Ah! Thanks. I had tried dropping the x and y (which resulted in a blank plot), but hadn’t seen what expand_limits was needed for.

That’s great.