6 GLORYS Gridded Sea Bottom Temperature
Data Type: Gridded Data
Spatial Scope: Northwest Atlantic
Duration: 2020-2025
Source: CMEMS Global Ocean Physics Reanalysis
6.1 Introduction to Indicator
The GLORYS12V1 dataset is a product of the Copernicus Marine Environment Monitoring Service (CMEMS), providing spatiotemporal modeled estimates of environmental data for global oceans at 1/12° horizontal resolution and 50 vertical levels (Copernicus Marine Service 2023). Here, we use the bottom temperature estimate for the Northwest Atlantic, encompassing the Scotian Shelf region.
GLORYS bottom temperature estimates are generated using a numerical ocean model with assimilated satellite and in-situ observations, but see Chapter 5 for summarized empirical temperature measurements.
6.2 View Data
library(terra)
library(plotly)
# prepare sf shapes as coordinates
# NAFO regions
#sf <- readRDS("data/derived_data/azmp_area.rds") %>%
# filter(area %in% c("4X","4Vn","4Vs","4W")) %>%
# inner_join(global_cols2 %>% rename("area" = "region"))
#sf <- sf %>% st_transform(crs = crs(r_stack))
#sf_coords <- st_coordinates(st_cast(sf, "MULTILINESTRING") ) %>%
# as.data.frame() %>%
# split(.,f = .$L2) %>%
# purrr::map(.x = .,
# .f = ~.x %>% rbind(c(NA,NA,NA,NA)))
#
sf <- readRDS("data/derived_data/nafo_regions_correct.rds") %>%
filter(region %in% c("4X","4Vn","4Vs","4W")) %>%
inner_join(global_cols2) %>%
rename(area = region)
sf <- sf %>% st_buffer(-.05)
sf <- sf %>% st_transform(crs = crs(r_stack))
# add NA after multipolygons so that plotly draws lines correctly
sf_coords <- st_coordinates(st_cast(sf, "MULTILINESTRING") ) %>%
as.data.frame() %>%
split(.,f = interaction(.$L2,.$L1), drop = T) %>%
purrr::map(.x = .,
.f = ~.x %>% rbind(c(NA,NA,NA,NA)))
# bind back together by region
name_ids <- sub("\\..*$", "", names(sf_coords))
grouped <- split(sf_coords, name_ids)
grouped <- purrr::map(.x = grouped,
.f = ~.x %>% bind_rows)
data("coastline")
coast_coords <- st_coordinates(coastline) %>%
as.data.frame() %>%
split(.,f = interaction(.$L1,.$L2,.$L3, drop = T)) %>%
purrr::map(.x = .,
.f = ~.x %>% rbind(c(NA,NA,NA,NA,NA))) %>%
bind_rows()
times <- names(r_stack)
# consistent color scale
zmin <- range(values(r_stack), na.rm = TRUE)[1]
zmax <- range(values(r_stack), na.rm = TRUE)[2]
x_vals <- xFromCol(r_stack, 1:ncol(r_stack))
y_vals <- yFromRow(r_stack, 1:nrow(r_stack))
ext <- ext(r_stack)
# Base plot
p <- plot_ly(
x = x_vals, y = y_vals,
z =as.matrix(r_stack[[1]], wide = TRUE),
type = "heatmap",
colorscale = "YlGnBu",
hoverinfo = "none",
colorbar = list(title = "Bottom<br>Temperature<br>(°C)"),
zmin = zmin, zmax = zmax,
showscale = TRUE
)
# add polygons
p <- p %>%
add_polygons(
x = coast_coords[,1],
y = coast_coords[,2],
fillcolor = "#dcdedc",
showlegend = F,
line = list(color = "black", width= .2),
hoverinfo = "none",
inherit = FALSE
) %>%
add_paths(x = grouped[[1]][,1],
y = grouped[[1]][,2],
line = list(color = unique(sf$color[1]),
width = 3),
hoverinfo = "none",
inherit = F,
name = unique(sf$area[1])) %>%
add_paths(x = grouped[[2]][,1],
y = grouped[[2]][,2],
line = list(color = unique(sf$color[2]),
width = 3),
hoverinfo = "none",
inherit = F,
name = unique(sf$area[2])) %>%
add_paths(x = grouped[[3]][,1],
y = grouped[[3]][,2],
line = list(color = unique(sf$color[3]),
width = 3),
hoverinfo = "none",
inherit = F,
name = unique(sf$area[3])) %>%
add_paths(x = grouped[[4]][,1],
y = grouped[[4]][,2],
line = list(color = unique(sf$color[4]),
width = 3),
hoverinfo = "none",
inherit = F,
name = unique(sf$area[4]))
# loop through raster layers to make frames
frames <- purrr::map(
.x = c(1:nlyr(r_stack)),
.f = ~list(
name = times[.x],
data = list(list(
z = as.matrix(r_stack[[.x]], wide = TRUE),
type = "heatmap",
zmin = zmin,
zmax = zmax,
hoverinfo = "none"
))
)
)
# add frames to map
p$x$frames <- frames
# make animation list
steps <- purrr::map(
.x = c(1:nlyr(r_stack)),
.f = ~list(
method = "animate",
label = times[.x],
args = list(
list(times[.x]),
list(
mode = "immediate",
frame = list(duration = 0, redraw = T),
transition = list(duration = 0)
)
)
)
)
# Slider steps (scrub)
steps <- lapply(seq_along(times), function(i) {
list(
method = "animate",
label = times[i],
args = list(
list(times[i]),
list(
mode = "immediate",
frame = list(duration = 0, redraw = TRUE),
transition = list(duration = 0)
)
)
)
})
# Layout + aspect lock + slider + play/pause
p <- p %>%
layout(
xaxis = list(
title = "",
showgrid = FALSE, zeroline = FALSE,
range = c(xmin(ext), xmax(ext)),
constrain = "domain"
),
yaxis = list(
title = "",
showgrid = FALSE, zeroline = FALSE,
range = c(ymin(ext), ymax(ext)),
scaleanchor = "x",
scaleratio = 1.5
),
margin = list(l = 0, r = 0, t = 50, b = 70),
sliders = list(list(
active = 0,
y = -.05,
currentvalue = list(prefix = "Time: "),
pad = list(t = 10),
steps = steps
)),
updatemenus = list(list(
type = "buttons",
direction = "left",
x = 0.02, y = 1.15,
xanchor = "left", yanchor = "top",
pad = list(r = 10, t = 0),
buttons = list(
# PLAY: explicitly animate through *all frame names*
list(
label = "Play",
method = "animate",
args = list(
as.list(times),
list(
mode = "immediate",
fromcurrent = TRUE,
frame = list(duration = 250, redraw = TRUE),
transition = list(duration = 0)
)
)
),
# PAUSE
list(
label = "Pause",
method = "animate",
args = list(
list(NULL),
list(
mode = "immediate",
frame = list(duration = 0, redraw = FALSE),
transition = list(duration = 0)
)
)
)
)
))
)
p %>% config(displayModeBar = F)