--- title: "Tracing Encounters: Orcas in the Salish Sea" author: "Aditya Dahiya" date: "2024-10-16" subtitle: "Mapping the paths of Southern Resident killer whale encounters highlights their concentrated movements within key areas of the Salish Sea." categories: - "#TidyTuesday" - "Maps" - "{ggmap}" image: "thumbnails/tidy_orcas_encounters.png" format: html: code-fold: true editor_options: chunk_output_type: console execute: error: false message: false warning: false eval: false filters: - social-share share: permalink: "https://aditya-dahiya.github.io/projects_presentations/data_vizs.html" twitter: true linkedin: true email: true mastodon: true bibliography: references.bib comments: giscus: repo: Aditya-Dahiya/projects_presentations --- This week's Tidy Tuesday dataset comes from the Center for Whale Research (CWR), which monitors Southern Resident killer whales in the Salish Sea, part of the Pacific Northwest. The dataset, scraped by [Jadey Ryan](https://github.com/jadeynryan) and documented [here](https://jadeynryan.github.io/orcas/), contains information on encounters from 2017 to 2024. Each encounter involves photographing and identifying individual whales. The data can be accessed via the {`orcas`} R package and includes variables like encounter duration, location, and pod. While the dataset is mostly tidy, some inconsistencies such as missing values and negative durations remain. **\|** [Source](https://github.com/jadeynryan/orcas) **\|** [Data](https://github.com/rfordatascience/tidytuesday/blob/master/data/2024/2024-10-15/readme.md) Background raster images for the map were obtained using [StadiaMaps](https://stadiamaps.com/) and the R package [ggmap](https://cran.r-project.org/web/packages/ggmap/) [@ggmap-2] ![This map visualizes the movements of [Southern Resident killer whales](https://en.wikipedia.org/wiki/Southern_resident_orcas), with arrows marking the starting and ending points of each recorded encounter. The concentration of arrows within a small area highlights the key regions in the [Salish Sea](https://en.wikipedia.org/wiki/Salish_Sea) where these encounters occur most frequently. Background map images provided by [StadiaMaps](https://stadiamaps.com/).](tidy_orcas_encounters.png) ### **How I made this graphic?** Loading required libraries, data import & creating custom functions. ```{r} #| label: setup # Data Import and Wrangling Tools library(tidyverse) # All things tidy library(janitor) # Cleaning names etc. library(here) # Root Directory Management library(dataverse) # Getting data from Harvard Dataverse # Final plot tools library(scales) # Nice Scales for ggplot2 library(fontawesome) # Icons display in ggplot2 library(ggtext) # Markdown text support for ggplot2 library(showtext) # Display fonts in ggplot2 library(colorspace) # Lighten and Darken colours library(patchwork) # Combining plots library(ggmap) # To get background map tiles # Option 1: Loading data directly from GitHub orcas <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-10-15/orcas.csv') ``` Visualization Parameters ```{r} #| label: viz-params # Font for titles font_add_google("Lato", family = "title_font" ) # Font for the caption font_add_google("Saira Extra Condensed", family = "caption_font" ) # Font for plot text font_add_google("Oswald", family = "body_font" ) showtext_auto() # Background Colour bg_col <- "white" # Colour for the text text_col <- colorspace::darken("#3d545e", 0.2) # Colour for highlighted text text_hil <- colorspace::darken("#3d545e", 0.2) # Define Base Text Size bts <- 90 # Caption stuff for the plot sysfonts::font_add( family = "Font Awesome 6 Brands", regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf") ) github <- "" github_username <- "aditya-dahiya" xtwitter <- "" xtwitter_username <- "@adityadahiyaias" social_caption_1 <- glue::glue("{github}; {github_username} ") social_caption_2 <- glue::glue("{xtwitter}; {xtwitter_username}") plot_title <- "Tracing Encounters: Orcas in the Salish Sea" plot_caption <- paste0( "**Data:** Center for Whale Research (CWR)", " | **Code:** ", social_caption_1, " | **Graphics:** ", social_caption_2 ) subtitle_text <- "Arrows trace the journey of each encounter with a Southern Resident killer whale, offering a visual exploration of where these whales are most frequently observed. The map shows a dense cluster of sightings, underscoring the importance of specific areas in the Salish Sea." plot_subtitle <- str_wrap(subtitle_text, width = 95) plot_subtitle |> str_view() rm(github, github_username, xtwitter, xtwitter_username, social_caption_1, social_caption_2) ``` Exploratory Data Analysis and Wrangling ```{r} #| label: data-wrangling # summarytools::dfSummary(orcas) |> # summarytools::view() # Manually drop the erratic ids by looking at the map id_to_filter <- c(7, 221, 167, 499, 152, 8, 21, 157, 56, 471, 193, 419, 562) df <- orcas |> # Only keep relevant variables select( duration, begin_latitude, begin_longitude, end_latitude, end_longitude, location ) |> mutate( # remove parenthesis content from duration duration = str_remove(duration, "\\s*\\(.*\\)"), # remove the "s" for seconds duration = str_extract(duration, "-?\\d+"), # convert the duration into number duration = as.numeric(duration) ) |> # remove aberrant durations filter(duration >= 0) |> filter( !( (begin_latitude == end_latitude) & (begin_longitude == end_longitude) ) ) |> mutate( id = row_number() ) |> filter(!(id %in% id_to_filter)) # Data needed to make a Static Graphic with ggmap library(ggmap) # Register your Stadia Maps key stadia_maps_api_key register_stadiamaps(stadia_maps_api_key, write = FALSE) background_tiles_bbox <- c( left = min(c(df$begin_longitude, df$end_longitude), na.rm = T) - 0.2, right = max(c(df$begin_longitude, df$end_longitude), na.rm = T) + 0.2, top = max(c(df$begin_latitude, df$end_latitude), na.rm = T), bottom = min(c(df$begin_latitude, df$end_latitude), na.rm = T) - 0.1 ) background_tiles_bbox <- c( left = min(c(df$begin_longitude, df$end_longitude), na.rm = T) - 0.2, right = -122.2, top = max(c(df$begin_latitude, df$end_latitude), na.rm = T), bottom = min(c(df$begin_latitude, df$end_latitude), na.rm = T) - 0.1 ) stamen_tiles_lowres <- ggmap::get_stadiamap( background_tiles_bbox, zoom = 9, maptype = "stamen_terrain_background" ) # stamen_tiles_10 <- ggmap::get_stadiamap( # background_tiles_bbox, # zoom = 11, # maptype = "stamen_terrain_background" # ) object.size(stamen_tiles_lowres) |> print(units = "Mb") ``` The Base Plot [@ggmap] ```{r} #| label: base-plot g <- ggmap( stamen_tiles_lowres ) + geom_segment( data = df, mapping = aes( x = begin_longitude, y = begin_latitude, xend = end_longitude, yend = end_latitude ), linewidth = 0.5, arrow = arrow( length = unit(2, "mm") ), alpha = 0.7, linetype = 1, colour = "grey20" ) + labs( title = plot_title, subtitle = plot_subtitle, caption = plot_caption ) + ggthemes::theme_map( base_family = "body_font", base_size = bts ) + # Add a north arrow annotation_north_arrow( location = "tl", style = north_arrow_nautical(text_size = bts, text_col = text_col) ) + theme( text = element_text( colour = text_hil, hjust = 0.5, lineheight = 0.3 ), plot.title = element_text( margin = margin(10,0,5,0, "mm"), hjust = 0.5, size = 2 * bts, face = "bold" ), plot.subtitle = element_text( margin = margin(5,0,5,0, "mm"), hjust = 0.5, size = bts ), plot.caption = element_textbox( margin = margin(0,0,5,0, "mm"), hjust = 0.5, size = 0.5 * bts ), plot.margin = margin(0,5,0,0, "mm"), panel.border = element_blank() ) ``` Add-on maps, insets and annotations ```{r} #| label: insets g_month <- orcas |> mutate( month = month(date, label = TRUE), year = year(date), .keep = "used" ) |> drop_na() |> count(month) |> ggplot( mapping = aes(y = month, x = n, label = n) ) + geom_col( colour = "transparent", fill = alpha(text_col, 0.5), width = 0.75 ) + geom_text( hjust = 0, nudge_x = 2, family = "body_font", colour = text_col, fontface = "bold", size = bts / 6 ) + scale_x_continuous( expand = expansion(c(0, 0.05)), breaks = seq(0, 160, 40) ) + coord_cartesian(clip = "off") + labs( title = "Encounters by the Month\n(2017-2024)", y = NULL, x = "Number of Encounters" ) + theme_minimal( base_size = bts / 2, base_family = "body_font" ) + theme( panel.grid = element_blank(), panel.grid.major.x = element_line( colour = alpha(text_col, 0.5), linetype = 1, linewidth = 0.5 ), text = element_text( colour = text_col, family = "body_font" ), plot.title = element_text( margin = margin(0,0,0,0, "mm"), lineheight = 0.3 ), axis.text = element_text( margin = margin(0,0,0,0, "mm"), colour = text_col ), axis.ticks = element_blank(), axis.ticks.length = unit(0, "mm") ) ``` Compiling Plots with `{patchwork}`[@patchwork] ```{r} #| label: patchwork g_full <- g + # Add inset to the plot inset_element( p = g_month, left = 0, right = 0.2, bottom = 0, top = 0.5, align_to = "panel" ) + # Basix Plot Annotations plot_annotation( theme = theme( plot.background = element_rect( fill = "transparent", colour = "transparent", linewidth = 0 ), panel.background = element_rect( fill = "transparent", colour = "transparent", linewidth = 0 ) ) ) ggsave( filename = here::here("data_vizs", "tidy_orcas_encounters.png"), plot = g_full, width = 400, height = 400, units = "mm", bg = "#99b3cc" ) ``` Savings the graphics ```{r} #| label: save-image # Saving a thumbnail library(magick) # Saving a thumbnail for the webpage image_read(here::here("data_vizs", "tidy_orcas_encounters.png")) |> image_resize(geometry = "400") |> image_write( here::here( "data_vizs", "thumbnails", "tidy_orcas_encounters.png" ) ) ``` Session Info ```{r} #| label: tbl-session-info #| tbl-cap: "R Packages and their versions used in the creation of this page and graphics" #| eval: true # Data Import and Wrangling Tools library(tidyverse) # All things tidy library(here) # Root Directory Management # Final plot tools library(scales) # Nice Scales for ggplot2 library(fontawesome) # Icons display in ggplot2 library(ggtext) # Markdown text support for ggplot2 library(showtext) # Display fonts in ggplot2 library(colorspace) # Lighten and Darken colours library(patchwork) # Combining plots library(ggmap) # To get background map tiles sessioninfo::session_info()$packages |> as_tibble() |> select(package, version = loadedversion, date, source) |> arrange(package) |> janitor::clean_names( case = "title" ) |> gt::gt() |> gt::opt_interactive( use_search = TRUE ) |> gtExtras::gt_theme_espn() ```