Dive log

A record of recreational and scientific diving, usually on shipwrecks.

I’m a qualified commercial diver (ADAS Part 1), and I have the PADI Open Water (2015), PADI Advanced Open Water (2016), SDI Nitrox (2017), SDI Deep (2017) and PADI Rescue (2019) diver certifications. I have been doing scientific diving since 2017, and I am comfortable working in challenging conditions including very low visibility (<1m) and strong surge. I specialise in underwater photogrammetry for archaeological recording, much of which I have done with the WA Museum.

Below is an abridged version of my dive log, which I keep in the Day One journaling application, including photos. The data behind this post is available for download here. Last updated November 2024.

Show code
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
  )
depth < 10m 10-20m 20-30m 30-40m
dives 151 115 52 8
hours 99.1 77.8 32.8 4.7
Show code
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

Show code
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))
Show code
dive_log %>% 
  select(date, time, mins = duration,
         depth, place, category, name) %>% 
  mutate(time = substr(time,1,5)) %>% 
datatable(filter = 'top',
          class = 'compact nowrap',
          options = list(scrollX = TRUE,
                         pageLength=25,
  order = list(list(1, 'desc'),list(2, 'desc'))
))