Plot Arctic Ocean Map

This (notebook) demonstrates creating an animation of hourly tidal elevations for the Arctic Ocean

Important

Need to download tide model prior to running this notebook.

OTIS format tidal solutions provided by Oregon State University and ESR

Global Tide Model (GOT) solutions provided by Richard Ray at GSFC

Finite Element Solution (FES) provided by AVISO

Python Dependencies

Program Dependencies

  • astro.py: computes the basic astronomical mean longitudes

  • constituents.py: calculates constituent parameters and nodal arguments

  • io.model.py: retrieves tide model parameters for named tide models

  • io.OTIS.py: extract tidal harmonic constants from OTIS tide models

  • io.ATLAS.py: extract tidal harmonic constants from ATLAS netcdf models

  • io.FES.py: extract tidal harmonic constants from FES tide models

  • io.GOT.py: extract tidal harmonic constants from GOT tide models

  • predict.py: predict tidal values using harmonic constants

  • utilities.py: download and management utilities for files

Note

This notebook uses Jupyter widgets to set parameters for calculating the tidal maps.

Load modules

import numpy as np
import xarray as xr
import matplotlib

matplotlib.rcParams["axes.linewidth"] = 2.0
matplotlib.rcParams["animation.html"] = "jshtml"
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import cartopy.crs as ccrs
from IPython.display import HTML

# import tide programs
import pyTMD.io
import pyTMD.predict
import pyTMD.tools
import pyTMD.utilities
import timescale.time

# autoreload
%load_ext autoreload
%autoreload 2

Set parameters for program

  • Model directory

  • Tide model

  • Date to run

# available model list
model_list = sorted(pyTMD.io.model.ocean_elevation())
# display widgets for setting directory and model
TMDwidgets = pyTMD.tools.widgets()
TMDwidgets.model.options = model_list
TMDwidgets.model.value = "GOT4.10_nc"
TMDwidgets.VBox([TMDwidgets.directory, TMDwidgets.model, TMDwidgets.datepick])

Read tide model

# get model parameters
model = pyTMD.io.model(
    TMDwidgets.directory.value,
).from_database(TMDwidgets.model.value)
# open dataset
ds = model.open_dataset(group="z")

Setup coordinates for calculating tides

# create an image around the Arctic Ocean
# use NSIDC Polar Stereographic definitions
# https://nsidc.org/data/polar-stereo/ps_grids.html
xlimits = [-3850000, 3750000]
ylimits = [-5350000, 5850000]
spacing = [20e3, -20e3]
# x and y coordinates
x = np.arange(xlimits[0], xlimits[1] + spacing[0], spacing[0])
y = np.arange(ylimits[1], ylimits[0] + spacing[1], spacing[1])
xgrid, ygrid = np.meshgrid(x, y)
# x and y dimensions
nx = int((xlimits[1] - xlimits[0]) / spacing[0]) + 1
ny = int((ylimits[0] - ylimits[1]) / spacing[1]) + 1
# create xarray DataArrays for coordinates in crs of model
X, Y = ds.tmd.coords_as(xgrid, ygrid, type="grid", crs=3413)

# convert from calendar date to days relative to Jan 1, 1992 (48622 MJD)
YMD = TMDwidgets.datepick.value
ts = timescale.from_calendar(YMD.year, YMD.month, YMD.day, hour=np.arange(24))
# delta time (TT - UT1)
if model.corrections in ("OTIS", "ATLAS", "TMD3"):
    DELTAT = np.zeros_like(ts.tide)
else:
    DELTAT = ts.tt_ut1

Calculate tide map

# interpolate to grid and convert to centimeters
local = ds.tmd.interp(X, Y)
local = local.tmd.to_units("cm")
# calculate tide elevation map
tide = local.tmd.predict(ts.tide, deltat=DELTAT, corrections=model.corrections)
# infer minor constituents and add to major components
tide += local.tmd.infer(ts.tide, deltat=DELTAT, corrections=model.corrections)

Create animation of hourly tidal oscillation

%matplotlib inline
# output Arctic Ocean Tide Animation
projection = ccrs.Stereographic(
    central_longitude=-45.0, central_latitude=+90.0, true_scale_latitude=+70.0
)
fig, ax = plt.subplots(
    num=1, figsize=(8, 9), subplot_kw=dict(projection=projection)
)
# plot tide height
vmin, vmax = (np.min(tide), np.max(tide))
extent = (xlimits[0], xlimits[1], ylimits[0], ylimits[1])
im = ax.imshow(
    np.zeros((ny, nx)),
    interpolation="nearest",
    vmin=vmin,
    vmax=vmax,
    transform=projection,
    extent=extent,
    origin="upper",
    animated=True,
)
# add moderate resolution cartopy coastlines
ax.coastlines("50m")

# Add colorbar and adjust size
# pad = distance from main plot axis
# extend = add extension triangles to upper and lower bounds
# options: neither, both, min, max
# shrink = percent size of colorbar
# aspect = lengthXwidth aspect of colorbar
cbar = plt.colorbar(
    im,
    ax=ax,
    pad=0.025,
    extend="both",
    extendfrac=0.0375,
    shrink=0.90,
    aspect=25.5,
    drawedges=False,
)
# rasterized colorbar to remove lines
cbar.solids.set_rasterized(True)
# Add label to the colorbar
cbar.ax.set_ylabel(f"{model.name} Tide Height", labelpad=10, fontsize=13)
cbar.ax.set_title("cm", fontsize=13, va="bottom")
# ticks lines all the way across
cbar.ax.tick_params(
    which="both", width=1, length=21, labelsize=13, direction="in"
)
# add title (date and time)
ttl = ax.set_title(None, fontsize=13)
# set x and y limits
ax.set_xlim(xlimits)
ax.set_ylim(ylimits)

# stronger linewidth on frame
ax.spines["geo"].set_linewidth(2.0)
ax.spines["geo"].set_capstyle("projecting")
# adjust subplot within figure
fig.subplots_adjust(left=0.02, right=0.98, bottom=0.05, top=0.95)


# animate each map
def animate_maps(hour):
    # set map data
    im.set_data(tide.values[:, :, hour])
    # set title
    args = (YMD.year, YMD.month, YMD.day, hour)
    ttl.set_text("{0:4d}-{1:02d}-{2:02d}T{3:02d}:00:00".format(*args))


# set animation
anim = animation.FuncAnimation(fig, animate_maps, frames=24)
plt.close()
HTML(anim.to_jshtml())