+ - 0:00:00
Notes for current slide
Notes for next slide

CS&SS 569 Visualizing Data and Models

Lab 6: Visualizing spatial data

Ramses Llobet

Department of Political Science, UW

2025-02-14

1 / 56

Introduction

  • A long rant on space: What do we mean when we say visualizing "spatial data"?
2 / 56

Introduction

  • A long rant on space: What do we mean when we say visualizing "spatial data"?
  1. Physical world

    • Physical, spatial features: geographical area, features, contours, etc
3 / 56

Introduction

  • A long rant on space: What do we mean when we say visualizing "spatial data"?
  1. Physical world

    • Physical, spatial features: geographical area, features, contours, etc
  2. Social world

    • Some socio-economic-political variables that could be mapped onto physical, geographical features

    • E.g., district-level income level, crime rate, education spending, etc

4 / 56

Introduction

  • A long rant on space: What do we mean when we say visualizing "spatial data"?
  1. Physical world

    • Physical, spatial features: geographical area, features, contours, etc
  2. Social world

    • Some socio-economic-political variables that could be mapped onto physical, geographical features

    • E.g., district-level income level, crime rate, education spending, etc

  3. Graphical space as dimension(s) to express some variables

    • E.g., x and y coordinates on our 2D canvas
5 / 56

Introduction

  • We can project (1) physical space onto (3) graphical space

    • Traditional understanding of "map"
6 / 56

Introduction

  • We can project (1) physical space onto (3) graphical space

    • Traditional understanding of "map"
  • We can project (2) social variables directly onto (3) graphical space

    • Bubble plot uses size/area to express magnitude; bar plot uses length to express magnitude
7 / 56

Introduction

  • We can project (1) physical space onto (3) graphical space

    • Traditional understanding of "map"
  • We can project (2) social variables directly onto (3) graphical space

    • Bubble plot uses size/area to express magnitude; bar plot uses length to express magnitude
  • Problems start to occur when we project (2) social variables onto (1) physical space, then onto (3) graphical space

    • Let's say we want to visualize some district-level covariates
8 / 56

Introduction

  • We can project (1) physical space onto (3) graphical space

    • Traditional understanding of "map"
  • We can project (2) social variables directly onto (3) graphical space

    • Bubble plot uses size/area to express magnitude; bar plot uses length to express magnitude
  • Problems start to occur when we project (2) social variables onto (1) physical space, then onto (3) graphical space

    • Let's say we want to visualize some district-level covariates

    • Problem 1: incongruity b/w social space and physical space

    • We visualize district-level variables onto the whole WA state; too much extrapolation

9 / 56

Introduction

  • We can project (1) physical space onto (3) graphical space

    • Traditional understanding of "map"
  • We can project (2) social variables directly onto (3) graphical space

    • Bubble plot uses size/area to express magnitude; bar plot uses length to express magnitude
  • Problems start to occur when we project (2) social variables onto (1) physical space, then onto (3) graphical space

    • Let's say we want to visualize some district-level covariates

    • Problem 1: incongruity b/w social space and physical space

    • We visualize district-level variables onto the whole WA state; too much extrapolation

    • Problem 2: why do we prioritize physical space?

    • E.g., why a vast piece of land w/ little people should be prioritized over a small but densely populated area?

    • Can we use variables other than physical space to mediate (2) and (3)?

10 / 56

(In)famous US election map...

11 / 56

... inspires many advances in visualizing spatial data

12 / 56

But the problem is more common than you think...

13 / 56

14 / 56

15 / 56

16 / 56

17 / 56

18 / 56

Roadmap

  • Cover different ways to visualize spatial data:
19 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

20 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

21 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

22 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

23 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

    • Brief introduction to spatial data file (e.g., shapefile; .shp)
24 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

    • Brief introduction to spatial data file (e.g., shapefile; .shp)

    • package sf to wrangle spatial data and tmap to visualize map

25 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

    • Brief introduction to spatial data file (e.g., shapefile; .shp)

    • package sf to wrangle spatial data and tmap to visualize map

    • Interactive maps; small multiples in choropleth maps

26 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

    • Brief introduction to spatial data file (e.g., shapefile; .shp)

    • package sf to wrangle spatial data and tmap to visualize map

    • Interactive maps; small multiples in choropleth maps

  • Be mindful of the issues of space(s) and the curse of dimensionality

27 / 56

