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]: