library(tidyverse)
library(sf)
library(colorspace)
library(scales)
library(crsuggest)
# set default theme
theme_set(theme_minimal())
# create reusable labels for each plot
map_labels <- labs(
title = "Median household income in New York in 2024",
subtitle = "By census tract",
color = NULL,
fill = NULL,
caption = "Source: American Community Survey"
)AE 17: Visualizing household income in New York
Suggested answers
Packages
Load New York 2024 median household income
We will use two data files for this analysis. The first contains median household incomes for each census tract in New York from 2024. The second contains the boundaries of each county in New York.
# load data
ny_inc <- st_read(dsn = "data/ny-inc.geojson")Reading layer `ny-inc.geojson' from data source
`/Users/bcs88/Projects/info-3312/course-site/ae/data/ny-inc.geojson'
using driver `GeoJSON'
Simple feature collection with 5397 features and 4 fields (with 17 geometries empty)
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -79.76215 ymin: 40.4961 xmax: -71.85648 ymax: 45.01585
Geodetic CRS: NAD83
ny_counties <- st_read(dsn = "data/ny-counties.geojson")Reading layer `ny-counties.geojson' from data source
`/Users/bcs88/Projects/info-3312/course-site/ae/data/ny-counties.geojson'
using driver `GeoJSON'
Simple feature collection with 62 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -79.76215 ymin: 40.4961 xmax: -71.85648 ymax: 45.01585
Geodetic CRS: NAD83
ny_incSimple feature collection with 5397 features and 4 fields (with 17 geometries empty)
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -79.76215 ymin: 40.4961 xmax: -71.85648 ymax: 45.01585
Geodetic CRS: NAD83
First 10 features:
GEOID NAME medincomeE
1 36015010800 Census Tract 108; Chemung County; New York 55881
2 36015000100 Census Tract 1; Chemung County; New York 43271
3 36051030100 Census Tract 301; Livingston County; New York 78649
4 36055013401 Census Tract 134.01; Monroe County; New York 59034
5 36055002300 Census Tract 23; Monroe County; New York 22010
6 36055014301 Census Tract 143.01; Monroe County; New York 67581
7 36055008500 Census Tract 85; Monroe County; New York 44507
8 36055013604 Census Tract 136.04; Monroe County; New York 61912
9 36055001900 Census Tract 19; Monroe County; New York 43411
10 36055006000 Census Tract 60; Monroe County; New York 53478
medincomeM geometry
1 11963 MULTIPOLYGON (((-76.83044 4...
2 4429 MULTIPOLYGON (((-76.82196 4...
3 13483 MULTIPOLYGON (((-77.93474 4...
4 13000 MULTIPOLYGON (((-77.657 43....
5 12220 MULTIPOLYGON (((-77.64784 4...
6 19903 MULTIPOLYGON (((-77.7016 43...
7 11561 MULTIPOLYGON (((-77.62735 4...
8 32602 MULTIPOLYGON (((-77.69645 4...
9 15481 MULTIPOLYGON (((-77.64533 4...
10 15700 MULTIPOLYGON (((-77.56453 4...
ny_countiesSimple feature collection with 62 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -79.76215 ymin: 40.4961 xmax: -71.85648 ymax: 45.01585
Geodetic CRS: NAD83
First 10 features:
GEOID NAME medincomeE medincomeM
1 36005 Bronx County, New York 48676 895
2 36119 Westchester County, New York 118976 2567
3 36053 Madison County, New York 75499 3230
4 36029 Erie County, New York 72839 1077
5 36091 Saratoga County, New York 100787 3028
6 36031 Essex County, New York 71661 4292
7 36113 Warren County, New York 78442 3623
8 36017 Chenango County, New York 62948 2655
9 36051 Livingston County, New York 74001 2171
10 36063 Niagara County, New York 69633 2124
geometry
1 MULTIPOLYGON (((-73.77242 4...
2 MULTIPOLYGON (((-73.77237 4...
3 MULTIPOLYGON (((-75.99243 4...
4 MULTIPOLYGON (((-79.13689 4...
5 MULTIPOLYGON (((-74.1601 43...
6 MULTIPOLYGON (((-74.33683 4...
7 MULTIPOLYGON (((-74.21462 4...
8 MULTIPOLYGON (((-75.88983 4...
9 MULTIPOLYGON (((-78.06078 4...
10 MULTIPOLYGON (((-79.07537 4...
Part 1
Draw a continuous choropleth of median household income
Your turn: Create a choropleth map of median household income in New York. Use a continuous color gradient to identify each tract’s median household income.
Use the stored map_labels to set the title, subtitle, and caption for this and the remaining plots.
ggplot(data = ny_inc) +
# use fill and color to avoid gray boundary lines
geom_sf(aes(fill = medincomeE, color = medincomeE)) +
# increase interpretability of graph
scale_color_continuous(labels = label_currency()) +
scale_fill_continuous(labels = label_currency()) +
map_labelsYour turn: Now revise the map to use an optimized color gradient for improved readability.
ggplot(data = ny_inc) +
# use fill and color to avoid gray boundary lines
geom_sf(mapping = aes(fill = medincomeE, color = medincomeE)) +
# increase interpretability of graph
scale_fill_continuous_sequential(
palette = "viridis",
rev = FALSE,
aesthetics = c("fill", "color"),
labels = label_currency(),
name = NULL
) +
map_labelsOverlay county borders
Your turn: To provide better context, overlay the NY county borders on the choropleth map.
ggplot(data = ny_inc) +
# use fill and color to avoid gray boundary lines
geom_sf(mapping = aes(fill = medincomeE, color = medincomeE)) +
# add county borders
geom_sf(data = ny_counties, color = "white", fill = NA) +
# increase interpretability of graph
scale_fill_continuous_sequential(
palette = "viridis",
rev = FALSE,
aesthetics = c("fill", "color"),
labels = label_currency(),
name = NULL
) +
map_labelsPart 2
Your turn: Continuous color palettes can be hard to distinguish visibly. To improve readability, convert the continuous color palette into a discrete one with 6 levels. Additionally, select an appropriate projection method using {crsuggest}.
suggest_crs(ny_inc)# A tibble: 10 × 6
crs_code crs_name crs_type crs_gcs crs_units crs_proj4
<chr> <chr> <chr> <dbl> <chr> <chr>
1 6563 NAD83(2011) / Pennsylvania Nor… project… 6318 us-ft +proj=lc…
2 6562 NAD83(2011) / Pennsylvania Nor… project… 6318 m +proj=lc…
3 3650 NAD83(NSRS2007) / Pennsylvania… project… 4759 us-ft +proj=lc…
4 3649 NAD83(NSRS2007) / Pennsylvania… project… 4759 m +proj=lc…
5 3363 NAD83(HARN) / Pennsylvania Nor… project… 4152 us-ft +proj=lc…
6 3362 NAD83(HARN) / Pennsylvania Nor… project… 4152 m +proj=lc…
7 32128 NAD83 / Pennsylvania North project… 4269 m +proj=lc…
8 32028 NAD27 / Pennsylvania North project… 4267 us-ft +proj=lc…
9 2271 NAD83 / Pennsylvania North (ft… project… 4269 us-ft +proj=lc…
10 6535 NAD83(2011) / New York Central… project… 6318 us-ft +proj=tm…
# binned_scale() - default breaks
ggplot(data = ny_inc) +
geom_sf(mapping = aes(fill = medincomeE, color = medincomeE)) +
geom_sf(data = ny_counties, color = "white", fill = NA) +
scale_fill_binned_sequential(
palette = "viridis",
rev = FALSE,
aesthetics = c("fill", "color"),
labels = label_currency()
) +
# increase interpretability of graph
map_labels +
# NY Central
coord_sf(crs = 6535)sessioninfo::session_info()─ Session info ───────────────────────────────────────────────────────────────
setting value
version R version 4.5.2 (2025-10-31)
os macOS Tahoe 26.4
system aarch64, darwin20
ui X11
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz America/New_York
date 2026-04-02
pandoc 3.4 @ /usr/local/bin/ (via rmarkdown)
quarto 1.9.36 @ /usr/local/bin/quarto
─ Packages ───────────────────────────────────────────────────────────────────
! package * version date (UTC) lib source
P base64enc 0.1-3 2015-07-28 [?] RSPM (R 4.5.0)
P class 7.3-23 2025-01-01 [?] CRAN (R 4.5.2)
P classInt 0.4-11 2025-01-08 [?] RSPM (R 4.5.0)
P cli 3.6.5 2025-04-23 [?] RSPM (R 4.5.0)
P codetools 0.2-20 2024-03-31 [?] CRAN (R 4.5.2)
P colorspace * 2.1-2 2025-09-22 [?] RSPM
P crosstalk 1.2.2 2025-08-26 [?] RSPM
P crsuggest * 0.4 2022-07-06 [?] RSPM
P DBI 1.2.3 2024-06-02 [?] RSPM (R 4.5.0)
P digest 0.6.39 2025-11-19 [?] RSPM (R 4.5.0)
P dplyr * 1.2.0 2026-02-03 [?] RSPM
P e1071 1.7-17 2025-12-18 [?] CRAN (R 4.5.2)
P evaluate 1.0.5 2025-08-27 [?] RSPM (R 4.5.0)
P farver 2.1.2 2024-05-13 [?] RSPM (R 4.5.0)
P fastmap 1.2.0 2024-05-15 [?] RSPM (R 4.5.0)
P forcats * 1.0.1 2025-09-25 [?] RSPM (R 4.5.0)
P generics 0.1.4 2025-05-09 [?] RSPM (R 4.5.0)
P ggplot2 * 4.0.1 2025-11-14 [?] RSPM (R 4.5.0)
P glue 1.8.0 2024-09-30 [?] RSPM (R 4.5.0)
P gtable 0.3.6 2024-10-25 [?] RSPM (R 4.5.0)
P here 1.0.2 2025-09-15 [?] CRAN (R 4.5.0)
P hms 1.1.4 2025-10-17 [?] RSPM (R 4.5.0)
P htmltools 0.5.9 2025-12-04 [?] RSPM (R 4.5.0)
P htmlwidgets 1.6.4 2023-12-06 [?] RSPM (R 4.5.0)
P jsonlite 2.0.0 2025-03-27 [?] RSPM (R 4.5.0)
P KernSmooth 2.23-26 2025-01-01 [?] CRAN (R 4.5.2)
P knitr 1.51 2025-12-20 [?] RSPM (R 4.5.0)
P labeling 0.4.3 2023-08-29 [?] RSPM (R 4.5.0)
P lattice 0.22-7 2025-04-02 [?] CRAN (R 4.5.2)
P leafem 0.2.5 2025-08-28 [?] RSPM
P leaflet 2.2.3 2025-09-04 [?] RSPM
P lifecycle 1.0.5 2026-01-08 [?] RSPM (R 4.5.0)
P lubridate * 1.9.4 2024-12-08 [?] RSPM (R 4.5.0)
P magrittr 2.0.4 2025-09-12 [?] RSPM (R 4.5.0)
P mapview 2.11.4 2025-09-08 [?] RSPM
P otel 0.2.0 2025-08-29 [?] RSPM (R 4.5.0)
P pillar 1.11.1 2025-09-17 [?] RSPM (R 4.5.0)
P pkgconfig 2.0.3 2019-09-22 [?] RSPM (R 4.5.0)
P png 0.1-8 2022-11-29 [?] RSPM (R 4.5.0)
P proxy 0.4-29 2025-12-29 [?] CRAN (R 4.5.2)
P purrr * 1.2.0 2025-11-04 [?] CRAN (R 4.5.0)
P R6 2.6.1 2025-02-15 [?] RSPM (R 4.5.0)
P raster 3.6-32 2025-03-28 [?] RSPM
P RColorBrewer 1.1-3 2022-04-03 [?] RSPM (R 4.5.0)
P Rcpp 1.1.0 2025-07-02 [?] RSPM (R 4.5.0)
P readr * 2.1.6 2025-11-14 [?] RSPM (R 4.5.0)
P renv 1.1.8 2026-03-05 [?] RSPM
P rlang 1.1.7 2026-01-09 [?] RSPM (R 4.5.0)
P rmarkdown 2.30 2025-09-28 [?] RSPM (R 4.5.0)
P rprojroot 2.1.1 2025-08-26 [?] RSPM (R 4.5.0)
P S7 0.2.1 2025-11-14 [?] RSPM (R 4.5.0)
P satellite 1.0.6 2025-08-21 [?] RSPM
P scales * 1.4.0 2025-04-24 [?] RSPM (R 4.5.0)
P sessioninfo 1.2.3 2025-02-05 [?] RSPM (R 4.5.0)
P sf * 1.0-23 2025-11-28 [?] CRAN (R 4.5.2)
P sp 2.2-0 2025-02-01 [?] RSPM
P stringi 1.8.7 2025-03-27 [?] RSPM (R 4.5.0)
P stringr * 1.6.0 2025-11-04 [?] RSPM (R 4.5.0)
P terra 1.8-86 2025-11-28 [?] CRAN (R 4.5.2)
P tibble * 3.3.0 2025-06-08 [?] RSPM (R 4.5.0)
P tidyr * 1.3.2 2025-12-19 [?] RSPM (R 4.5.0)
P tidyselect 1.2.1 2024-03-11 [?] RSPM (R 4.5.0)
P tidyverse * 2.0.0 2023-02-22 [?] RSPM (R 4.5.0)
P timechange 0.3.0 2024-01-18 [?] RSPM (R 4.5.0)
P tzdb 0.5.0 2025-03-15 [?] RSPM (R 4.5.0)
P units 1.0-0 2025-10-09 [?] RSPM
P utf8 1.2.6 2025-06-08 [?] RSPM (R 4.5.0)
P vctrs 0.7.1 2026-01-23 [?] RSPM
P withr 3.0.2 2024-10-28 [?] RSPM (R 4.5.0)
P xfun 0.55 2025-12-16 [?] CRAN (R 4.5.2)
P yaml 2.3.12 2025-12-10 [?] RSPM (R 4.5.0)
[1] /Users/bcs88/Projects/info-3312/course-site/renv/library/macos/R-4.5/aarch64-apple-darwin20
[2] /Users/bcs88/Library/Caches/org.R-project.R/R/renv/sandbox/macos/R-4.5/aarch64-apple-darwin20/4cd76b74
* ── Packages attached to the search path.
P ── Loaded and on-disk path mismatch.
──────────────────────────────────────────────────────────────────────────────