Roadmap

  • Cover different ways to visualize spatial data:

  • Geo-faceted small multiples w/ package geofacet

  • Cartogram heatmap w/ package statebins

  • Tiled cartogram w/ package tilegramsR

  • Choropleth maps (a.k.a. "maps'')

    • Brief introduction to spatial data file (e.g., shapefile; .shp)

    • package sf to wrangle spatial data and tmap to visualize map

    • Interactive maps; small multiples in choropleth maps

  • Be mindful of the issues of space(s) and the curse of dimensionality

    • How to incorporate time series or extra covariates when visualizing spatial data?
28 / 56

Prerequisite

# download packages
packages <- c("tidyverse", "geofacet", "statebins", "tilegramsR", "sf", "tmap", "tigris")
not_installed <- setdiff(packages, rownames(installed.packages()))
if (length(not_installed)) install.packages(not_installed)
# load packages
library(tidyverse)
library(geofacet)
library(statebins)
library(tilegramsR)
library(sf)
library(tmap)
library(maptiles)
library(tigris)
# load theme
source("https://students.washington.edu/kpleung/vis/theme_cavis.R")
29 / 56

Geo-faceted small multiples

WaPo_data <- read_csv("data/WaPo_data.csv")
29 / 56

Geo-faceted small multiples

WaPo_data <- read_csv("data/WaPo_data.csv")
print(WaPo_data, n = 5)
# A tibble: 51 × 23
stab state share_cut1994 share_cut1995 share_cut1996 share_cut1997
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 NC North Carolina 1.4 0.9 3 4.1
2 AL Alabama 1.1 2.4 5.2 4.6
3 MS Mississippi 2 3.9 5.1 2.2
4 AR Arkansas 1.6 1.3 1.6 2.7
5 TN Tennessee 1.6 2 3.4 3.5
# ℹ 46 more rows
# ℹ 17 more variables: share_cut1998 <dbl>, share_cut1999 <dbl>,
# share_cut2000 <dbl>, share_cut2001 <dbl>, share_cut2002 <dbl>,
# share_cut2003 <dbl>, share_cut2004 <dbl>, share_cut2005 <dbl>,
# share_cut2006 <dbl>, share_cut2007 <dbl>, share_cut2008 <dbl>,
# share_cut2009 <dbl>, share_cut2010 <dbl>, share_cut2011 <dbl>,
# share_cut2012 <dbl>, share_cut2013 <dbl>, avgshare <dbl>
29 / 56

Geo-faceted small multiples

# convert the data into long format
WaPo_data
# A tibble: 51 × 23
stab state share_cut1994 share_cut1995 share_cut1996 share_cut1997
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 NC North Carolina 1.4 0.9 3 4.1
2 AL Alabama 1.1 2.4 5.2 4.6
3 MS Mississippi 2 3.9 5.1 2.2
4 AR Arkansas 1.6 1.3 1.6 2.7
5 TN Tennessee 1.6 2 3.4 3.5
6 SC South Carolina 1.5 1 2.5 0.7
7 ME Maine 2.3 1.9 3.5 1.7
8 MI Michigan 0.3 0.4 1.1 0.9
9 OR Oregon 0.4 0.7 1.3 0.8
10 KY Kentucky 2.5 1 3.1 1.8
# ℹ 41 more rows
# ℹ 17 more variables: share_cut1998 <dbl>, share_cut1999 <dbl>,
# share_cut2000 <dbl>, share_cut2001 <dbl>, share_cut2002 <dbl>,
# share_cut2003 <dbl>, share_cut2004 <dbl>, share_cut2005 <dbl>,
# share_cut2006 <dbl>, share_cut2007 <dbl>, share_cut2008 <dbl>,
# share_cut2009 <dbl>, share_cut2010 <dbl>, share_cut2011 <dbl>,
# share_cut2012 <dbl>, share_cut2013 <dbl>, avgshare <dbl>
29 / 56

Geo-faceted small multiples

# convert the data into long format
WaPo_data %>%
select(-avgshare)
# A tibble: 51 × 22
stab state share_cut1994 share_cut1995 share_cut1996 share_cut1997
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 NC North Carolina 1.4 0.9 3 4.1
2 AL Alabama 1.1 2.4 5.2 4.6
3 MS Mississippi 2 3.9 5.1 2.2
4 AR Arkansas 1.6 1.3 1.6 2.7
5 TN Tennessee 1.6 2 3.4 3.5
6 SC South Carolina 1.5 1 2.5 0.7
7 ME Maine 2.3 1.9 3.5 1.7
8 MI Michigan 0.3 0.4 1.1 0.9
9 OR Oregon 0.4 0.7 1.3 0.8
10 KY Kentucky 2.5 1 3.1 1.8
# ℹ 41 more rows
# ℹ 16 more variables: share_cut1998 <dbl>, share_cut1999 <dbl>,
# share_cut2000 <dbl>, share_cut2001 <dbl>, share_cut2002 <dbl>,
# share_cut2003 <dbl>, share_cut2004 <dbl>, share_cut2005 <dbl>,
# share_cut2006 <dbl>, share_cut2007 <dbl>, share_cut2008 <dbl>,
# share_cut2009 <dbl>, share_cut2010 <dbl>, share_cut2011 <dbl>,
# share_cut2012 <dbl>, share_cut2013 <dbl>
29 / 56

Geo-faceted small multiples

# convert the data into long format
WaPo_data %>%
select(-avgshare) %>%
pivot_longer(contains("share_cut"), names_to = "year", values_to = "share_cut")
# A tibble: 1,020 × 4
stab state year share_cut
<chr> <chr> <chr> <dbl>
1 NC North Carolina share_cut1994 1.4
2 NC North Carolina share_cut1995 0.9
3 NC North Carolina share_cut1996 3
4 NC North Carolina share_cut1997 4.1
5 NC North Carolina share_cut1998 3
6 NC North Carolina share_cut1999 3.9
7 NC North Carolina share_cut2000 1.5
8 NC North Carolina share_cut2001 3.8
9 NC North Carolina share_cut2002 6.1
10 NC North Carolina share_cut2003 6.7
# ℹ 1,010 more rows
29 / 56

Geo-faceted small multiples

# convert the data into long format
WaPo_data %>%
select(-avgshare) %>%
pivot_longer(contains("share_cut"), names_to = "year", values_to = "share_cut") %>%
mutate(year = str_extract(year, "\\d+"),
year = as.numeric(year))
# A tibble: 1,020 × 4
stab state year share_cut
<chr> <chr> <dbl> <dbl>
1 NC North Carolina 1994 1.4
2 NC North Carolina 1995 0.9
3 NC North Carolina 1996 3
4 NC North Carolina 1997 4.1
5 NC North Carolina 1998 3
6 NC North Carolina 1999 3.9
7 NC North Carolina 2000 1.5
8 NC North Carolina 2001 3.8
9 NC North Carolina 2002 6.1
10 NC North Carolina 2003 6.7
# ℹ 1,010 more rows
29 / 56

Geo-faceted small multiples

# convert the data into long format
WaPo_data %>%
select(-avgshare) %>%
pivot_longer(contains("share_cut"), names_to = "year", values_to = "share_cut") %>%
mutate(year = str_extract(year, "\\d+"),
year = as.numeric(year)) ->
WaPo_data_long
29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut))

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line()

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_wrap(~ state)

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_wrap(~ state) +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
)

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_wrap(~ state) +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%")
)

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_wrap(~ state) +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%")
) +
theme(
strip.text.x = element_text(size = 7),
axis.text.x = element_text(size = 7),
axis.text.y = element_text(size = 7)
)

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_wrap(~ state) +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%")
) +
theme(
strip.text.x = element_text(size = 7),
axis.text.x = element_text(size = 7),
axis.text.y = element_text(size = 7)
) +
labs(x = NULL, y = "Share of job loss due to trade")

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_geo(~ state, grid = "us_state_grid2") +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%")
) +
theme(
strip.text.x = element_text(size = 7),
axis.text.x = element_text(size = 7),
axis.text.y = element_text(size = 7)
) +
labs(x = NULL, y = "Share of job loss due to trade")

29 / 56

Geo-faceted small multiples

ggplot(WaPo_data_long, aes(x = year , y = share_cut)) +
theme_cavis_hgrid +
geom_line() +
facet_geo(~ state, grid = "us_state_grid1") +
scale_x_continuous(
labels = function(x) paste0("'", str_sub(x, 3, 4))
) +
scale_y_continuous(
labels = function(x) paste0(x, "%")
) +
theme(
strip.text.x = element_text(size = 7),
axis.text.x = element_text(size = 7),
axis.text.y = element_text(size = 7)
) +
labs(x = NULL, y = "Share of job loss due to trade")

29 / 56

Geo-faceted small multiples

30 / 56

Geo-faceted small multiples

31 / 56

Cartogram Heatmaps

32 / 56

Cartogram heatmaps with statebins package

# coerce avgshare into a factor
WaPo_data
# A tibble: 51 × 23
stab state share_cut1994 share_cut1995 share_cut1996 share_cut1997
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 NC North Carolina 1.4 0.9 3 4.1
2 AL Alabama 1.1 2.4 5.2 4.6
3 MS Mississippi 2 3.9 5.1 2.2
4 AR Arkansas 1.6 1.3 1.6 2.7
5 TN Tennessee 1.6 2 3.4 3.5
6 SC South Carolina 1.5 1 2.5 0.7
7 ME Maine 2.3 1.9 3.5 1.7
8 MI Michigan 0.3 0.4 1.1 0.9
9 OR Oregon 0.4 0.7 1.3 0.8
10 KY Kentucky 2.5 1 3.1 1.8
# ℹ 41 more rows
# ℹ 17 more variables: share_cut1998 <dbl>, share_cut1999 <dbl>,
# share_cut2000 <dbl>, share_cut2001 <dbl>, share_cut2002 <dbl>,
# share_cut2003 <dbl>, share_cut2004 <dbl>, share_cut2005 <dbl>,
# share_cut2006 <dbl>, share_cut2007 <dbl>, share_cut2008 <dbl>,
# share_cut2009 <dbl>, share_cut2010 <dbl>, share_cut2011 <dbl>,
# share_cut2012 <dbl>, share_cut2013 <dbl>, avgshare <dbl>
32 / 56

