Connor Rothschild

← Back to all posts

Creating a Streetmap of Springfield, MO

November 21, 2019

In this post, I expand upon Christian Burkhart’s wonderful ggplot2tor tutorial on streetmap creation using ggplot2. My process differs slightly from his in that I include text using geom_label, rather than PowerPoint, to create the text annotations. (This was much more difficult!)

library(tidyverse)
library(gridExtra)
library(grid)
library(ggplot2)
library(lattice)
library(osmdata)
library(sf)

First, per the tutorial, we load street (and river, etc). data:

streets <- getbb("Springfield Missouri")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("motorway", "primary", 
                            "secondary", "tertiary")) %>%
  osmdata_sf()

small_streets <- getbb("Springfield Missouri")%>%
  opq()%>%
  add_osm_feature(key = "highway", 
                  value = c("residential", "living_street",
                            "unclassified",
                            "service", "footway")) %>%
  osmdata_sf()

river <- getbb("Springfield Missouri")%>%
  opq()%>%
  add_osm_feature(key = "waterway", value = "river") %>%
  osmdata_sf()

Next, we define the plot limits, using the lat-long found in the last step.

left = -93.175
right = -93.395
bottom = 37
top = 37.275

In my plot, I’m going to create a text box to hold the city, state, and lat/long combination.

We can create the parameters for this box through some manipulations of the existing plot limits:

top_rect = (top + bottom)/2.0035
bot_rect = bottom + .01
box_height = (top_rect + bot_rect)/2
mid_box = (left + right)/2

Finally, we can create a black and white plot. This follows the same structure as the ggplot2tor tutorial:

plot_bw <- ggplot() +
  geom_sf(data = streets$osm_lines,
          inherit.aes = FALSE,
          color = "#000000",
          size = .3,
          alpha = .8) +
  geom_sf(data = small_streets$osm_lines,
          inherit.aes = FALSE,
          color = "#000000",
          size = .1,
          alpha = .6) +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "#000000",
          size = .2,
          alpha = .5) +
  coord_sf(xlim = c(left, right),
           ylim = c(bottom, top),
           expand = FALSE) +
  theme_void() +
  theme(
    plot.background = element_rect(fill = "#FFFFFF"),
    panel.background = element_rect(fill = "#FFFFFF"),
    plot.margin=unit(c(0,-0.5,0,0), "mm")
  )

Finally, we can introduce our text elements using geom_text (as well as borders using geom_rect).

map_bw <- plot_bw +
  geom_rect(aes(xmax = right+.005, xmin = left-.005, ymin = bottom+.005, ymax = top-.005),
            alpha = 0,
            color = "black",
            size = 1) +
  geom_rect(aes(xmax = right+.01, xmin = left-.01, ymin = bot_rect, ymax = top_rect), 
            alpha = .75, 
            color = "black", 
            fill = "white",
            size = .6) +
  geom_text(aes(x = mid_box, y = box_height+.002,
                  label = "SPRINGFIELD\n"), 
            color = "black",
            family = "Lato", 
            fontface = "bold",
            size = 9) +
  geom_segment(aes(x = left-.03, y = (top_rect + bottom)/2, xend = right+.03, yend = (top_rect + bottom)/2), color = "black") +
  geom_label(aes(x = mid_box, y = box_height-.005,
                  label = "MISSOURI"), 
            color = "black",
            fill = "white",
            # alpha = .9,
            label.size = 0,
            family = "Lato", 
            # fontface = "thin",
            size = 7) +
  geom_text(aes(x = mid_box, y = box_height-.02,
                label = "37.2090° N / 93.2923° W"), 
          color = "black",
          family = "Lato", 
          size = 4) +
  geom_label(aes(x = left-.035, y = top_rect + .005, label = "Design: Connor Rothschild"), 
          size = 1.5,
          color = "black",
          fill = "white",
          label.size = 0,
          family = "Lato")

map_bw

center

Finally, save the plot:

ggsave(map_bw, filename = "bw_springfield_map.png", width = 3.234, height = 5.016)

Replicate that code with different colors:

plot_gold <- ggplot() +
  geom_sf(data = streets$osm_lines,
          inherit.aes = FALSE,
          color = "steelblue",
          size = .3,
          alpha = .8) +
    geom_sf(data = small_streets$osm_lines,
          inherit.aes = FALSE,
          color = "#ffbe7f",
          size = .1,
          alpha = .6) +
  geom_sf(data = river$osm_lines,
          inherit.aes = FALSE,
          color = "#ffbe7f",
          size = .2,
          alpha = .5) +
  coord_sf(xlim = c(left, right),
           ylim = c(bottom, top),
           expand = FALSE) +
  theme_void() +
  theme(
    plot.background = element_rect(fill = "#282828"),
    panel.background = element_rect(fill = "#282828"),
    plot.margin=unit(c(0,-0.5,0,0), "mm")
  )

map_gold <- plot_gold +
  geom_rect(aes(xmax = right+.005, xmin = left-.005, ymin = bottom+.005, ymax = top-.005),
            alpha = 0,
            color = "white",
            size = 1) +
  geom_rect(aes(xmax = right+.01, xmin = left-.01, ymin = bot_rect, ymax = top_rect), 
            alpha = .5, 
            color = "#ffbe7f", 
            fill = "#282828",
            size = .5) +
  geom_text(aes(x = mid_box, y = box_height+.002,
                  label = "SPRINGFIELD\n"), 
            color = "white",
            family = "Lato", 
            fontface = "bold",
            size = 9) +
  geom_segment(aes(x = left-.03, y = (top_rect + bottom)/2, xend = right+.03, yend = (top_rect + bottom)/2), 
               color = "#ffbe7f") +
  geom_label(aes(x = mid_box, y = box_height-.005,
                  label = "MISSOURI"), 
            color = "white",
            fill = "#282828",
            # alpha = .9,
            label.size = 0,
            family = "Lato", 
            # fontface = "thin",
            size = 7) +
  geom_text(aes(x = mid_box, y = box_height-.02,
                label = "37.2090° N / 93.2923° W"), 
          color = "white",
          family = "Lato", 
          size = 4) +
  geom_label(aes(x = left-.035, y = top_rect + .005, label = "Design: Connor Rothschild"), 
            size = 1.5,
            color = "white",
            fill = "#282828",
            label.size = 0,
            family = "Lato")

map_gold

center

ggsave(map_gold, filename = "gold_springfield_map.png", width = 3.234, height = 5.016)