---
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()
```