Lucinda Roberts | March, 2024

Prepared in partial fulfillment of the requirements of GEOG 590: R for Earth System Science

1 Project Summary

1.1 R in Cartography

As a cartographer, I am often asked to break down complicated data stories into easily digestible information. Sometimes, this means I use visual communication to spatialize or depict qualitative stories. This is where the majority of my traditional cartography has focused. However, being an effective cartographer and spatial storyteller involves being competent at handling, cleaning, and distilling large datasets into digestible stories.

There are many toolboxes in R which allow for advanced cartographic visualizations. The Rayshader package, for example, is an opensource pachage that uses raytracing and hillshading algorithms to create stunning 2D and 3D maps. In the video linked below, Kati Perry, a cartographer at the Washington Post and UO Alumn, talks through how she used R to programmatically create a series of maps for the Associated Press showing Arctic ice loss over time.

NACIS video

1.2 Trade Project

My motivation behind this work is a project I have been developing for the last 3 years in collaboration with the InfoGraphics Lab and 2 economics professors– Dr. Woan Foong Wong and Dean of the Lundquist School of Business Bruce Blonigen. Drs. Wong and Blonigen have an NSF grant to research how the invention of the steam engine changed the relative importance of global cities to international trade. So, I have been working with Joanna Merson in the InfoGraphics Lab to create a heuristic model of global historic sailing routes in the early 1850s. Previous researchers have created similar models, but none were geographers, so they failed to accurately accomodate issues such as the earth’s projection or spatial limitations to travel.

1.3 This project

This project was motivated by my attempt to learn R for the first time and guided by my intention of getting more familiar with an update we made to our underlying dataset for the Trade project. The products, then, are less focused on how to perform earth system science using R, but rather trying new techniques for how to communicate earth system science using packages in R. I do not have this communication down quite yet, so these images are not intended to represent scientifically informative graphics, but rather a demonstration of my capabilities as a designer using this programming language.

The goal was to produce an R Markdown file which could be integrated integrated into my portfolio which highlights, not just my skills in R, but how I approach learning new applications. As such, it was important to me that the file not only be reflective of my learning progress, but that it also matches the overall aesthetic of my portfolio. Therefore, I focused on creating a custom cascading style sheet (CSS) file, using a custom font from Google fonts, and making sure the design and layout were easy to read and scan.

2 Methodology

In the sections below, I walk through how I came up with my three iterations on developing a data visualization of wind speed and direction in R.

2.1 Installing Libraries

Below are the libraries I used to install, manipulate, and plot my maps.

library(ncdf4) # For handling Net CDF files
library(sf) # Simple features in R
library(stars)
library(tmap) # Quickly drawing data, including simple datasets
library(rnaturalearth) # Quickly loading data from Natural Earth
library(metR) # Has a cool package for visualizing vectors
library(dplyr) 
library(classInt)
library(lattice)
library(ggplot2) # for plotting data
library(RColorBrewer) # for incorporating cartographically tried-and-true colors

2.2 Opening NetCDF File

The data I used was the ERA5 wind dataset from Copernicus. This is a dataset of atmospheric conditions at a very small temporal and spatial scale, which is incredibly useful for the purposes of our model.

# set path and filename
ncpath <- ".\\Data\\"
ncname <- "Wind_5Dec"  
ncfname <- paste(ncpath, ncname, ".nc", sep="")
dname <- "Wind_Dec"


# open a netCDF file
ncin <- nc_open(ncfname)
print(ncin)
## File .\Data\Wind_5Dec.nc (NC_FORMAT_64BIT):
## 
##      2 variables (excluding dimension variables):
##         short u10[longitude,latitude,time]   
##             scale_factor: 0.000725724893463742
##             add_offset: 1.09752226938921
##             _FillValue: -32767
##             missing_value: -32767
##             units: m s**-1
##             long_name: 10 metre U wind component
##         short v10[longitude,latitude,time]   
##             scale_factor: 0.000684122905143568
##             add_offset: -1.47976558440179
##             _FillValue: -32767
##             missing_value: -32767
##             units: m s**-1
##             long_name: 10 metre V wind component
## 
##      3 dimensions:
##         longitude  Size:1440 
##             units: degrees_east
##             long_name: longitude
##         latitude  Size:721 
##             units: degrees_north
##             long_name: latitude
##         time  Size:3 
##             units: hours since 1900-01-01 00:00:00.0
##             long_name: time
##             calendar: gregorian
## 
##     2 global attributes:
##         Conventions: CF-1.6
##         history: 2024-03-13 10:04:42 GMT by grib_to_netcdf-2.25.1: /opt/ecmwf/mars-client/bin/grib_to_netcdf.bin -S param -o /cache/data9/adaptor.mars.internal-1710324282.5448966-27416-6-d11edc9d-5e9e-4dc0-b32f-9dc14aac69fd.nc /cache/tmp/d11edc9d-5e9e-4dc0-b32f-9dc14aac69fd-adaptor.mars.internal-1710324273.6142778-27416-6-tmp.grib

2.3 Processing UV Data

In a vector, ‘U’ refers to the direction of a vector and ‘V’ refers to its magnitude.This section demonstrates how I pre-process UV data from the netCDF files.

# Read the longitude, latitude, and wind components
longitude <- ncvar_get(ncin, "longitude") -180
latitude <- ncvar_get(ncin, "latitude")
u10 <- ncvar_get(ncin, "u10")
v10 <- ncvar_get(ncin, "v10")


# Create a data frame
wind_data <- data.frame(
  lon = rep(longitude, each = length(latitude)),
  lat = rep(latitude, times = length(longitude)),
  u = as.vector(u10),
  v = as.vector(v10)
)

# Sample data to reduce rendering time
sample_size <- 1500  # Adjust this number to control the density of wind vectors
sample_indices <- sample(nrow(wind_data), sample_size)
sampled_wind_data <- wind_data[sample_indices, ]

2.4 Simple plot

This was my firs