Introduction
The aim of this mini project is make some fun cartograms of Puerto Rico!
library(tidyverse)
library(broom)
library(sf)
library(ggthemes)
library(ggplot2)
library(cartogram)
library(tweenr)
library(gganimate)
library(sp)
Loading data
The first dataset I am using is Geodata regarding Puerto Rico. This data was very hard to find.
districts <- st_read("map.json") # load as sf object
## Reading layer `map' from data source
## `C:\Users\jodyh\Desktop\islands_projects\pr_pop\map.json' using driver `GeoJSON'
## Simple feature collection with 78 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -67.95181 ymin: 17.88264 xmax: -64.99986 ymax: 18.51597
## Geodetic CRS: WGS 84
Next is loading the population data
population <- read.csv("data.csv") %>% as_tibble() # load as tibble for binding
Now I have to prepare the data and calculate the cartogram
toplot_base <- left_join(districts, population, by = c("id_1" = "id")) %>%
st_transform(crs = 3857) # load with a mercator project
toplot_base$X2019 <- as.double(toplot_base$X2019) # make sure is a number
toplot2019 <- toplot_base %>% select(c("id",
"X2019",
"geometry"))
toplot_plain <- toplot_base %>% select(c("id",
"X2019",
"geometry"))
toplot_end <- toplot_plain # create the frames
toplot_plain$frame <- "a"
toplot2019$frame <- "b"
toplot_end$frame <- "c" # give the frames identities
toplot2019 <- toplot2019 %>% cartogram_cont(weight = "X2019") # calculate
data <- rbind(toplot_plain, toplot2019, toplot_end)
Making Plots
Now I make the plots, one static, one animated
ggplot(toplot2019, aes(fill = X2019)) + # load data into plot
geom_sf(size = 0) + # remove borders
theme_void() +
scale_fill_viridis_b(option = "B", # format scale and legend
breaks = c(50000, 100000, 150000, 200000),
labels = c("50000", "100000", "150000", "200000"),
guide = guide_legend(title = "Population",
keyheight = unit(3, units = "mm"),
keywidth=unit(12, units = "mm"),
label.position = "bottom",
title.position = 'top', nrow=1)) +
theme(
legend.position = "bottom", # put key at the bottom
plot.background = element_rect(fill = "#D2D2CF", color = NA),
panel.background = element_rect(fill = "#D2D2CF", color = NA),
legend.background = element_rect(fill = "#D2D2CF", color = NA),
) +
coord_sf()
Now I make the animated plot using gganimate
p <- ggplot(data, aes(fill = X2019)) +
geom_sf(size = 0) + # remove borders
theme_void() +
scale_fill_viridis_b(option = "B", # format scale and legend
breaks = c(50000, 100000, 150000, 200000),
labels = c("50000", "100000", "150000", "200000"),
guide = guide_legend(title = "Population",
keyheight = unit(3, units = "mm"),
keywidth=unit(12, units = "mm"),
label.position = "bottom",
title.position = 'top', nrow=1)) +
theme(legend.position = "bottom", # put key at the bottom
plot.background = element_rect(fill = "#D2D2CF", color = NA),
panel.background = element_rect(fill = "#D2D2CF", color = NA),
legend.background = element_rect(fill = "#D2D2CF", color = NA)) +
coord_sf() +
transition_states(frame,
transition_length = 2,
state_length = 1) + # code frames
ease_aes('sine-in-out')
anim_save(animation = p,
"cart.gif",
renderer = gifski_renderer(),
res = 1080,
width = 3,
height = 2,
units = "in") # save as gif