# 11 Day 9: Yellow

## 11.1 Technologies/Techniques

• R Simple Features `{sf}`
• Generating your own data to put on a map
• Using `{rnaturalearth}` basemaps
• Using `{ggplot2}` `geom_sf()` to draw a basemap, `geom_path()` to draw lines and `geom_ribbon()` to make filled polygons
• Making animations with `{magick}`

## 11.2 Data Source: Solar Terminator

The line on the surface of our planet that separates day and night is called the “terminator” and for today’s challenge I decided to create an animation of this line as it moves across the Earth. To do this, we need to compute the terminator for each hour.

Joe Gallagher43 made an initial R script44 to compute the terminator. I riffed off of this and made an Rcpp-based `{terminator}` package45 that dramatically speeds up the calculations and makes the function easier to use since it’s in a package.

``````library(sf)
library(magick)
library(terminator)
library(rnaturalearth)
library(hrbrthemes)
library(tidyverse)``````

To see what the `terminator()` function does before making the final map, we’ll compute one terminator line for midday (GMT) and place it on a map:

``````ne_countries(scale = "medium", returnclass = "sf") %>%
filter(name != "Antarctica") -> world

ggplot() +
geom_sf(data = world, size = 0.125) +
geom_path(
data = terminator(as.integer((as.POSIXct(Sys.Date()) + (60*60*12))), -180, 180, 0.1),
aes(lon, lat), size = 2
) +
coord_sf(crs="+proj=longlat") +
labs(x = NULL, y = NULL) +
theme_minimal()``````

Note the use of `geom_path()` which forced us to re-project the `world` back to plain ol’ `longlat` in order to avoid messing with the unprojected longitude/latitude pairs from `terminator()`

## 11.3 Building Projected Terminators

We’ll use a different projection — cylindrical equal-earth46 – this time just to mix things up a bit and also write a helper function to obtain pre-projected longitude/latitude points for our terminator lines:

``````# cylindrical equal-earth projection
proj <- "+proj=cea +lat_ts=37.5 +ellps=WGS84 +datum=WGS84 +units=m +no_defs +towgs84=0,0,0"

get_terms <- function(i) { # i is the hour of the day (GMT)

terminator(as.integer((as.POSIXct(Sys.Date()) + (60*60*(i)))), -180, 180, 0.1) %>% # get a data frame of points
st_as_sf(coords = c("lon", "lat"), crs = 4326, agr = "constant") %>% # make an {sf} object
st_transform(crs = proj) %>% # project the points
st_coordinates() %>% # get the coordinates back
as_tibble() %>% # turn it back into a data frame
set_names(c("lng", "lat"))

}``````

Rather than build complete polygons, we’ll cheat a bit and use `geom_ribbon()` to do that for us. The `lat` value of our line gives us the top (`ymax`) of the ribbon, so we just need to know the value for the bottom, which we can either look-up or compute:

``````st_as_sf(tibble(lon = 0, lat = -90), coords = c("lon", "lat"), crs = 4326, agr = "constant") %>%
st_transform(crs = proj) %>%
st_coordinates() %>%
.[,2] -> bottom

bottom
## [1] -8011546``````

## 11.4 Drawing the Terminator Map (Part 1)

Let’s re-draw the GMT midday terminator map with a yellow ribbon:

``````  ggplot() +
geom_sf(data = world, size = 0.125, fill = "#3B454A", color = "#b2b2b2") +
geom_ribbon(
data = get_terms(12), aes(lng, ymin = bottom, ymax = lat),
fill = "#f9d71c", alpha = 1/6
) +
coord_sf(crs = proj) +
labs(
x = NULL, y = NULL, title = sprintf("%02d:00", 12),
caption = "Data source: {terminator} • #30DayMapChallenge"
) +
theme_ft_rc(grid = "XY") +
theme(plot.title = element_text(hjust = 0.5))``````

## 11.5 Drawing the Terminator Map (Part 2)

Now, we just follow the familiar-by-now `{magick}` animation idiom:"

``````img <- image_graph(width=1000*2, height=500*2, res=96)

pb <- progress_estimated(24)

for (i in 0:23) {

pb\$tick()\$print()

ggplot() +
geom_sf(data = world, size = 0.125, fill = "#3B454A", color = "#b2b2b2") +
geom_ribbon(
data = get_terms(i), aes(lng, ymin = bottom, ymax = lat),
fill = "#f9d71c", alpha = 1/6
) +
coord_sf(crs = proj) +
labs(
x = NULL, y = NULL, title = sprintf("%02d:00", i),
caption = "Data source: {terminator}\n<git.rud.is/hrbrmstr/y2019-30daymapchallenge> • #30DayMapChallenge"
) +
theme_ft_rc(grid = "XY") +
theme(plot.title = element_text(hjust = 0.5)) -> gg

print(gg)

}

dev.off()

img <- image_animate(img)

image_write(img, here::here("img/terminus.gif"))``````

## 11.6 In Review

We mixed things up a bit and made our own data for this challenge along with trying out a new map projection. We also did some data frame to `{sf}` coordinate machinations in order to use our new projection.

## 11.7 Try This At Home

Flip the idiom (along with the basemap colors) and map night vs day.

Make `{sf}` polygons vs lines and plot the terminator on a `{mapdeck}` interactive map.