1

I'm working with a data set corresponding to the extract below:

# Data sourcing -----------------------------------------------------------

# Download an read US state shapefiles
tmp_shps <- tempfile(); tmp_dir <- tempdir()
download.file("http://www2.census.gov/geo/tiger/GENZ2014/shp/cb_2014_us_state_20m.zip",
              tmp_shps)
unzip(tmp_shps, exdir = tmp_dir)

# Libs
require(rgdal); require(ggplot2)

# Read
us_shps <- readOGR(dsn = tmp_dir, layer = "cb_2014_us_state_20m")
# Prepare data set for ggplot2
us_shps_frt <- fortify(us_shps, region = "NAME")

From within that data set I subset a custom selection of shapefiles, like in the example below:

map_shps <- ggplot(data = us_shps_frt[grep("South", us_shps_frt$id),]) +
  geom_polygon(aes(x = long, y = lat, group = group,
                                fill = id)) +
  coord_equal() +
  ggtitle("Odd Map") +
  theme_map()

Odd Map

Given the odd selection of shapefiles above I would like to fit a background map that would neatly overlay with the maximum extent of the polygons. Initially I tried to achieve this in a following manner:

# Get box for the map
bbox <- make_bbox(lon = long, lat = lat,
                  data = us_shps_frt[grep("South", us_shps_frt$id),],
                  f = 0.5)
map_backgr  <- get_map(bbox, maptype = "roadmap", zoom = 5,
                       source = "google", scale = 2, messaging = TRUE)
map_backgr <- ggmap(map_backgr, extent = "normal", maprange = FALSE)

and then generating the map:

map_backgr +
  geom_polygon(data = us_shps_frt[grep("South", us_shps_frt$id),],
               aes(x = long, y = lat, group = group,
                   fill = id)) +
  coord_equal() +
  ggtitle("Odd Map with Background") +
  theme_map()

The produced graphic does not fit the polygons well:

Messy map

I'm interested in adjusting the background map so it matches the polygons exactly. In particular I would like to crop/shorten the background by the red lines marked in the picture below:

What to delete

Konrad
  • 17,740
  • 16
  • 106
  • 167
  • 1
    Using `coord_map` instead of `coord_equal` looks better already, though still a bit off.. – erc Oct 28 '15 at 13:09
  • @beetroot Thanks very much for this suggestion. The example could be more elaborate. In practice the difficulty pertains to fitting zoom factor correctly so it matches a custom set of shapefiles. In my real data set some of the shapes are stretched beyond the background map. Selecting lower zoom factor fixes that but makes the map less presentable. I'm looking for solution where I would be able to simply get *bigger* background map (i.e. two squares next to each other) that would match with the shapes at hand. – Konrad Oct 28 '15 at 13:41
  • This question seems to have the answer to both why the google map does this, but also how to fix it: https://stackoverflow.com/questions/47749078/how-to-put-a-geom-sf-produced-map-on-top-of-a-ggmap-produced-raster – saritonin Sep 13 '22 at 22:12

1 Answers1

2

Idea 1: Go with Stamen, they support oddly-shaped maps:

Stamen

dat <- us_shps_frt[grep("South", us_shps_frt$id),]

ggmap(get_stamenmap(c(min(dat$long), min(dat$lat), 
                      max(dat$long), max(dat$lat)), 
                    zoom = 6)) +
geom_polygon(data = dat,
             aes(x = long, y = lat, group = group,
                 fill = id)) +
ggtitle("Odd Map with Background") 

Idea 2: Cut your Google Maps map:

Google

dat <- us_shps_frt[grep("South", us_shps_frt$id),]

ggmap(get_map(c(min(dat$long), min(dat$lat), max(dat$long), max(dat$lat)))) +
geom_polygon(data = dat,
             aes(x = long, y = lat, group = group,
                 fill = id)) +
ggtitle("Odd Map with Background") +
coord_map(xlim = c(min(dat$long), max(dat$long)),
          ylim = c(min(dat$lat), max(dat$lat)))

But this one is still a bit off and I assume you need to play with the projection = "..." and parameters = "..." of coord_map().

Roman
  • 4,744
  • 2
  • 16
  • 58