library(ggplot2)
library(ggalt)
library(maptools)
library(dplyr)

Show which version of ggplot (et al) we’re using

devtools::session_info()
## Session info --------------------------------------------------------------
##  setting  value                                 
##  version  R version 3.3.2 RC (2016-10-26 r71594)
##  system   x86_64, darwin13.4.0                  
##  ui       X11                                   
##  language (EN)                                  
##  collate  en_US.UTF-8                           
##  tz       America/New_York                      
##  date     2016-12-30
## Packages ------------------------------------------------------------------
##  package      * version    date       source                         
##  ash            1.0-15     2015-09-01 CRAN (R 3.3.0)                 
##  assertthat     0.1        2013-12-06 CRAN (R 3.3.0)                 
##  colorspace     1.3-2      2016-12-14 cran (@1.3-2)                  
##  DBI            0.5-1      2016-09-10 CRAN (R 3.3.0)                 
##  devtools       1.12.0     2016-06-24 CRAN (R 3.3.0)                 
##  digest         0.6.10     2016-08-02 CRAN (R 3.3.0)                 
##  dplyr        * 0.5.0.9000 2016-11-08 local                          
##  evaluate       0.10       2016-10-11 cran (@0.10)                   
##  extrafont      0.17       2014-12-08 CRAN (R 3.3.0)                 
##  extrafontdb    1.0        2012-06-11 CRAN (R 3.3.0)                 
##  foreign        0.8-67     2016-09-13 CRAN (R 3.3.2)                 
##  ggalt        * 0.3.1.9000 2016-12-05 local (hrbrmstr/ggalt@d014b9e) 
##  ggplot2      * 2.2.0.9000 2016-12-05 Github (hadley/ggplot2@f6f9f9d)
##  gtable         0.2.0      2016-02-26 CRAN (R 3.3.0)                 
##  htmltools      0.3.5      2016-03-21 CRAN (R 3.3.0)                 
##  KernSmooth     2.23-15    2015-06-29 CRAN (R 3.3.2)                 
##  knitr          1.15.6     2016-12-15 Github (yihui/knitr@849f2d0)   
##  lattice        0.20-34    2016-09-06 CRAN (R 3.3.2)                 
##  lazyeval       0.2.0      2016-06-12 CRAN (R 3.3.0)                 
##  magrittr       1.5        2014-11-22 CRAN (R 3.3.0)                 
##  maps           3.1.1      2016-07-27 CRAN (R 3.3.0)                 
##  maptools     * 0.8-39     2016-01-30 CRAN (R 3.3.0)                 
##  MASS           7.3-45     2016-04-21 CRAN (R 3.3.2)                 
##  memoise        1.0.0      2016-01-29 CRAN (R 3.3.0)                 
##  munsell        0.4.3      2016-02-13 CRAN (R 3.3.0)                 
##  plyr           1.8.4      2016-06-08 CRAN (R 3.3.0)                 
##  proj4          1.0-8      2012-08-05 CRAN (R 3.3.0)                 
##  R6             2.2.0      2016-10-05 cran (@2.2.0)                  
##  RColorBrewer   1.1-2      2014-12-07 CRAN (R 3.3.0)                 
##  Rcpp           0.12.8     2016-11-17 cran (@0.12.8)                 
##  rmarkdown      1.2        2016-11-21 CRAN (R 3.3.2)                 
##  rprojroot      1.0-2      2016-03-28 CRAN (R 3.3.0)                 
##  Rttf2pt1       1.3.4      2016-05-19 CRAN (R 3.3.0)                 
##  scales         0.4.1.9000 2016-12-05 Github (hadley/scales@89c2a2f) 
##  sp           * 1.2-3      2016-04-14 CRAN (R 3.3.0)                 
##  stringi        1.1.2      2016-10-01 cran (@1.1.2)                  
##  stringr        1.1.0      2016-08-19 cran (@1.1.0)                  
##  tibble         1.2        2016-08-26 cran (@1.2)                    
##  withr          1.0.2      2016-06-20 CRAN (R 3.3.0)                 
##  yaml           2.1.14     2016-11-12 cran (@2.1.14)

Get some built-in map data

world <- map_data("world")

Unlike every other geom, geom_map() stands out with different behaviour O_o

ggplot() +
  geom_map(data=world, map=world, aes(map_id=region))

What the…

It’s due to the fact that it no longer accepts x & y aesthetic mappings. But…it really does still take them. It just coughs up some blood while doing so.

ggplot() +
  geom_map(data=world, map=world, aes(x=long, y=lat, map_id=region))
## Warning: Ignoring unknown aesthetics: x, y

The new man page for geom_map() says to use expand_limits()

ggplot() +
  geom_map(data=world, map=world, aes(map_id=region)) +
  expand_limits(x=world$long, y=world$lat)

All that does is build a data frame for you and then call geom_blank(), so we could just do this instead:

ggplot() +
  geom_blank(data=world, aes(x=long, y=lat)) +
  geom_map(data=world, map=world, aes(map_id=region))

Fundamentally, it’s just a matter of getting x & y into the resultant ggplot2 objects so it can pass real values to the grid graphics calls.

The example below was a bit more elegant but that failed to work in a knitr context, so it’s very “ugh” now.

