# Copyright 2013 – present by the SalishSeaCast Project contributors
# and The University of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# SPDX-License-Identifier: Apache-2.0
"""Produce image-loop figures showing vertical transects for variables from
the VHFR FVCOM model domain along several thalweg transects.
Testing notebook for this module is
`https://nbviewer.org/github/SalishSeaCast/SalishSeaNowcast/blob/main/notebooks/figures/fvcom/research/TestThalwegTransect.ipynb`
"""
from types import SimpleNamespace
import cmocean
import matplotlib.pyplot as plt
import numpy
from OPPTools.utils import fvcom_postprocess as fpp
import nowcast.figures.website_theme
def _prep_fig_axes(figsize, theme):
fig = plt.figure(figsize=figsize, facecolor=theme.COLOURS["figure"]["facecolor"])
ax = fig.add_subplot(1, 1, 1)
ax.set_facecolor(theme.COLOURS["axes"]["background"])
return fig, ax
def _prep_plot_data(place, fvcom_results_dataset, time_index, varname):
# Get time stamp from results dataset
date_bytes = fvcom_results_dataset.variables["Times"][time_index, :]
date_str = date_bytes.data.tostring().decode("utf-8")
date = date_str[0:10] + " " + date_str[11:19] + " UTC"
# Load the rest of the arrays needed
x = fvcom_results_dataset["x"][:]
y = fvcom_results_dataset["y"][:]
h = fvcom_results_dataset["h"][:]
tri = fvcom_results_dataset["nv"][...].T - 1 # 3-column, zero-based
siglay = fvcom_results_dataset["siglay"][:]
siglev = fvcom_results_dataset["siglev"][:]
# fmt: off
if place == "Vancouver Harbour":
xt = [488231.735, 489164.600, 489791.471, 492539.541, 494090.738,
496814.042, 497666.143, 498271.520, 498919.346, 499575.585,
500341.197, 501288.236, 502974.669, 504338.308]
yt = [5462843.199, 5462728.295, 5462608.950, 5460732.559, 5460268.553,
5460372.070, 5460170.150, 5460240.891, 5460271.740, 5460181.998,
5460330.633, 5460651.256, 5460316.877, 5460870.514]
clim = {'salinity':(24, 30), "temp": (5, 10), 'tangential velocity': (-3, 3)}
if place == "Port Moody":
xt = [504338.308, 505350.106, 505994.245, 506911.296, 507681.396,
508673.051, 509396.596, 510689.110]
yt = [5460870.514, 5460186.615, 5459860.430, 5459857.626, 5460230.616,
5460350.709, 5460123.549, 5459285.152]
clim = {'salinity':(22, 27), "temp": (5, 9), 'tangential velocity': (-0.5, 0.5)}
if place == "Indian Arm":
xt = [504338.308, 504614.340, 505299.179, 506644.379, 507388.050,
508500.265, 508722.376, 509146.408, 508948.526, 510248.889,
509733.686, 509069.678, 508427.574]
yt = [5460870.514, 5462694.832, 5464229.277, 5465152.303, 5466614.650,
5468046.238, 5468964.879, 5469615.060, 5472405.130, 5475485.044,
5477079.703, 5478077.966, 5479284.985]
clim = {'salinity':(24, 29), "temp": (5.5, 9), 'tangential velocity': (-0.75, 0.75)}
# fmt: on
xt, yt = numpy.array(xt), numpy.array(yt)
vmin, vmax = clim[varname]
# Calculate transect
tr = fpp.vertical_transect(xt, yt, x, y, tri, h, siglay, siglev)
# Interpolate variable onto transect
xx, zz, vi, _, __, ___ = fpp.vertical_transect_snap(
fvcom_results_dataset, time_index, varname, tr
)
if varname == "salinity":
longname, units, cmap = "Salinity", "psu", cmocean.cm.haline
if varname == "temp":
longname, units, cmap = "Temperature", "Degrees C", cmocean.cm.thermal
if varname == "tangential velocity":
longname, units, cmap = "Tangential Velocity", "m/s", cmocean.cm.balance
return SimpleNamespace(
xx=xx,
zz=zz,
vi=vi,
varname=varname,
longname=longname,
units=units,
cmap=cmap,
vmin=vmin,
vmax=vmax,
place=place,
date=date,
)
def _plot_thalweg(ax, plot_data, theme):
# use continuous colormap with pcolormesh
hp = ax.pcolormesh(
plot_data.xx,
plot_data.zz,
plot_data.vi,
shading="gouraud",
vmin=plot_data.vmin,
vmax=plot_data.vmax,
cmap=plot_data.cmap,
)
cbar = plt.colorbar(hp)
if plot_data.place == "Vancouver Harbour":
xlim, ylim = [0, 17000], [-65, 5]
if plot_data.place == "Port Moody":
xlim, ylim = [0, 7000], [-25, 5]
if plot_data.place == "Indian Arm":
xlim, ylim = [0, 22000], [-160, 5]
ax.set_xlim(xlim)
ax.set_ylim(ylim)
return cbar
def _set_axes_labels(ax, cbar, plot_data, theme):
ax.set_title(
f"{plot_data.place} {plot_data.longname} {plot_data.date}",
fontproperties=theme.FONTS["axes title"],
color=theme.COLOURS["text"]["axes title"],
)
ax.set_xlabel(
"Distance (m)",
fontproperties=theme.FONTS["axis"],
color=theme.COLOURS["text"]["axis"],
)
ax.set_ylabel(
"Depth (m)",
fontproperties=theme.FONTS["axis"],
color=theme.COLOURS["text"]["axis"],
)
theme.set_axis_colors(ax)
cbar.ax.axes.tick_params(labelcolor=theme.COLOURS["cbar"]["tick labels"])
cbar.set_label(
f"{plot_data.longname} ({plot_data.units})",
fontproperties=theme.FONTS["axis"],
color=theme.COLOURS["text"]["axis"],
)