Plot Solid Earth Tides
This notebook demonstrates creating a global animation of solid Earth tide displacements
Python Dependencies
Program Dependencies
astro.py: computes the basic astronomical mean longitudespredict.py: predict tidal values using harmonic constantsutilities.py: download and management utilities for files
Note
This notebook uses Jupyter widgets to set parameters for calculating the solid Earth tide maps.
Load modules
from __future__ import print_function
import numpy as np
import ipywidgets
import matplotlib
matplotlib.rcParams["axes.linewidth"] = 2.0
matplotlib.rcParams["animation.html"] = "jshtml"
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.animation as animation
import cartopy.crs as ccrs
from IPython.display import HTML
# import tide programs
import pyTMD.compute
import pyTMD.tools
import pyTMD.utilities
import timescale.time
# autoreload
%load_ext autoreload
%autoreload 2
Set parameters for program
# display widgets
TMDwidgets = pyTMD.tools.widgets()
# create dropdown with ephemeride type
TMDwidgets.ephemerides = ipywidgets.Dropdown(
options=["Approximate", "JPL"],
value="JPL",
description="Ephemerides:",
disabled=False,
style=TMDwidgets.style,
)
# create dropdown with permanent tide type
TMDwidgets.tide_system = ipywidgets.Dropdown(
options=["mean_tide", "tide_free"],
value="tide_free",
description="Tide System:",
disabled=False,
style=TMDwidgets.style,
)
TMDwidgets.VBox(
[TMDwidgets.ephemerides, TMDwidgets.tide_system, TMDwidgets.datepick]
)
Setup coordinates for calculating tides
# create a global image
xlimits = [-180, 180]
ylimits = [-90, 90]
spacing = [1.0, 1.0]
# x and y coordinates
x = np.arange(xlimits[0], xlimits[1] + spacing[0], spacing[0])
y = np.arange(ylimits[0], ylimits[1] + spacing[1], spacing[1])
# x and y dimensions
nx = int((xlimits[1] - xlimits[0]) / spacing[0]) + 1
ny = int((ylimits[1] - ylimits[0]) / spacing[1]) + 1
Calculate and plot solid Earth tides
# convert from calendar date to days relative to Jan 1, 1992 (48622 MJD)
YMD = TMDwidgets.datepick.value
# calculate a forecast every hour
hours = np.arange(24)
# convert time from MJD to days relative to Jan 1, 1992 (48622 MJD)
ts = timescale.from_calendar(YMD.year, YMD.month, YMD.day, hour=hours)
nt = len(ts)
# predict solid earth tides
tide_se = pyTMD.compute.SET_displacements(
x,
y,
ts.to_datetime(),
type="grid",
standard="datetime",
ephemerides=TMDwidgets.ephemerides.value,
ellipsoid="WGS84",
tide_system=TMDwidgets.tide_system.value,
)
# convert to centimeters
tide_se = tide_se.tmd.to_units("centimeters")
%matplotlib inline
# cartopy transform for Equirectangular Projection
projection = ccrs.PlateCarree()
# create figure axis
fig, ax = plt.subplots(
num=1, figsize=(5.5, 3.5), subplot_kw=dict(projection=projection)
)
# plot solid earth tide height
norm = colors.CenteredNorm(halfrange=np.max(np.abs(tide_se)))
extent = (xlimits[0], xlimits[1], ylimits[0], ylimits[1])
im = ax.imshow(
np.zeros((ny, nx)),
interpolation="nearest",
norm=norm,
cmap="Spectral",
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,
extend="both",
extendfrac=0.0375,
orientation="horizontal",
pad=0.025,
shrink=0.90,
aspect=22,
drawedges=False,
)
# rasterized colorbar to remove lines
cbar.solids.set_rasterized(True)
# Add label to the colorbar
cbar.ax.set_title(
"Radial Tide Displacement", fontsize=13, rotation=0, y=-2.0, va="top"
)
cbar.ax.set_xlabel("cm", fontsize=13, rotation=0, va="center")
cbar.ax.xaxis.set_label_coords(1.085, 0.5)
# ticks lines all the way across
cbar.ax.tick_params(
which="both", width=1, length=15, labelsize=13, direction="in"
)
# add title (date and time)
ttl = ax.set_title(None, fontsize=13)
# axis = equal
ax.set_aspect("equal", adjustable="box")
# set x and y limits
ax.set_xlim(xlimits)
ax.set_ylim(ylimits)
# no ticks on the x and y axes
ax.get_xaxis().set_ticks([])
ax.get_yaxis().set_ticks([])
# 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.04, right=0.96, bottom=0.05, top=0.96)
# animate each map
def animate_maps(hour):
# set map data
im.set_data(tide_se[:, :, 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())