Cartogram heatmaps with statebins package

# coerce avgshare into a factor
WaPo_data %>%
select(stab, state, avgshare)
# A tibble: 51 × 3
stab state avgshare
<chr> <chr> <dbl>
1 NC North Carolina 3.56
2 AL Alabama 3.22
3 MS Mississippi 2.94
4 AR Arkansas 2.89
5 TN Tennessee 2.86
6 SC South Carolina 2.61
7 ME Maine 2.58
8 MI Michigan 2.55
9 OR Oregon 2.38
10 KY Kentucky 2.24
# ℹ 41 more rows
32 / 56

Cartogram heatmaps with statebins package

# coerce avgshare into a factor
WaPo_data %>%
select(stab, state, avgshare) %>%
mutate(avgshare2 = cut(avgshare,
breaks = 4,
labels = c("0-1", "1-2", "2-3", "3-4")))
# A tibble: 51 × 4
stab state avgshare avgshare2
<chr> <chr> <dbl> <fct>
1 NC North Carolina 3.56 3-4
2 AL Alabama 3.22 3-4
3 MS Mississippi 2.94 3-4
4 AR Arkansas 2.89 3-4
5 TN Tennessee 2.86 3-4
6 SC South Carolina 2.61 2-3
7 ME Maine 2.58 2-3
8 MI Michigan 2.55 2-3
9 OR Oregon 2.38 2-3
10 KY Kentucky 2.24 2-3
# ℹ 41 more rows
32 / 56

Cartogram heatmaps with statebins package

# coerce avgshare into a factor
WaPo_data %>%
select(stab, state, avgshare) %>%
mutate(avgshare2 = cut(avgshare,
breaks = 4,
labels = c("0-1", "1-2", "2-3", "3-4"))) ->
WaPo_data2
32 / 56

Cartogram heatmaps with statebins package

WaPo_data2
# A tibble: 51 × 4
stab state avgshare avgshare2
<chr> <chr> <dbl> <fct>
1 NC North Carolina 3.56 3-4
2 AL Alabama 3.22 3-4
3 MS Mississippi 2.94 3-4
4 AR Arkansas 2.89 3-4
5 TN Tennessee 2.86 3-4
6 SC South Carolina 2.61 2-3
7 ME Maine 2.58 2-3
8 MI Michigan 2.55 2-3
9 OR Oregon 2.38 2-3
10 KY Kentucky 2.24 2-3
# ℹ 41 more rows
32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
)

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
) +
theme_statebins()

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
round = TRUE
) +
theme_statebins()

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
round = TRUE
) +
theme_statebins() +
scale_fill_brewer(
palette = "Blues",
labels = c("Smallest\nshare", "", "", "Largest"),
name = "Share of job loss due to trade")

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
round = TRUE
) +
theme_statebins() +
scale_fill_brewer(
palette = "Blues",
labels = c("Smallest\nshare", "", "", "Largest"),
name = "Share of job loss due to trade") +
guides(fill = guide_legend(title.position = "top",
label.position = "bottom"))

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
round = TRUE
) +
theme_statebins() +
scale_fill_brewer(
palette = "Blues",
labels = c("Smallest\nshare", "", "", "Largest"),
name = "Share of job loss due to trade") +
guides(fill = guide_legend(title.position = "top",
label.position = "bottom")) +
theme(legend.position = c(0, 0.85),
legend.direction = "horizontal",
)

32 / 56

Cartogram heatmaps with statebins package

WaPo_data2 %>%
statebins(
value_col = "avgshare2",
ggplot2_scale_function = scale_fill_brewer,
round = TRUE
) +
theme_statebins() +
scale_fill_brewer(
palette = "Blues",
labels = c("Smallest\nshare", "", "", "Largest"),
name = "Share of job loss due to trade") +
guides(fill = guide_legend(title.position = "top",
label.position = "bottom")) +
theme(legend.position = c(0, 0.85),
legend.direction = "horizontal",
legend.key.height = unit(0.2, "cm"),
legend.key.width = unit(1.6, "cm")
)

32 / 56

Cartogram heatmaps with statebins package

  • The statebins package only supports the United States data at the moment

  • But customizing grid should be easy to implement, like geofacet package?

33 / 56

Tiled cartogram with tilegramsR package

