A record of recreational and scientific diving, usually on shipwrecks.
I’m a qualified Commercial and Technical Diver (ADAS P1, TDI ANDP). I have been doing scientific diving since 2017, and I am comfortable working in challenging conditions including very low visibility (<1m) and breaking swell. I specialise in underwater photogrammetry for archaeological recording, much of which I have done with the WA Museum.
Below is my dive log. The data behind this post is available for download here. Please note some coordinates are slightly obfuscated, they are indicative only. Last updated January 2025.
library(tidyverse)
library(patchwork)
library(leaflet)
library(sf)
library(gt)
library(DT)
theme_set(theme_minimal())
dive_log <- read_csv("portfolio/dive_log.csv") %>%
mutate(across(c(
category, entry, group, nitrox, night, water),
as_factor))
dive_log %>% mutate(depth_bins = cut(depth,
breaks=c(0,10,20,30, 40),
labels=c('< 10m', '10-20m',
'20-30m', '30-40m'))) %>%
group_by("depth range" = depth_bins) %>%
summarise(dives = n(),
hours = round(sum(duration)/60,1)) %>%
pivot_longer(-`depth range`, names_to = 'depth') %>%
pivot_wider(names_from = `depth range`) %>%
gt() %>% tab_options(table.width = pct(100)) %>%
fmt_number(
columns = 2:5,
rows = 1,
decimals = 0
) %>%
tab_caption(
glue::glue(
"{nrow(dive_log)} dives over {round(sum(dive_log$duration)/60,0)} hours. ",
"{sum(!is.na(dive_log$nitrox), na.rm = TRUE)} on nitrox, ",
"and {sum(!is.na(dive_log$night), na.rm = TRUE)} at night. ",
"Deepest to {max(dive_log$depth, na.rm = TRUE)} m."
)
)
depth | < 10m | 10-20m | 20-30m | 30-40m |
---|---|---|---|---|
dives | 152 | 122 | 52 | 11 |
hours | 99.3 | 83.4 | 32.8 | 6.4 |
depth_hist <- ggplot(dive_log) +
geom_histogram(aes(depth), binwidth = 1,
fill = "#48497F", alpha = 0.9) +
geom_vline(xintercept = 18, lty=2) +
labs(
title = paste0(nrow(dive_log),
" dives since 2015"),
subtitle = paste0(sum(dive_log$depth > 18),
' dives deeper than 18m'))
time_hist <- ggplot(dive_log) +
geom_histogram(aes(duration), binwidth = 5,
fill = "#48497F", alpha = 0.9) +
geom_vline(xintercept = mean(dive_log$duration), lty=2) +
labs(
title = paste0(round(sum(dive_log$duration)/60),
" hours underwater"),
subtitle = paste0("mean dive time is ",
round(mean(dive_log$duration)), ' mins'))
depth_hist + time_hist
map_labels <- paste0(dive_log$date, " ", dive_log$name)
dive_log %>%
st_as_sf(coords=c('lon', 'lat')) %>%
leaflet(options=leafletOptions(
minZoom = 3,
maxZoom = 10,
)) %>%
setView(lng = 115, lat = -26, zoom = 4) %>%
addProviderTiles(provider = providers$CartoDB.Voyager) %>%
addCircleMarkers(radius = 7, label = map_labels,
stroke = FALSE, fillOpacity = .7,
clusterOptions = markerClusterOptions(
maxClusterRadius=30,
spiderfyDistanceMultiplier=1.2))