Working with NEMO files

Here are some examples for plotting outputs on a NEMO grid.

Building variable

Let’s first build a bathymetric field using the vertical scale factors.

import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
import cartopy.feature as cfeature
import cartopy.crs as ccrs

data = xr.open_dataset('data/mesh_mask_eORCA1_v2.2.nc')
data = data.isel(t=0)
tmask = data['tmask'].values
e3t = data['e3t_0'].values
lon = data['glamt'].values
lat = data['gphit'].values

bathy = np.sum(e3t * tmask, axis=0)
bathy = np.ma.masked_where(bathy == 0, bathy)

First try

If we first try to use the pcolormesh as we learned, here is what comes out:

fig = plt.figure(figsize=(12, 15))
ax = plt.axes(projection=ccrs.PlateCarree())
cs = ax.pcolormesh(lon, lat, bathy, transform=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND, zorder=50)
ax.add_feature(cfeature.COASTLINE, zorder=51)
cb = plt.colorbar(cs, shrink=0.3)
/home/barrier/Softwares/anaconda3/lib/python3.7/site-packages/cartopy/mpl/geoaxes.py:1797: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3.  Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading'].  This will become an error two minor releases later.
  result = matplotlib.axes.Axes.pcolormesh(self, *args, **kwargs)
../_images/nemo_3_1.png

We have an error message saying that the longitudes and latitudes are not monotonic. Let’s improve our figure.

Better way

As indicated in the documentation, the pcolormesh method assumes the following layout:

(X[i+1, j], Y[i+1, j])          (X[i+1, j+1], Y[i+1, j+1])
                      +--------+
                      | C[i,j] |
                      +--------+
    (X[i, j], Y[i, j])          (X[i, j+1], Y[i, j+1])

Therefore, the good way to draw is to provide the coordinates of the F points (upper-right corners), and to give a sub-array of T points.

Grid layout of NEMO outputs:

../_images/nemo-index.png
lonf = data['glamf'].data
latf = data['gphif'].data
fig = plt.figure()
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=0))
cs = ax.pcolormesh(lonf, latf, bathy[1:, 1:], transform=ccrs.PlateCarree(), shading='flat')
ax.set_extent([-20, 20, -20, 20], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.COASTLINE, zorder=2)
ax.add_feature(cfeature.LAND, zorder=1)
cb = plt.colorbar(cs, shrink=0.5)
../_images/nemo_6_0.png

Contour plots

However, the drawing of contour plots is not simple on irregular grid. Instead, we need to use the tricontour method, as indicated here.

First, we recover the coordinates on the T points, not on the F points as for pcolormesh.

lont = data['glamt'].data
latt = data['gphit'].data

Then, we extract the data mask.

mask = (np.ma.getmaskarray(bathy))

Now, we extract the bathy, longitudes and latitudes on wet points and we convert into 1D arrays:

lon1d = np.ravel(lont[~mask])
lat1d = np.ravel(latt[~mask])
bat1d = np.ravel(bathy[~mask])
bat1d
masked_array(data=[121.15876481013115, 64.95892756174798,
                   515.0322590608843, ..., 24.57716311091656,
                   24.57716311091656, 24.57716311091656],
             mask=[False, False, False, ..., False, False, False],
       fill_value=1e+20)

The next step is to convert our 1D geographical coordinates (lon/lat) into the coordinates of the output map. If we want to draw our contours on a Mollweide projection:

projin = ccrs.PlateCarree()
projout = ccrs.Mollweide(central_longitude=180)
#projout = ccrs.PlateCarree(central_longitude=0)

output = projout.transform_points(projin, lon1d, lat1d)
lonout = output[..., 0]
latout = output[..., 1]
latout.shape
(65549,)

Now, we can add contours using the tricontour method:

fig = plt.figure(figsize=(12, 12))
ax = plt.axes(projection=projout)
cs = ax.pcolormesh(lonf, latf, bathy[1:, 1:], transform=projin)
cl = ax.tricontour(lonout, latout, bat1d, levels=np.arange(0, 6000 + 1000, 1000), colors='k', linewidths=0.5)
ax.add_feature(cfeature.LAND, zorder=100)
l = ax.add_feature(cfeature.COASTLINE, zorder=101, linewidth=2)
../_images/nemo_18_0.png