34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
[1] "sf" "data.frame"
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
ec_tiles
[1] "sf" "data.frame"
Simple feature collection with 538 features and 3 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 293.6239 ymin: 16.95238 xmax: 2495.803 ymax: 1661.333
CRS: NA
First 10 features:
FID state tilegramVa geometry
1 02 AK 3 POLYGON ((293.6239 237.3333...
2 06 CA 55 POLYGON ((352.3486 847.619,...
3 06 CA 55 POLYGON ((322.9862 796.7619...
4 06 CA 55 POLYGON ((352.3486 745.9048...
5 06 CA 55 POLYGON ((322.9862 695.0476...
6 06 CA 55 POLYGON ((352.3486 644.1905...
7 02 AK 3 POLYGON ((322.9862 288.1905...
8 02 AK 3 POLYGON ((352.3486 237.3333...
9 06 CA 55 POLYGON ((411.0734 949.3333...
10 06 CA 55 POLYGON ((381.711 898.4762,...
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
ec_tiles %>%
left_join(WaPo_data2, by = c("state" = "stab"))
[1] "sf" "data.frame"
Simple feature collection with 538 features and 6 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 293.6239 ymin: 16.95238 xmax: 2495.803 ymax: 1661.333
CRS: NA
First 10 features:
FID state tilegramVa state.y avgshare avgshare2
1 02 AK 3 Alaska 1.88 2-3
2 06 CA 55 California 0.72 0-1
3 06 CA 55 California 0.72 0-1
4 06 CA 55 California 0.72 0-1
5 06 CA 55 California 0.72 0-1
6 06 CA 55 California 0.72 0-1
7 02 AK 3 Alaska 1.88 2-3
8 02 AK 3 Alaska 1.88 2-3
9 06 CA 55 California 0.72 0-1
10 06 CA 55 California 0.72 0-1
geometry
1 POLYGON ((293.6239 237.3333...
2 POLYGON ((352.3486 847.619,...
3 POLYGON ((322.9862 796.7619...
4 POLYGON ((352.3486 745.9048...
5 POLYGON ((322.9862 695.0476...
6 POLYGON ((352.3486 644.1905...
7 POLYGON ((322.9862 288.1905...
8 POLYGON ((352.3486 237.3333...
9 POLYGON ((411.0734 949.3333...
10 POLYGON ((381.711 898.4762,...
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
ec_tiles %>%
left_join(WaPo_data2, by = c("state" = "stab")) ->
ec_tiles
[1] "sf" "data.frame"
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
ec_tiles %>%
left_join(WaPo_data2, by = c("state" = "stab")) ->
ec_tiles
state_tiles <- sf_FiveThirtyEightElectoralCollege.states # state polygons for drawing borders
[1] "sf" "data.frame"
34 / 56

Tiled cartogram with tilegramsR package

ec_tiles <- tilegramsR::sf_FiveThirtyEightElectoralCollege
class(ec_tiles) # more on sf obejct soon
ec_tiles %>%
left_join(WaPo_data2, by = c("state" = "stab")) ->
ec_tiles
state_tiles <- sf_FiveThirtyEightElectoralCollege.states # state polygons for drawing borders
ec_centers <- sf_FiveThirtyEightElectoralCollege.centers # state centroids for drawing labels
[1] "sf" "data.frame"
34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void()

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
)

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
)
)

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
)

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
) +
scale_fill_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade")

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
) +
scale_fill_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
scale_color_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade")

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
) +
scale_fill_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
scale_color_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
geom_sf_text(
data = ec_centers,
aes(label = state)
)

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
) +
scale_fill_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
scale_color_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
geom_sf_text(
data = ec_centers,
aes(label = state)
) +
geom_sf(
data = state_tiles,
color = "white", alpha = 0
)

34 / 56

Tiled cartogram with tilegramsR package

ggplot() +
theme_void() +
geom_sf(
data = ec_tiles,
aes(
fill = avgshare2,
color = avgshare2
)
) +
scale_fill_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
scale_color_brewer(palette = "Blues",
name = "Share of job loss\ndue to trade") +
geom_sf_text(
data = ec_centers,
aes(label = state)
) +
geom_sf(
data = state_tiles,
color = "white", alpha = 0
) +
theme(legend.position = c(0.925, 0.25))

34 / 56

Final thoughts about tiled cartograms

35 / 56

Final thoughts about tiled cartograms

36 / 56

Final thoughts about tiled cartograms

  • Why hexagos? Because hexagons are the bestagons

  • To my knowledge, there is no existing algorithm to automatically generate the tile cartogram layouts

  • I'm trying to develop a function/package to do that: inspirations from using neural networks/ genetic algorithms to solve the Tetris game

37 / 56

Introduction to spatial data in R

  • Numerous spatial data formats
38 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
39 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

40 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

    • Recent package sf allows geospatial data to be stored in data frames
41 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

    • Recent package sf allows geospatial data to be stored in data frames

    • Well integrated with tidyverse

42 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

    • Recent package sf allows geospatial data to be stored in data frames

    • Well integrated with tidyverse

  • Many packages to draw maps

43 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

    • Recent package sf allows geospatial data to be stored in data frames

    • Well integrated with tidyverse

  • Many packages to draw maps

    • tmap allows easy visualization of static and interactive maps
44 / 56

Introduction to spatial data in R

  • Numerous spatial data formats

    • .shp (shapefile; the most common); .geojson, .json; .gml; .csv; .tiff...
  • Countless packages to work with spatial data

    • Recent package sf allows geospatial data to be stored in data frames

    • Well integrated with tidyverse

  • Many packages to draw maps

    • tmap allows easy visualization of static and interactive maps

    • Also employs the "grammar of graphics"

45 / 56

Introduction to spatial data in R

  • Grammar of graphics in tmap:
ggplot2 tmap
Data ggplot(...) + tm_shape(...) +
Layers geom_...(...) + tm_...(...) +
Small Multiples facet_grid(...) tm_facets(...)
Layout theme(...) tm_layout(...)
46 / 56

Introduction to spatial data in R

  • Before plotting choropleth maps, we need to find the appropriate shapefile
47 / 56

Introduction to spatial data in R

  • Before plotting choropleth maps, we need to find the appropriate shapefile

  • Download the US shapefile here

48 / 56

Choropleth maps with sf and tmap

us_shp <- st_read("data/cb_2018_us_state_20m/cb_2018_us_state_20m.shp")
Reading layer `cb_2018_us_state_20m' from data source
`D:\Google Drive\Phd UW\Courses\5th year\CS&SS 569 - Visualizing Data and Models\Labs\Lab6\data\cb_2018_us_state_20m\cb_2018_us_state_20m.shp'
using driver `ESRI Shapefile'
Simple feature collection with 52 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -179.1743 ymin: 17.91377 xmax: 179.7739 ymax: 71.35256
Geodetic CRS: NAD83
48 / 56

Choropleth maps with sf and tmap

us_shp <- st_read("data/cb_2018_us_state_20m/cb_2018_us_state_20m.shp")
class(us_shp)
Reading layer `cb_2018_us_state_20m' from data source
`D:\Google Drive\Phd UW\Courses\5th year\CS&SS 569 - Visualizing Data and Models\Labs\Lab6\data\cb_2018_us_state_20m\cb_2018_us_state_20m.shp'
using driver `ESRI Shapefile'
Simple feature collection with 52 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -179.1743 ymin: 17.91377 xmax: 179.7739 ymax: 71.35256
Geodetic CRS: NAD83
[1] "sf" "data.frame"
48 / 56

Choropleth maps with sf and tmap

us_shp <- st_read("data/cb_2018_us_state_20m/cb_2018_us_state_20m.shp")
class(us_shp)
head(as_tibble(us_shp))
Reading layer `cb_2018_us_state_20m' from data source
`D:\Google Drive\Phd UW\Courses\5th year\CS&SS 569 - Visualizing Data and Models\Labs\Lab6\data\cb_2018_us_state_20m\cb_2018_us_state_20m.shp'
using driver `ESRI Shapefile'
Simple feature collection with 52 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -179.1743 ymin: 17.91377 xmax: 179.7739 ymax: 71.35256
Geodetic CRS: NAD83
[1] "sf" "data.frame"
# A tibble: 6 × 10
STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND AWATER
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
1 24 01714934 0400000US24 24 MD Maryland 00 2.52e10 6.98e 9
2 19 01779785 0400000US19 19 IA Iowa 00 1.45e11 1.08e 9
3 10 01779781 0400000US10 10 DE Delaware 00 5.05e 9 1.40e 9
4 39 01085497 0400000US39 39 OH Ohio 00 1.06e11 1.03e10
5 42 01779798 0400000US42 42 PA Pennsylvania 00 1.16e11 3.39e 9
6 31 01779792 0400000US31 31 NE Nebraska 00 1.99e11 1.37e 9
# ℹ 1 more variable: geometry <MULTIPOLYGON [°]>
48 / 56

Choropleth maps with sf and tmap

us_shp
Simple feature collection with 52 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -179.1743 ymin: 17.91377 xmax: 179.7739 ymax: 71.35256
Geodetic CRS: NAD83
First 10 features:
STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND
1 24 01714934 0400000US24 24 MD Maryland 00 25151100280
2 19 01779785 0400000US19 19 IA Iowa 00 144661267977
3 10 01779781 0400000US10 10 DE Delaware 00 5045925646
4 39 01085497 0400000US39 39 OH Ohio 00 105828882568
5 42 01779798 0400000US42 42 PA Pennsylvania 00 115884442321
6 31 01779792 0400000US31 31 NE Nebraska 00 198956658395
7 53 01779804 0400000US53 53 WA Washington 00 172112588220
8 72 01779808 0400000US72 72 PR Puerto Rico 00 8868896030
9 01 01779775 0400000US01 01 AL Alabama 00 131174048583
10 05 00068085 0400000US05 05 AR Arkansas 00 134768872727
AWATER geometry
1 6979966958 MULTIPOLYGON (((-76.04621 3...
2 1084180812 MULTIPOLYGON (((-96.62187 4...
3 1399985648 MULTIPOLYGON (((-75.77379 3...
4 10268850702 MULTIPOLYGON (((-82.86334 4...
5 3394589990 MULTIPOLYGON (((-80.51989 4...
6 1371829134 MULTIPOLYGON (((-104.0531 4...
7 12559278850 MULTIPOLYGON (((-123.2371 4...
8 4922382562 MULTIPOLYGON (((-65.34207 1...
9 4593327154 MULTIPOLYGON (((-88.46866 3...
10 2962859592 MULTIPOLYGON (((-94.61792 3...
48 / 56

Choropleth maps with sf and tmap

us_shp %>%
left_join(WaPo_data, by=c("NAME" = "state"))
Simple feature collection with 52 features and 31 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -179.1743 ymin: 17.91377 xmax: 179.7739 ymax: 71.35256
Geodetic CRS: NAD83
First 10 features:
STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND
1 24 01714934 0400000US24 24 MD Maryland 00 25151100280
2 19 01779785 0400000US19 19 IA Iowa 00 144661267977
3 10 01779781 0400000US10 10 DE Delaware 00 5045925646
4 39 01085497 0400000US39 39 OH Ohio 00 105828882568
5 42 01779798 0400000US42 42 PA Pennsylvania 00 115884442321
6 31 01779792 0400000US31 31 NE Nebraska 00 198956658395
7 53 01779804 0400000US53 53 WA Washington 00 172112588220
8 72 01779808 0400000US72 72 PR Puerto Rico 00 8868896030
9 01 01779775 0400000US01 01 AL Alabama 00 131174048583
10 05 00068085 0400000US05 05 AR Arkansas 00 134768872727
AWATER stab share_cut1994 share_cut1995 share_cut1996 share_cut1997
1 6979966958 MD 0.4 1.1 0.7 0.4
2 1084180812 IA 0.1 0.4 0.5 0.6
3 1399985648 DE 0.6 0.0 0.0 0.0
4 10268850702 OH 0.6 0.8 0.6 1.0
5 3394589990 PA 1.5 1.4 2.0 1.7
6 1371829134 NE 0.0 0.2 0.7 0.1
7 12559278850 WA 1.0 1.2 0.5 0.4
8 4922382562 <NA> NA NA NA NA
9 4593327154 AL 1.1 2.4 5.2 4.6
10 2962859592 AR 1.6 1.3 1.6 2.7
share_cut1998 share_cut1999 share_cut2000 share_cut2001 share_cut2002
1 0.5 0.4 0.3 0.1 0.3
2 0.1 0.5 0.1 0.6 0.9
3 0.0 0.4 0.0 0.0 0.0
4 0.5 1.0 0.9 1.3 2.5
5 1.5 1.3 1.4 3.6 2.8
6 0.1 0.2 1.0 0.0 0.6
7 1.0 0.7 2.5 1.4 9.4
8 NA NA NA NA NA
9 3.5 5.6 2.5 2.8 6.5
10 2.7 2.8 0.6 3.1 3.9
share_cut2003 share_cut2004 share_cut2005 share_cut2006 share_cut2007
1 1.1 0.1 0.5 0.7 0.8
2 0.9 1.0 0.6 2.4 0.9
3 1.0 0.9 0.7 0.4 0.1
4 1.9 1.4 0.9 2.9 2.0
5 2.8 1.2 1.5 0.9 1.6
6 2.0 1.2 0.2 0.2 0.9
7 1.3 3.4 0.6 0.4 0.6
8 NA NA NA NA NA
9 2.2 2.1 1.2 3.3 2.6
10 3.6 1.1 2.3 3.8 4.9
share_cut2008 share_cut2009 share_cut2010 share_cut2011 share_cut2012
1 0.5 0.2 0.6 0.8 0.3
2 0.8 2.3 1.4 1.4 0.2
3 0.0 5.4 0.0 0.0 0.0
4 2.2 5.0 2.8 1.0 1.3
5 1.0 2.6 2.5 0.9 1.1
6 0.3 1.3 0.3 1.1 0.1
7 0.7 2.2 1.6 1.1 1.0
8 NA NA NA NA NA
9 3.9 4.3 3.6 0.4 0.7
10 3.2 3.0 3.3 2.4 3.9
share_cut2013 avgshare geometry
1 0.1 0.47 MULTIPOLYGON (((-76.04621 3...
2 1.1 0.89 MULTIPOLYGON (((-96.62187 4...
3 0.1 0.53 MULTIPOLYGON (((-75.77379 3...
4 0.4 1.72 MULTIPOLYGON (((-82.86334 4...
5 0.8 1.79 MULTIPOLYGON (((-80.51989 4...
6 0.5 0.62 MULTIPOLYGON (((-104.0531 4...
7 0.7 1.69 MULTIPOLYGON (((-123.2371 4...
8 NA NA MULTIPOLYGON (((-65.34207 1...
9 0.6 3.22 MULTIPOLYGON (((-88.46866 3...
10 0.5 2.89 MULTIPOLYGON (((-94.61792 3...
48 / 56

Choropleth maps with sf and tmap

us_shp %>%
left_join(WaPo_data, by=c("NAME" = "state")) %>%
tigris::shift_geometry() # rescale AK, HI, PR
Simple feature collection with 52 features and 31 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -3112200 ymin: -1697728 xmax: 2258154 ymax: 1558935
Projected CRS: USA_Contiguous_Albers_Equal_Area_Conic
First 10 features:
STATEFP STATENS AFFGEOID GEOID STUSPS NAME LSAD ALAND
1 24 01714934 0400000US24 24 MD Maryland 00 25151100280
2 19 01779785 0400000US19 19 IA Iowa 00 144661267977
3 10 01779781 0400000US10 10 DE Delaware 00 5045925646
4 39 01085497 0400000US39 39 OH Ohio 00 105828882568
5 42 01779798 0400000US42 42 PA Pennsylvania 00 115884442321
6 31 01779792 0400000US31 31 NE Nebraska 00 198956658395
7 53 01779804 0400000US53 53 WA Washington 00 172112588220
8 01 01779775 0400000US01 01 AL Alabama 00 131174048583
9 05 00068085 0400000US05 05 AR Arkansas 00 134768872727
10 35 00897535 0400000US35 35 NM New Mexico 00 314196306401
AWATER stab share_cut1994 share_cut1995 share_cut1996 share_cut1997
1 6979966958 MD 0.4 1.1 0.7 0.4
2 1084180812 IA 0.1 0.4 0.5 0.6
3 1399985648 DE 0.6 0.0 0.0 0.0
4 10268850702 OH 0.6 0.8 0.6 1.0
5 3394589990 PA 1.5 1.4 2.0 1.7
6 1371829134 NE 0.0 0.2 0.7 0.1
7 12559278850 WA 1.0 1.2 0.5 0.4
8 4593327154 AL 1.1 2.4 5.2 4.6
9 2962859592 AR 1.6 1.3 1.6 2.7
10 728776523 NM 1.4 0.8 0.9 3.0
share_cut1998 share_cut1999 share_cut2000 share_cut2001 share_cut2002
1 0.5 0.4 0.3 0.1 0.3
2 0.1 0.5 0.1 0.6 0.9
3 0.0 0.4 0.0 0.0 0.0
4 0.5 1.0 0.9 1.3 2.5
5 1.5 1.3 1.4 3.6 2.8
6 0.1 0.2 1.0 0.0 0.6
7 1.0 0.7 2.5 1.4 9.4
8 3.5 5.6 2.5 2.8 6.5
9 2.7 2.8 0.6 3.1 3.9
10 1.4 4.5 0.4 0.3 1.7
share_cut2003 share_cut2004 share_cut2005 share_cut2006 share_cut2007
1 1.1 0.1 0.5 0.7 0.8
2 0.9 1.0 0.6 2.4 0.9
3 1.0 0.9 0.7 0.4 0.1
4 1.9 1.4 0.9 2.9 2.0
5 2.8 1.2 1.5 0.9 1.6
6 2.0 1.2 0.2 0.2 0.9
7 1.3 3.4 0.6 0.4 0.6
8 2.2 2.1 1.2 3.3 2.6
9 3.6 1.1 2.3 3.8 4.9
10 0.5 0.1 0.1 0.1 0.0
share_cut2008 share_cut2009 share_cut2010 share_cut2011 share_cut2012
1 0.5 0.2 0.6 0.8 0.3
2 0.8 2.3 1.4 1.4 0.2
3 0.0 5.4 0.0 0.0 0.0
4 2.2 5.0 2.8 1.0 1.3
5 1.0 2.6 2.5 0.9 1.1
6 0.3 1.3 0.3 1.1 0.1
7 0.7 2.2 1.6 1.1 1.0
8 3.9 4.3 3.6 0.4 0.7
9 3.2 3.0 3.3 2.4 3.9
10 4.1 1.7 1.9 0.1 0.8
share_cut2013 avgshare geometry
1 0.1 0.47 MULTIPOLYGON (((1722285 240...
2 1.1 0.89 MULTIPOLYGON (((-50588.83 5...
3 0.1 0.53 MULTIPOLYGON (((1705278 431...
4 0.4 1.72 MULTIPOLYGON (((1081987 544...
5 0.8 1.79 MULTIPOLYGON (((1287712 486...
6 0.5 0.62 MULTIPOLYGON (((-670097.4 4...
7 0.7 1.69 MULTIPOLYGON (((-2000238 15...
8 0.6 3.22 MULTIPOLYGON (((708460.5 -5...
9 0.5 2.89 MULTIPOLYGON (((122656.3 -1...
10 0.0 1.26 MULTIPOLYGON (((-1226428 -5...
48 / 56

Choropleth maps with sf and tmap

us_shp %>%
left_join(WaPo_data, by=c("NAME" = "state")) %>%
tigris::shift_geometry() -> # rescale AK, HI, PR
us_shp2
48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
) +
tm_text(
text = "STUSPS",
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
) +
tm_text(
text = "STUSPS",
size = "avgshare",
legend.size.show = FALSE
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
) +
tm_text(
text = "STUSPS",
size = "avgshare",
legend.size.show = FALSE
) +
tm_layout(
frame = FALSE,
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
legend.is.portrait = FALSE,
) +
tm_text(
text = "STUSPS",
size = "avgshare",
legend.size.show = FALSE
) +
tm_layout(
frame = FALSE,
legend.stack = "horizontal",
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
legend.is.portrait = FALSE,
) +
tm_text(
text = "STUSPS",
size = "avgshare",
legend.size.show = FALSE
) +
tm_layout(
frame = FALSE,
legend.stack = "horizontal",
legend.position = c('right', 'top'),
)

48 / 56

Choropleth maps with sf and tmap

tm_shape(us_shp2) + tm_polygons(
col = "avgshare",
palette = "Blues",
border.col = "white",
legend.is.portrait = FALSE,
title = "Share of job loss due to trade",
labels = c("Smallest", "", "", "Largest share")
) +
tm_text(
text = "STUSPS",
size = "avgshare",
legend.size.show = FALSE
) +
tm_layout(
frame = FALSE,
legend.stack = "horizontal",
legend.position = c('right', 'top'),
legend.title.size = 1,
legend.text.size = 0.5
)

48 / 56

Choropleth maps with sf and tmap

  • To save the map:
tmap_save(tmap_object, filename = "[...].pdf")
49 / 56

Choropleth maps with sf and tmap: NYC examples

50 / 56

Choropleth maps with sf and tmap: NYC examples

51 / 56

Choropleth maps with sf and tmap: NYC examples

# load .shp file with sf
nyc_shp <- st_read("data/nyc/nyc.shp")
Reading layer `nyc' from data source
`D:\Google Drive\Phd UW\Courses\5th year\CS&SS 569 - Visualizing Data and Models\Labs\Lab6\data\nyc\nyc.shp'
using driver `ESRI Shapefile'
Simple feature collection with 55 features and 34 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 913037.2 ymin: 120117 xmax: 1067549 ymax: 272751.4
Projected CRS: NAD83 / New York Long Island (ftUS)
52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
)

52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
)

52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
)

52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
)

52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
)

52 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_layout(frame = FALSE)

52 / 56

Choropleth maps with sf and tmap: NYC examples

## interactive mode in tmap
tmap_mode("view")
52 / 56

Choropleth maps with sf and tmap: NYC examples

## interactive mode in tmap
tmap_mode("view")
## switch off spherical geometry to avoid error
## usually you don't need to do this
sf::sf_use_s2(use_s2 = FALSE)
52 / 56

Choropleth maps with sf and tmap: NYC examples

## interactive mode in tmap
tmap_mode("view")
## switch off spherical geometry to avoid error
## usually you don't need to do this
sf::sf_use_s2(use_s2 = FALSE)
## tmap
tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
title = "Rent in 2008",
alpha = 0.5
)

Rent in 2008
0 to 500
500 to 1,000
1,000 to 1,500
1,500 to 2,000
2,000 to 2,500
2,500 to 3,000
Missing
Leaflet | Tiles © Esri — Esri, DeLorme, NAVTEQ
52 / 56

Choropleth maps with sf and tmap: NYC examples

## interactive mode in tmap
tmap_mode("view")
## switch off spherical geometry to avoid error
## usually you don't need to do this
sf::sf_use_s2(use_s2 = FALSE)
## tmap
tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
title = "Rent in 2008",
alpha = 0.5
) +
tm_basemap(
server = "OpenStreetMap",
alpha = 0.5
)

Rent in 2008
0 to 500
500 to 1,000
1,000 to 1,500
1,500 to 2,000
2,000 to 2,500
2,500 to 3,000
Missing
Leaflet | © OpenStreetMap contributors
52 / 56

Choropleth maps with sf and tmap: NYC examples

## interactive mode in tmap
tmap_mode("view")
## switch off spherical geometry to avoid error
## usually you don't need to do this
sf::sf_use_s2(use_s2 = FALSE)
## tmap
tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
title = "Rent in 2008",
alpha = 0.5
) +
tm_basemap(
server = "OpenStreetMap",
alpha = 0.5
)
## switch back to plotting mode
tmap_mode("plot")

Rent in 2008
0 to 500
500 to 1,000
1,000 to 1,500
1,500 to 2,000
2,000 to 2,500
2,500 to 3,000
Missing
Leaflet | © OpenStreetMap contributors
52 / 56

Choropleth maps with sf and tmap: NYC examples

  • How to do small multiples in tmap?
53 / 56

Choropleth maps with sf and tmap: NYC examples

  • How to do small multiples in tmap?

    • tmap_arrange(): like cowplot::plot_grid(); arrange multiple maps into a grid
54 / 56

Choropleth maps with sf and tmap: NYC examples

  • How to do small multiples in tmap?

    • tmap_arrange(): like cowplot::plot_grid(); arrange multiple maps into a grid

    • tm_facets(): like facet_grid() or facet_wrap(); facet areas(polygons) by some variables

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_layout(frame = FALSE)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_layout(frame = FALSE) ->
rentNYC
55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "forhis08",
border.col = "white",
title = "Hispanic population in 2008 (%)"
)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "forhis08",
border.col = "white",
title = "Hispanic population in 2008 (%)"
) +
tm_layout(frame = FALSE)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "forhis08",
border.col = "white",
title = "Hispanic population in 2008 (%)"
) +
tm_layout(frame = FALSE) ->
hisNYC
55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "pubast00",
palette = "Blues",
border.col = "white",
title = "% of households receiving \nassistance in 2000"
)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "pubast00",
palette = "Blues",
border.col = "white",
title = "% of households receiving \nassistance in 2000"
) +
tm_layout(frame = FALSE)

55 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp) + tm_polygons(
col = "pubast00",
palette = "Blues",
border.col = "white",
title = "% of households receiving \nassistance in 2000"
) +
tm_layout(frame = FALSE) ->
pubastNYC
55 / 56

Choropleth maps with sf and tmap: NYC examples

tmap_arrange(rentNYC, hisNYC, pubastNYC, nrow = 1)

56 / 56

Choropleth maps with sf and tmap: NYC examples

## categorize hispanic pop levels
labels <- c("Low hisp pop",
"Mid hisp pop",
"High hisp pop")
56 / 56

Choropleth maps with sf and tmap: NYC examples

## categorize hispanic pop levels
labels <- c("Low hisp pop",
"Mid hisp pop",
"High hisp pop")
nyc_shp
Simple feature collection with 55 features and 34 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 913037.2 ymin: 120117 xmax: 1067549 ymax: 272751.4
Projected CRS: NAD83 / New York Long Island (ftUS)
First 10 features:
bor_subb name code subborough forhis06
1 501 North Shore 501 North Shore 37.0657
2 502 Mid-Island 502 Mid-Island 27.9822
3 503 South Shore 503 South Shore 10.7019
4 401 Astoria 401 Astoria 52.0961
5 402 Sunnyside / Woodside 402 Sunnyside/Woodside 62.7242
6 403 Jackson Heights 403 Jackson Heights 68.4834
7 404 Elmhurst / Corona 404 Elmhurst/Corona 69.5219
8 405 Middle Village / Ridgewood 405 Middle Village/Ridgewood 39.4185
9 406 Forest Hills / Rego Park 406 Rego Park/Forest Hills 58.5388
10 407 Flushing / Whitestone 407 Flushing/Whitestone 59.4432
forhis07 forhis08 forhis09 forwh06 forwh07 forwh08 forwh09 hhsiz1990 hhsiz00
1 34.0317 27.3767 29.3091 13.2540 11.8768 11.1788 11.1459 2.7146 2.7338
2 18.1193 24.0452 31.1566 20.0616 19.8575 22.4870 17.0371 2.8233 2.7176
3 12.1404 9.6890 14.6638 10.3060 12.7699 9.3561 10.2830 3.0547 2.8497
4 53.9585 54.6968 47.8050 38.3658 35.6551 32.1289 34.6578 2.4279 2.4995
5 69.3969 67.0897 58.2963 37.0512 31.9057 32.3264 33.8794 2.4646 2.6287
6 68.5405 66.5080 69.1580 34.3999 38.2428 38.1470 26.5347 2.8081 3.1650
7 66.8795 69.3414 64.3005 40.3935 51.6376 45.9578 48.3542 2.9690 3.1784
8 35.9546 36.2750 35.0181 37.8097 34.0156 33.0695 33.0816 2.5174 2.6606
9 52.6183 42.3878 47.9795 43.7395 47.5873 45.1205 39.8293 2.0631 2.1532
10 53.4747 53.2531 57.9868 26.5802 25.6864 21.3858 23.5204 2.6302 2.6818
hhsiz02 hhsiz05 hhsiz08 kids2000 kids2005 kids2006 kids2007 kids2008
1 2.7412 2.8010 2.6983 39.2995 43.3788 38.4022 41.5213 39.8390
2 2.5405 2.6228 2.5749 36.2234 35.7630 36.9081 37.6798 37.2447
3 2.6525 2.6121 2.6483 39.7362 42.5232 40.3577 40.3797 40.4820
4 2.3032 2.3227 2.2746 28.4592 27.2223 25.2556 24.8911 22.0364
5 2.5300 2.4993 2.4766 29.8808 28.6841 28.1440 26.3675 29.9032
6 2.9108 2.8599 2.8604 41.6335 40.2431 39.3135 37.4414 39.4144
7 2.8740 3.1064 3.2223 41.8224 35.8002 40.2321 44.0976 37.2912
8 2.7540 2.7750 2.7007 35.0385 36.6091 37.7748 37.6190 30.9096
9 2.1504 2.1932 2.1512 21.9464 21.4119 24.2723 23.7545 24.7718
10 2.5351 2.5668 2.5857 31.5298 27.7413 28.5853 28.1564 31.1019
kids2009 rent2002 rent2005 rent2008 rentpct02 rentpct05 rentpct08 pubast90
1 40.3169 800 900 1000 21.1119 24.8073 28.5344 47.32913
2 37.8176 650 800 950 32.3615 27.2584 27.9567 35.18232
3 35.3880 750 775 800 23.0547 20.4146 18.1590 23.89404
4 17.9996 1000 1100 1400 25.6022 26.7685 28.0467 80.53393
5 26.2156 1000 1000 1400 18.8079 22.6752 21.3009 75.51687
6 39.0377 910 1000 1100 34.0156 34.8050 27.1032 66.64228
7 43.3207 896 1001 1300 26.7381 34.3842 28.8255 77.53080
8 35.4524 800 900 1100 41.2035 40.6256 36.2956 59.01702
9 21.9552 1000 1035 1400 11.9766 10.4943 11.5520 64.16213
10 28.3184 1000 1100 1200 23.9394 23.3487 22.6715 53.62965
pubast00 yrhom02 yrhom05 yrhom08 geometry
1 6.005791 10.80507 12.127853 11.54743 MULTIPOLYGON (((962498.9 17...
2 2.287034 15.24125 15.183111 14.68212 MULTIPOLYGON (((928296.9 16...
3 1.350208 12.70425 12.972280 13.56149 MULTIPOLYGON (((932416.3 14...
4 5.204510 12.83917 13.377513 12.54464 MULTIPOLYGON (((1010873 226...
5 2.974139 15.38766 12.518789 12.66691 MULTIPOLYGON (((1011647 216...
6 5.332569 12.64923 12.580355 11.96598 MULTIPOLYGON (((1014790 220...
7 6.029230 11.55498 9.828084 10.73805 MULTIPOLYGON (((1018353 205...
8 3.951290 13.49841 12.616178 11.19165 MULTIPOLYGON (((1013477 206...
9 3.111417 13.40156 13.375477 12.74230 MULTIPOLYGON (((1026974 207...
10 2.795721 14.01126 12.806067 12.84800 MULTIPOLYGON (((1034251 230...
56 / 56

Choropleth maps with sf and tmap: NYC examples

## categorize hispanic pop levels
labels <- c("Low hisp pop",
"Mid hisp pop",
"High hisp pop")
nyc_shp %>%
mutate(forhis08_cat =
cut(forhis08,
breaks = 3,
labels = labels))
Simple feature collection with 55 features and 35 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 913037.2 ymin: 120117 xmax: 1067549 ymax: 272751.4
Projected CRS: NAD83 / New York Long Island (ftUS)
First 10 features:
bor_subb name code subborough forhis06
1 501 North Shore 501 North Shore 37.0657
2 502 Mid-Island 502 Mid-Island 27.9822
3 503 South Shore 503 South Shore 10.7019
4 401 Astoria 401 Astoria 52.0961
5 402 Sunnyside / Woodside 402 Sunnyside/Woodside 62.7242
6 403 Jackson Heights 403 Jackson Heights 68.4834
7 404 Elmhurst / Corona 404 Elmhurst/Corona 69.5219
8 405 Middle Village / Ridgewood 405 Middle Village/Ridgewood 39.4185
9 406 Forest Hills / Rego Park 406 Rego Park/Forest Hills 58.5388
10 407 Flushing / Whitestone 407 Flushing/Whitestone 59.4432
forhis07 forhis08 forhis09 forwh06 forwh07 forwh08 forwh09 hhsiz1990 hhsiz00
1 34.0317 27.3767 29.3091 13.2540 11.8768 11.1788 11.1459 2.7146 2.7338
2 18.1193 24.0452 31.1566 20.0616 19.8575 22.4870 17.0371 2.8233 2.7176
3 12.1404 9.6890 14.6638 10.3060 12.7699 9.3561 10.2830 3.0547 2.8497
4 53.9585 54.6968 47.8050 38.3658 35.6551 32.1289 34.6578 2.4279 2.4995
5 69.3969 67.0897 58.2963 37.0512 31.9057 32.3264 33.8794 2.4646 2.6287
6 68.5405 66.5080 69.1580 34.3999 38.2428 38.1470 26.5347 2.8081 3.1650
7 66.8795 69.3414 64.3005 40.3935 51.6376 45.9578 48.3542 2.9690 3.1784
8 35.9546 36.2750 35.0181 37.8097 34.0156 33.0695 33.0816 2.5174 2.6606
9 52.6183 42.3878 47.9795 43.7395 47.5873 45.1205 39.8293 2.0631 2.1532
10 53.4747 53.2531 57.9868 26.5802 25.6864 21.3858 23.5204 2.6302 2.6818
hhsiz02 hhsiz05 hhsiz08 kids2000 kids2005 kids2006 kids2007 kids2008
1 2.7412 2.8010 2.6983 39.2995 43.3788 38.4022 41.5213 39.8390
2 2.5405 2.6228 2.5749 36.2234 35.7630 36.9081 37.6798 37.2447
3 2.6525 2.6121 2.6483 39.7362 42.5232 40.3577 40.3797 40.4820
4 2.3032 2.3227 2.2746 28.4592 27.2223 25.2556 24.8911 22.0364
5 2.5300 2.4993 2.4766 29.8808 28.6841 28.1440 26.3675 29.9032
6 2.9108 2.8599 2.8604 41.6335 40.2431 39.3135 37.4414 39.4144
7 2.8740 3.1064 3.2223 41.8224 35.8002 40.2321 44.0976 37.2912
8 2.7540 2.7750 2.7007 35.0385 36.6091 37.7748 37.6190 30.9096
9 2.1504 2.1932 2.1512 21.9464 21.4119 24.2723 23.7545 24.7718
10 2.5351 2.5668 2.5857 31.5298 27.7413 28.5853 28.1564 31.1019
kids2009 rent2002 rent2005 rent2008 rentpct02 rentpct05 rentpct08 pubast90
1 40.3169 800 900 1000 21.1119 24.8073 28.5344 47.32913
2 37.8176 650 800 950 32.3615 27.2584 27.9567 35.18232
3 35.3880 750 775 800 23.0547 20.4146 18.1590 23.89404
4 17.9996 1000 1100 1400 25.6022 26.7685 28.0467 80.53393
5 26.2156 1000 1000 1400 18.8079 22.6752 21.3009 75.51687
6 39.0377 910 1000 1100 34.0156 34.8050 27.1032 66.64228
7 43.3207 896 1001 1300 26.7381 34.3842 28.8255 77.53080
8 35.4524 800 900 1100 41.2035 40.6256 36.2956 59.01702
9 21.9552 1000 1035 1400 11.9766 10.4943 11.5520 64.16213
10 28.3184 1000 1100 1200 23.9394 23.3487 22.6715 53.62965
pubast00 yrhom02 yrhom05 yrhom08 geometry
1 6.005791 10.80507 12.127853 11.54743 MULTIPOLYGON (((962498.9 17...
2 2.287034 15.24125 15.183111 14.68212 MULTIPOLYGON (((928296.9 16...
3 1.350208 12.70425 12.972280 13.56149 MULTIPOLYGON (((932416.3 14...
4 5.204510 12.83917 13.377513 12.54464 MULTIPOLYGON (((1010873 226...
5 2.974139 15.38766 12.518789 12.66691 MULTIPOLYGON (((1011647 216...
6 5.332569 12.64923 12.580355 11.96598 MULTIPOLYGON (((1014790 220...
7 6.029230 11.55498 9.828084 10.73805 MULTIPOLYGON (((1018353 205...
8 3.951290 13.49841 12.616178 11.19165 MULTIPOLYGON (((1013477 206...
9 3.111417 13.40156 13.375477 12.74230 MULTIPOLYGON (((1026974 207...
10 2.795721 14.01126 12.806067 12.84800 MULTIPOLYGON (((1034251 230...
forhis08_cat
1 Low hisp pop
2 Low hisp pop
3 Low hisp pop
4 High hisp pop
5 High hisp pop
6 High hisp pop
7 High hisp pop
8 Mid hisp pop
9 Mid hisp pop
10 High hisp pop
56 / 56

Choropleth maps with sf and tmap: NYC examples

## categorize hispanic pop levels
labels <- c("Low hisp pop",
"Mid hisp pop",
"High hisp pop")
nyc_shp %>%
mutate(forhis08_cat =
cut(forhis08,
breaks = 3,
labels = labels)) ->
nyc_shp2
56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
frame = FALSE,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
frame = FALSE,
panel.label.bg.color = NA,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
frame = FALSE,
panel.label.bg.color = NA,
frame.lwd = 0,
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
frame = FALSE,
panel.label.bg.color = NA,
frame.lwd = 0,
panel.label.size = 1.5
)

56 / 56

Choropleth maps with sf and tmap: NYC examples

tm_shape(nyc_shp2) + tm_polygons(
col = "rent2008",
palette = "BrBG",
border.col = "white",
title = "Rent in 2008"
) +
tm_facets(
by = "forhis08_cat",
drop.units = TRUE,
free.coords = FALSE,
) +
tm_layout(
legend.outside.size = 0.135,
frame = FALSE,
panel.label.bg.color = NA,
frame.lwd = 0,
panel.label.size = 1.5
) +
tm_shape(nyc_shp2) +
tm_borders(col = "grey75", lty = 2)

56 / 56

Introduction

  • A long rant on space: What do we mean when we say visualizing "spatial data"?
2 / 56
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow