Skip to content

Commit

Permalink
refactor: using new JSON dictionary format for model projections for #…
Browse files Browse the repository at this point in the history
…333 (#345)

* docs: add notebook with a cotidal chart for #344
  • Loading branch information
tsutterley authored Sep 27, 2024
1 parent 2aa4938 commit 1cb6a4b
Show file tree
Hide file tree
Showing 23 changed files with 1,065 additions and 457 deletions.
8 changes: 8 additions & 0 deletions doc/source/user_guide/Examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The available examples include:
Plots a weekly forecast of tidal displacements at a given location
- Harmonic Constants Solver |github solve| |nbviewer solve|
Solves for the amplitude and phase of harmonic constituents at a given location
- Antarctic Cotidal Chart Mapper |github cotidal| |nbviewer cotidal|
Plot the cotidal charts for selected constituents around Antarctica
- Antarctic Tidal Amplitudes Mapper |github range| |nbviewer range|
Plot the total combined tidal amplitude for all constituents around Antarctica
- Arctic Ocean Tide Mapper |github arctic| |nbviewer arctic|
Expand Down Expand Up @@ -43,6 +45,12 @@ The available examples include:
.. |nbviewer solve| image:: https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg
:target: https://nbviewer.jupyter.org/github/tsutterley/pyTMD/blob/main/notebooks/Solve\ Synthetic\ Tides.ipynb

.. |github cotidal| image:: https://img.shields.io/badge/GitHub-view-6f42c1?style=flat&logo=Github
:target: https://github.com/tsutterley/pyTMD/blob/main/notebooks/Plot\ Antarctic\ Cotidal\ Charts.ipynb

.. |nbviewer cotidal| image:: https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg
:target: https://nbviewer.jupyter.org/github/tsutterley/pyTMD/blob/main/notebooks/Plot\ Antarctic\ Cotidal\ Charts.ipynb

.. |github currents| image:: https://img.shields.io/badge/GitHub-view-6f42c1?style=flat&logo=Github
:target: https://github.com/tsutterley/pyTMD/blob/main/notebooks/Plot\ Antarctic\ Tidal\ Currents.ipynb

Expand Down
2 changes: 0 additions & 2 deletions notebooks/Check Tide Map.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
"TMDwidgets.VBox([\n",
" TMDwidgets.directory,\n",
" TMDwidgets.model,\n",
" TMDwidgets.atlas,\n",
" TMDwidgets.compress\n",
"])"
]
Expand All @@ -111,7 +110,6 @@
"source": [
"# get model parameters\n",
"model = pyTMD.io.model(TMDwidgets.directory.value,\n",
" format=TMDwidgets.atlas.value,\n",
" compressed=TMDwidgets.compress.value\n",
" ).elevation(TMDwidgets.model.value)\n",
"\n",
Expand Down
309 changes: 309 additions & 0 deletions notebooks/Plot Antarctic Cotidal Charts.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot Antarctic Cotidal Charts\n",
"=============================\n",
"\n",
"Demonstrates plotting cotidal charts around Antarctica\n",
"\n",
"OTIS format tidal solutions provided by Oregon State University and ESR \n",
"- http://volkov.oce.orst.edu/tides/region.html \n",
"- https://www.esr.org/research/polar-tide-models/list-of-polar-tide-models/\n",
"- ftp://ftp.esr.org/pub/datasets/tmd/ \n",
"\n",
"Global Tide Model (GOT) solutions provided by Richard Ray at GSFC \n",
"\n",
"Finite Element Solution (FES) provided by AVISO \n",
"- https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html\n",
"\n",
"#### Python Dependencies\n",
" - [numpy: Scientific Computing Tools For Python](https://www.numpy.org) \n",
" - [scipy: Scientific Tools for Python](https://www.scipy.org/) \n",
" - [pyproj: Python interface to PROJ library](https://pypi.org/project/pyproj/) \n",
" - [netCDF4: Python interface to the netCDF C library](https://unidata.github.io/netcdf4-python/) \n",
" - [matplotlib: Python 2D plotting library](http://matplotlib.org/) \n",
" - [cartopy: Python package designed for geospatial data processing](https://scitools.org.uk/cartopy/docs/latest/) \n",
"\n",
"#### Program Dependencies\n",
"\n",
"- `arguments.py`: load the nodal corrections for tidal constituents \n",
"- `astro.py`: computes the basic astronomical mean longitudes \n",
"- `crs.py`: Coordinate Reference System (CRS) routines \n",
"- `io.model.py`: retrieves tide model parameters for named tide models\n",
"- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n",
"- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n",
"- `io.GOT.py`: extract tidal harmonic constants from GOT tide models \n",
"- `io.FES.py`: extract tidal harmonic constants from FES tide models \n",
"- `predict.py`: predict tidal values using harmonic constants \n",
"- `time.py`: utilities for calculating time operations\n",
"- `utilities.py`: download and management utilities for files\n",
"\n",
"This notebook uses Jupyter widgets to set parameters for calculating the cotidal maps. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Load modules"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import pyproj\n",
"import numpy as np\n",
"import matplotlib\n",
"matplotlib.rcParams['axes.linewidth'] = 2.0\n",
"import matplotlib.pyplot as plt\n",
"import cartopy.crs as ccrs\n",
"\n",
"# import tide programs\n",
"import pyTMD.io\n",
"import pyTMD.predict\n",
"import pyTMD.tools\n",
"import pyTMD.utilities\n",
"\n",
"# autoreload\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Set parameters for program\n",
"\n",
"- Model directory \n",
"- Tide model "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# available model list\n",
"model_list = sorted(pyTMD.io.model.ocean_elevation())\n",
"# display widgets for setting directory and model\n",
"TMDwidgets = pyTMD.tools.widgets()\n",
"TMDwidgets.model.options = model_list\n",
"TMDwidgets.model.value = 'CATS2008'\n",
"TMDwidgets.VBox([\n",
" TMDwidgets.directory,\n",
" TMDwidgets.model,\n",
" TMDwidgets.compress,\n",
"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Setup tide model parameters"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# get model parameters\n",
"model = pyTMD.io.model(TMDwidgets.directory.value,\n",
" compressed=TMDwidgets.compress.value\n",
" ).elevation(TMDwidgets.model.value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Setup coordinates for calculating tidal amplitudes"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# create an image around Antarctica\n",
"xlimits = [-560.*5e3,560.*5e3]\n",
"ylimits = [-560.*5e3,560.*5e3]\n",
"spacing = [20e3,-20e3]\n",
"# x and y coordinates\n",
"x = np.arange(xlimits[0],xlimits[1]+spacing[0],spacing[0])\n",
"y = np.arange(ylimits[1],ylimits[0]+spacing[1],spacing[1])\n",
"xgrid,ygrid = np.meshgrid(x,y)\n",
"# x and y dimensions\n",
"nx = int((xlimits[1]-xlimits[0])/spacing[0])+1\n",
"ny = int((ylimits[0]-ylimits[1])/spacing[1])+1\n",
"# convert image coordinates from polar stereographic to latitude/longitude\n",
"crs1 = pyproj.CRS.from_epsg(3031)\n",
"crs2 = pyproj.CRS.from_epsg(4326)\n",
"transformer = pyproj.Transformer.from_crs(crs1, crs2, always_xy=True)\n",
"lon,lat = transformer.transform(xgrid.flatten(), ygrid.flatten())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Calculate tide map"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# read tidal constants and interpolate to grid points\n",
"if model.format in ('OTIS','ATLAS-compact','TMD3'):\n",
" amp,ph,D,c = pyTMD.io.OTIS.extract_constants(lon, lat, model.grid_file,\n",
" model.model_file, model.projection, type=model.type, crop=True,\n",
" method='spline', grid=model.file_format)\n",
"elif (model.format == 'ATLAS-netcdf'):\n",
" amp,ph,D,c = pyTMD.io.ATLAS.extract_constants(lon, lat, model.grid_file,\n",
" model.model_file, type=model.type, crop=True, method='spline',\n",
" scale=model.scale, compressed=model.compressed)\n",
"elif model.format in ('GOT-ascii', 'GOT-netcdf'):\n",
" amp,ph,c = pyTMD.io.GOT.extract_constants(lon, lat, model.model_file,\n",
" grid=model.file_format, crop=True, method='spline', scale=model.scale,\n",
" compressed=model.compressed)\n",
"elif (model.format == 'FES-netcdf'):\n",
" amp,ph = pyTMD.io.FES.extract_constants(lon, lat, model.model_file,\n",
" type=model.type, version=model.version, crop=True,\n",
" method='spline', scale=model.scale, compressed=model.compressed)\n",
" c = model.constituents"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Select constituent for cotidal chart"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"TMDwidgets.constituents.options = c\n",
"TMDwidgets.constituents.value = c[0]\n",
"display(TMDwidgets.constituents)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Create cotidal chart"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# extract amplitude and phase for constituent\n",
"i = TMDwidgets.constituents.index\n",
"cons = TMDwidgets.constituents.value\n",
"amplitude = amp[:,i].reshape(ny,nx)\n",
"phase = ph[:,i].reshape(ny,nx)\n",
"\n",
"# plot Antarctic cotidal charts\n",
"projection = ccrs.Stereographic(central_longitude=0.0,\n",
" central_latitude=-90,true_scale_latitude=-71.0)\n",
"fig, ax = plt.subplots(num=1, figsize=(9,8),\n",
" subplot_kw=dict(projection=projection))\n",
"# plot tide amplitude\n",
"extent = (xlimits[0],xlimits[1],ylimits[0],ylimits[1])\n",
"im = ax.imshow(amplitude, interpolation='nearest',\n",
" vmin=0, vmax=amplitude.max(), transform=projection,\n",
" extent=extent, origin='upper')\n",
"# plot tide phase\n",
"contour_levels = np.arange(0, 360, 30)\n",
"contour = ax.contour(xgrid, ygrid, phase,\n",
" contour_levels, colors='0.2', linestyles='solid',\n",
" transform=projection)\n",
"# add high resolution cartopy coastlines\n",
"ax.coastlines('10m')\n",
"\n",
"# Add colorbar and adjust size\n",
"# pad = distance from main plot axis\n",
"# extend = add extension triangles to upper and lower bounds\n",
"# options: neither, both, min, max\n",
"# shrink = percent size of colorbar\n",
"# aspect = lengthXwidth aspect of colorbar\n",
"cbar = plt.colorbar(im, ax=ax, pad=0.025, extend='max',\n",
" extendfrac=0.0375, shrink=0.85, aspect=22.5, drawedges=False)\n",
"# rasterized colorbar to remove lines\n",
"cbar.solids.set_rasterized(True)\n",
"# Add label to the colorbar\n",
"cbar.ax.set_ylabel(f'{model.name} {cons} Tide Chart', labelpad=10, fontsize=13)\n",
"cbar.ax.set_title('cm', fontsize=13, va='bottom')\n",
"# ticks lines all the way across\n",
"cbar.ax.tick_params(which='both', width=1, length=20,\n",
" labelsize=13, direction='in')\n",
"\n",
"# set x and y limits\n",
"ax.set_xlim(xlimits)\n",
"ax.set_ylim(ylimits)\n",
"\n",
"# stronger linewidth on frame\n",
"ax.spines['geo'].set_linewidth(2.0)\n",
"ax.spines['geo'].set_capstyle('projecting')\n",
"# adjust subplot within figure\n",
"fig.subplots_adjust(left=0.02,right=0.98,bottom=0.05,top=0.98)\n",
"\n",
"# show the plot\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.4 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.14"
},
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
2 changes: 0 additions & 2 deletions notebooks/Plot Antarctic Tidal Currents.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@
"TMDwidgets.VBox([\n",
" TMDwidgets.directory,\n",
" TMDwidgets.model,\n",
" TMDwidgets.atlas,\n",
" TMDwidgets.compress,\n",
" TMDwidgets.datepick\n",
"])"
Expand All @@ -126,7 +125,6 @@
"source": [
"# get model parameters\n",
"model = pyTMD.io.model(TMDwidgets.directory.value,\n",
" format=TMDwidgets.atlas.value,\n",
" compressed=TMDwidgets.compress.value\n",
" ).current(TMDwidgets.model.value)"
]
Expand Down
3 changes: 1 addition & 2 deletions notebooks/Plot Antarctic Tide Range.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"- `io.model.py`: retrieves tide model parameters for named tide models \n",
"- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n",
"- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n",
"- `io.GOT.py`: extract tidal harmonic constants from GOT tide models \n",
"- `io.FES.py`: extract tidal harmonic constants from FES tide models \n",
"\n",
"This notebook uses Jupyter widgets to set parameters for calculating the tidal maps. "
Expand Down Expand Up @@ -94,7 +95,6 @@
"TMDwidgets.VBox([\n",
" TMDwidgets.directory,\n",
" TMDwidgets.model,\n",
" TMDwidgets.atlas,\n",
" TMDwidgets.compress\n",
"])"
]
Expand All @@ -114,7 +114,6 @@
"source": [
"# get model parameters\n",
"model = pyTMD.io.model(TMDwidgets.directory.value,\n",
" format=TMDwidgets.atlas.value,\n",
" compressed=TMDwidgets.compress.value\n",
" ).elevation(TMDwidgets.model.value)"
]
Expand Down
Loading

0 comments on commit 1cb6a4b

Please sign in to comment.