ggplot() + geom_map(data=world, map=world, aes(map_id=region)) -> g1
ggplot() + geom_map(data=world, map=world, aes(x=long, y=lat, map_id=region)) -> g2
ggplot() + geom_map(data=world, map=world, aes(map_id=region)) + expand_limits(x=world$long, y=world$lat) -> g3
ggplot() + geom_blank(data=world, aes(x=long, y=lat)) + geom_map(data=world, map=world, aes(map_id=region)) -> g4

gb1 <- ggplot_build(g1)
gb2 <- ggplot_build(g2)
gb3 <- ggplot_build(g3)
gb4 <- ggplot_build(g4)

We can look at the data built for each of those

No x or y aes in geom_map() and no expand_limits() or geom_blank()

glimpse(gb1$data)
## List of 1
##  $ :'data.frame':    99338 obs. of  8 variables:
##   ..$ map_id  : chr [1:99338] "Aruba" "Aruba" "Aruba" "Aruba" ...
##   ..$ PANEL   : int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group   : atomic [1:99338] 12 12 12 12 12 12 12 12 12 12 ...
##   .. ..- attr(*, "n")= int 252
##   ..$ colour  : chr [1:99338] "NA" "NA" "NA" "NA" ...
##   ..$ fill    : chr [1:99338] "grey20" "grey20" "grey20" "grey20" ...
##   ..$ size    : num [1:99338] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
##   ..$ linetype: num [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ alpha   : logi [1:99338] NA NA NA NA NA NA ...

The polygons have no x or y variables in ^^ so they can’t be drawn :-( Has x and y aes in geom_map() but no expand_limits() or geom_blank()

glimpse(gb2$data)
## List of 1
##  $ :'data.frame':    99338 obs. of  10 variables:
##   ..$ x       : num [1:99338] -69.9 -69.9 -69.9 -70 -70.1 ...
##   ..$ y       : num [1:99338] 12.5 12.4 12.4 12.5 12.5 ...
##   ..$ map_id  : chr [1:99338] "Aruba" "Aruba" "Aruba" "Aruba" ...
##   ..$ PANEL   : int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group   : atomic [1:99338] 12 12 12 12 12 12 12 12 12 12 ...
##   .. ..- attr(*, "n")= int 252
##   ..$ colour  : chr [1:99338] "NA" "NA" "NA" "NA" ...
##   ..$ fill    : chr [1:99338] "grey20" "grey20" "grey20" "grey20" ...
##   ..$ size    : num [1:99338] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
##   ..$ linetype: num [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ alpha   : logi [1:99338] NA NA NA NA NA NA ...

Old school ggplot2 behaviour in ^^ (one data.frame with everyting including x & y). No x or y aes in geom_map() but has expand_limits() [which is really geom_blank()]

glimpse(gb3$data)
## List of 2
##  $ :'data.frame':    99338 obs. of  8 variables:
##   ..$ map_id  : chr [1:99338] "Aruba" "Aruba" "Aruba" "Aruba" ...
##   ..$ PANEL   : int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group   : atomic [1:99338] 12 12 12 12 12 12 12 12 12 12 ...
##   .. ..- attr(*, "n")= int 252
##   ..$ colour  : chr [1:99338] "NA" "NA" "NA" "NA" ...
##   ..$ fill    : chr [1:99338] "grey20" "grey20" "grey20" "grey20" ...
##   ..$ size    : num [1:99338] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
##   ..$ linetype: num [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ alpha   : logi [1:99338] NA NA NA NA NA NA ...
##  $ :'data.frame':    99338 obs. of  4 variables:
##   ..$ x    : num [1:99338] -69.9 -69.9 -69.9 -70 -70.1 ...
##   ..$ y    : num [1:99338] 12.5 12.4 12.4 12.5 12.5 ...
##   ..$ PANEL: int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group: int [1:99338] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...

That ^^ gives us x and y, but in a second data.frame with PANEL (thankfully the same) and a different group. No x or y aes in geom_map() but has geom_blank() [which expand_limits() just wraps]

glimpse(gb4$data)
## List of 2
##  $ :'data.frame':    99338 obs. of  4 variables:
##   ..$ x    : num [1:99338] -69.9 -69.9 -69.9 -70 -70.1 ...
##   ..$ y    : num [1:99338] 12.5 12.4 12.4 12.5 12.5 ...
##   ..$ PANEL: int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group: int [1:99338] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ :'data.frame':    99338 obs. of  8 variables:
##   ..$ map_id  : chr [1:99338] "Aruba" "Aruba" "Aruba" "Aruba" ...
##   ..$ PANEL   : int [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ group   : atomic [1:99338] 12 12 12 12 12 12 12 12 12 12 ...
##   .. ..- attr(*, "n")= int 252
##   ..$ colour  : chr [1:99338] "NA" "NA" "NA" "NA" ...
##   ..$ fill    : chr [1:99338] "grey20" "grey20" "grey20" "grey20" ...
##   ..$ size    : num [1:99338] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
##   ..$ linetype: num [1:99338] 1 1 1 1 1 1 1 1 1 1 ...
##   ..$ alpha   : logi [1:99338] NA NA NA NA NA NA ...

That ^^ also gives us x and y, but in a second data.frame with PANEL (thankfully the same) and a different group.

I don’t do enough mapping in the $DAYJOB to know if the different groups are going to cause issues for folks, nor have I looked in the ggplot2 github issues log. ### Thankfully, projections still work in the new paradigm

us <- map_data("usa")

ggplot() +
  geom_blank(data=us, aes(x=long, y=lat)) +
  geom_map(data=us, map=us, aes(map_id=region)) +
  coord_map("polyconic")