In [1]:
    
name = '2016-10-14-loading-netcdf-datasets'
title = 'Loading NetCDF datasets'
tags = 'netcdf, io'
author = 'Denis Sergeev'
    
In [2]:
    
from nb_tools import connect_notebook_to_post
from IPython.core.display import HTML, Image
html = connect_notebook_to_post(name, title, tags, author)
    
Continuing the previous week's topic, today we went through the basics of loading netCDF datasets.
In this notebook we explore a netCDF file from the Atlantic Real-Time Ocean Forecast System (downloaded from the Unidata Python Workshop's GitHub repository. The filename is rtofs_glo_3dz_f006_6hrly_reg3.nc.
In [3]:
    
import os
path_to_file = os.path.join(os.path.pardir, 'data', 'rtofs_glo_3dz_f006_6hrly_reg3.nc')
print(path_to_file)
    
    
First, let's load essential modules
In [4]:
    
from __future__ import division, print_function
import netCDF4 as nc
import numpy as np
    
In [5]:
    
f = nc.Dataset(path_to_file)
print(f)
    
    
So what have we got here?
f is a Dataset object, representing an open netCDF file.ncdump -h.You can also get a list of global attributes:
In [6]:
    
f.ncattrs()
    
    Out[6]:
In [7]:
    
for d in f.dimensions.items():
    print(d)
    
    
In [8]:
    
type(f.variables)
    
    Out[8]:
In [9]:
    
print(f.variables.keys()) # get all variable names
# or like this: [*f.variables.keys()]
    
    
In [10]:
    
temp_c = f.get_variables_by_attributes(units='degC')[0]
sal = f.variables['salinity']
    
In [11]:
    
print(sal)
    
    
In [12]:
    
sal.dimensions, sal.shape
    
    Out[12]:
In [13]:
    
mt = f.variables['MT']
depth = f.variables['Depth']
x, y = f.variables['X'], f.variables['Y']
print(mt)
print(x)
    
    
IndexError: Index cannot be multidimensional (?).To plot it, we need the auxilary coordinate variables, Latitude and Longitude that define the 'real' data coordinates.
In [14]:
    
lat = f.variables['Latitude']
lon = f.variables['Longitude']
print(lat)
    
    
In [15]:
    
# extract lat/lon values (in degrees) to numpy arrays
latvals = lat[:]; lonvals = lon[:]
    
In [16]:
    
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
%matplotlib inline
    
In [17]:
    
fig, ax = plt.subplots(figsize=(12, 8),
                       subplot_kw=dict(projection=ccrs.PlateCarree()))
ax.coastlines('10m')
ax.set_title('Sea surface salinity', fontsize=24)
p = ax.contourf(lonvals, latvals, sal[0, 0, ...], cmap='viridis')
cb = plt.colorbar(p, orientation='horizontal', shrink=0.9, pad=0.05)
ax.set_extent([-180, -100, 40, 80])
ax.stock_img()
# Colorbar ticks fontsize
cb.ax.tick_params(labelsize=30)
    
    
In [18]:
    
def getclosest_ij(lats, lons, latpt, lonpt):
    """
    A function to find indices of the point closest
    (in squared distance) to return the given lat/lon value."""
    # find squared distance of every point on grid
    dist_sq = (lats - latpt)**2 + (lons - lonpt)**2  
    # 1D index of minimum dist_sq element
    minindex_flattened = dist_sq.argmin()    
    # Get 2D index for latvals and lonvals arrays from 1D index
    return np.unravel_index(minindex_flattened, lats.shape)
    
In [19]:
    
pnt_lat, pnt_lon = (63.202533, -170.650635)
    
In [20]:
    
iy, ix = getclosest_ij(latvals, lonvals, pnt_lat, pnt_lon)
    
In [21]:
    
# Read values out of the netCDF file for temperature and salinity
print('{value:7.4f} {units}'.format(value=temp_c[0, 0, iy, ix], units=temp_c.units))
print('{value:7.4f} {units}'.format(value=sal[0, 0, iy, ix], units=sal.units))
    
    
Load the files
In [22]:
    
files_wcard = os.path.join(os.path.pardir, 'data', 'uwnd*nc')
print(files_wcard)
    
    
In [23]:
    
mf = nc.MFDataset(files_wcard)
    
Check time span
In [24]:
    
times = mf.variables['time']
dates = nc.num2date(times[:], times.units)
print('starting date = {}'.format(dates[0]))
print('  ending date = {}'.format(dates[-1]))
    
    
In [25]:
    
u = mf.variables['uwnd']
print('u dimensions = {},\nu shape      = {}'.format(u.dimensions, u.shape))
    
    
This notebook is build upon the great materials of the Unidata Python Workshop:
In [26]:
    
HTML(html)
    
    Out[26]: