Week 13: Visualizing Spatial Data

PPOL 6805 / DSAN 6750: GIS for Spatial Data Science
Fall 2025

Class Sessions
Author
Affiliation

Jeff Jacobs

Published

Wednesday, November 20, 2024

Open slides in new tab →

Final Project Details

  • Project Showcase: 6:30-9pm, Wed, December 3, 2025
    • Come eat falafel and show off your cool visualizations and regression coefficients!
  • Reports: Due 5:59pm, Fri, December 12, 2025
    • If you’re in DSAN 6000 and you’re worried about that final project… See next slide!

Due Date Details

Visualizing Spatial Data

  • My recommendation for final presentations: Tiptoe from mapview \(\leadsto\) Leaflet!
Code
library(tidyverse) |> suppressPackageStartupMessages()
library(sf) |> suppressPackageStartupMessages()
library(leaflet) |> suppressPackageStartupMessages()
library(leaflet.extras2) |> suppressPackageStartupMessages()
library(mapview) |> suppressPackageStartupMessages()
city_df <- tibble::tribble(
  ~city, ~lon, ~lat, ~pop,
  "Chicago", 41.950567516553896, -87.93011127491978, 2746388,
  "Detroit", 42.45123004999075, -83.18402319217698, 631524
)
city_sf <- sf::st_as_sf(
  city_df,
  coords = c("lat", "lon"),
  crs=4326
)
city_buf_sf <- city_sf |> sf::st_buffer(20000)
city_cases_sf <- city_buf_sf |> sf::st_sample(size=rep(10,2)) |> sf::st_as_sf()
city_cases_sf$city <- "Detroit (10 Cases)"
city_cases_sf[1:10, 'city'] <- "Chicago (10 Cases)"
city_cases_sf$sample <- "Flu"
city_pop_sf <- city_buf_sf |>
  sf::st_sample(size=c(16, 4)) |> sf::st_as_sf()
city_pop_sf$city <- "Detroit"
city_pop_sf[1:16, 'city'] <- "Chicago"
city_pop_sf$sample <- "People"
city_combined_sf <- bind_rows(city_cases_sf, city_pop_sf)
# mapview(city_combined_sf, zcol="city", marker="sample")
Flu = makeIcon(
    "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Maki2-danger-24.svg/240px-Maki2-danger-24.svg.png",
    "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Maki2-danger-24.svg/24px-Maki2-danger-24.svg.png",
    20,
    20
)
People = makeIcon(
  "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Maki2-pitch-24.svg/24px-Maki2-pitch-24.svg.png",
  "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Maki2-pitch-24.svg/24px-Maki2-pitch-24.svg.png",
  20,
  20
)

city_combined_sf$r <- ifelse(city_combined_sf$sample == "Flu", 0, 4)
city_flu_sf <- city_combined_sf |> filter(sample == "Flu")
city_ppl_sf <- city_combined_sf |> filter(sample == "People")
leaflet(city_flu_sf) |>
  addProviderTiles("CartoDB.Positron") |>
  addMarkers(data=city_flu_sf, icon = Flu) |>
  addMarkers(data=city_ppl_sf, icon = People)

You’ve Secretly Been Using Leaflet All Along!

Code
library(tidyverse) |> suppressPackageStartupMessages()
library(sf) |> suppressPackageStartupMessages()
library(osmdata) |> suppressPackageStartupMessages()
library(mapview) |> suppressPackageStartupMessages()
nh_query <- opq("New Haven")
highway_result <- nh_query |>
  add_osm_feature(
    key = "highway",
    value = "motorway"
  )
transport_result <- nh_query |>
  add_osm_feature(
    key="public_transport"
  )
nh_road_sfs <- osmdata_sf(highway_result)
nh_transport_sfs <- osmdata_sf(transport_result)
nh_road_sf <- nh_road_sfs$osm_lines
Code
mapview(nh_road_sf)
Code
mapview(nh_road_sf)
Code
leaflet() |>
  leaflet::addProviderTiles("CartoDB.Positron") |>
  leaflet::addPolylines(
    data=nh_road_sf, weight=2
  )

Step 1: Constructing “Overpass Queries”

getbb()

Map features

Application: Urban Segregation

Mapping Inequality

Custom Bounding Box

Code
custom_upper_left <- c(41.362432360113566, -72.9722636671877)
custom_lower_right <- c(41.34295668062255, -72.9385289699316)
bbox_coords <- c(
  custom_upper_left[2],
  custom_upper_left[1],
  custom_lower_right[2],
  custom_lower_right[1]
)
names(bbox_coords) = c("xmin","ymin","xmax","ymax")
custom_sf <- st_as_sf(
  st_as_sfc(
    st_bbox(bbox_coords)
  ),
  crs=4326
)
mapview(custom_sf)
Code
# nh_query <- opq(bbox=bbox_coords) |>
#   add_osm_feature(
#     key = "highway"
#   )
# nh_sfs <- osmdata_sf(nh_query)
# nh_road_sf <- nh_sfs$osm_lines
# mapview(nh_road_sf)

References