The datasets being accessed here are NetCDF files from ADCIRC, SELFE and FVCOM, with attributes added or modified virtually using NcML to meet the UGRID conventions standard for unstructured grid models.
This example was developed for the Integrated Ocean Observing System (IOOS) Coastal and Ocean Modeling Testbed.
You can quickly and easily set up the IOOS Anaconda python environment that can run this notebook.
%matplotlib inline
from __future__ import (absolute_import, division, print_function)
import numpy as np
import matplotlib.tri as tri
import datetime as dt
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import iris
iris.FUTURE.netcdf_promote = True
import pyugrid
# specify UGRID compliant OPeNDAP Data URL
#ADCIRC
#url = 'http://comt.sura.org/thredds/dodsC/data/comt_1_archive/inundation_tropical/UND_ADCIRC/Hurricane_Rita_2D_final_run_without_waves'
#FVCOM
#url = 'http://comt.sura.org/thredds/dodsC/data/comt_1_archive/inundation_tropical/USF_FVCOM/Hurricane_Rita_2D_final_run_without_waves'
#SELFE
#url = 'http://comt.sura.org/thredds/dodsC/data/comt_1_archive/inundation_tropical/VIMS_SELFE/Hurricane_Rita_2D_final_run_without_waves'
#MWRA FVCOM
#url = 'http://www.smast.umassd.edu:8080/thredds/dodsC/fvcom/mwra/fvcom'
#MWRA Water Quality run
url = 'http://www.smast.umassd.edu:8080/thredds/dodsC/fvcom/mwra/wq'
# set parameters
bbox = [-71.15, -69.8, 41.7, 42.7] # set the bounding box [lon_min, lon_max, lat_min, lat_max]
var = 'Dissolved oxygen' # standard_name (or long_name, if no standard_name)
levs = np.arange(6.,9.,.1) # set the contour levels
start = dt.datetime(2012, 8, 24, 5, 0, 0) # time in UTC
#start = dt.datetime.utcnow() + dt.timedelta(hours=6)
cube = iris.load_cube(url,var)
C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'Itime2' invalid units u'msec since 00:00:00' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'TPSI' invalid units u'mg Si/l' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'DOP' invalid units u'mg P/l' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'POP' invalid units u'mg P/l' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'DPO4' invalid units u'mg P/l' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'DSI' invalid units u'mg Si/l' warnings.warn(msg.encode('ascii', errors='backslashreplace')) C:\Anaconda64\envs\ioos3\lib\site-packages\iris\fileformats\_pyke_rules\compiled_krb\fc_rules_cf_fc.py:1300: UserWarning: Ignoring netCDF variable u'O2EQ' invalid units u'mg O2/l' warnings.warn(msg.encode('ascii', errors='backslashreplace'))
print(cube)
Dissolved oxygen (time: 2440; -- : 30; -- : 4537) Dimension coordinates: time x - - Auxiliary coordinates: sea_surface_height_above_geoid x - x ocean_sigma_coordinate - x x latitude - - x longitude - - x sea_floor_depth_below_geoid - - x Derived coordinates: sea_surface_height_above_reference_ellipsoid x x x Attributes: Conventions: CF-1.0, UGRID-0.9 CoordinateProjection: init=nad83:1802 CoordinateSystem: Cartesian DODS.dimName: DateStrLen DODS.strlen: 26 cdm_data_type: any coverage_content_type: modelResult history: convert binary file to NetCDF location: node mesh: fvcom_mesh references: http://fvcom.smast.umassd.edu, http://codfish.smast.umassd.edu source: FVCOM_3.0 summary: Archive of MWRA water quality modeling simulations (1995-present) title: Mass Water Resources Authority (MWRA) Water Quality UG-RCA-FVCOM simul...
ug = pyugrid.UGrid.from_ncfile(url)
# What's in there?
#print("There are %i nodes"%ug.nodes.shape[0])
#print("There are %i edges"%ug.edges.shape[0])
#print("There are %i faces"%ug.faces.shape[0])
cube.mesh = ug
cube.mesh_dimension = 1 # (0:time,1:node)
lon = cube.mesh.nodes[:,0]
lat = cube.mesh.nodes[:,1]
nv = cube.mesh.faces
triang = tri.Triangulation(lon,lat,triangles=nv)
tvar = cube.coord('time')
itime = tvar.nearest_neighbour_index(tvar.units.date2num(start))
klev = -1
zcube = cube[itime,klev]
plt.figure(figsize=(16,6))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent(bbox)
ax.coastlines(resolution='10m')
plt.tricontourf(triang, zcube.data, levels=levs)
plt.colorbar(fraction=0.046, pad=0.04)
plt.tricontour(triang, zcube.data, colors='k',levels=levs)
tstr = tvar.units.num2date(tvar.points[itime])
gl = ax.gridlines(draw_labels=True)
gl.xlabels_top = False
gl.ylabels_right = False
plt.title('%s: %s: %s' % (var,tstr,zcube.attributes['title']));
import mplleaflet
fig = plt.figure(figsize=(6,8))
plt.tricontourf(triang, zcube.data, levels=levs)
plt.axis(bbox) # Vineyard sound 2.
mplleaflet.display()