Working with NetCDF files

Reading NetCDF files

In [1]:
from netCDF4 import Dataset   # import netCDF4 library
In [2]:
import numpy as np   # import numpy library
In [3]:
nc4file = 'data/pr_SEA-44_HadGEM2-AO_rcp85_r1i1p1_WRF_v3-5_day_209101-210012.nc'
In [4]:
ds = Dataset(nc4file, 'r')   # open a netcdf file
In [5]:
print (ds)
<class 'netCDF4._netCDF4.Dataset'>
root group (NETCDF4_CLASSIC data model, file format HDF5):
    institution: APCC (APEC Climate Center, busan, Korea)
    institute_id: APCC
    experiment_id: rcp85
    source: WRF3.5 2013 atmosphere: ARW; land: Unified Noah land-surface model; ocean: prescript SST
    model_id: WRFv3-5
    forcing: Nat, Ant, GHG, SA, Oz, LU, Sl, Vl, SS, Ds, BC, MD, OC
    parent_experiment_id: N/A
    parent_experiment_rip: r1i1p1
    branch_time: 0.0
    contact: Hongwei Yang (hwyangapcc@gmail.com)
    history: Rewrite from the original output of WRF downscaling 2014-09-22T01:20:07Z CMOR rewrote data to comply with CF standards and CORDEX requirements.
    comment: In future projection, the information of green house gases is only from the lateral boundary forcing. There is not such internal forcing inside the WRF domain.
    The data does not include the 10 grids buffer zone.
    references: Hongwei Yang, 2013, Revision of Climate Change by Dynamic Downscaling over the Maritime Continents. APCC Tech. Report (http://www.apcc21.org/eng/common/file_dn.jsp?fileName=APCC%20Research%20Report_2013-02(ENGLISH).pdf&fileServerName=1396858461899_1.pdf&fileSubPath=/attach/res/pbl)
    initialization_method: 1
    physics_version: 1
    tracking_id: 1fcade70-b9ec-49a2-a674-98c7db5b6dba
    experiment: RCP8.5
    frequency: day
    product: output
    creation_date: 2014-09-22T01:20:07Z
    Conventions: CF-1.4
    project_id: CORDEX
    table_id: Table day (Sept 2013) 70a3732ab8b66ffa6aa3fd77bb726fab
    title: WRFv3-5 model output prepared for CORDEX RCP8.5
    parent_experiment: N/A
    modeling_realm: atmos
    realization: 1
    cmor_version: 2.8.0
    dimensions(sizes): time(3600), lat(73), lon(147), bnds(2)
    variables(dimensions): float64 time(time), float64 time_bnds(time,bnds), float64 lat(lat), float64 lat_bnds(lat,bnds), float64 lon(lon), float64 lon_bnds(lon,bnds), float32 pr(time,lat,lon)
    groups:

In [6]:
print (ds.dimensions)
OrderedDict([('time', <class 'netCDF4._netCDF4.Dimension'> (unlimited): name = 'time', size = 3600
), ('lat', <class 'netCDF4._netCDF4.Dimension'>: name = 'lat', size = 73
), ('lon', <class 'netCDF4._netCDF4.Dimension'>: name = 'lon', size = 147
), ('bnds', <class 'netCDF4._netCDF4.Dimension'>: name = 'bnds', size = 2
)])
In [7]:
print (ds.variables)
OrderedDict([('time', <class 'netCDF4._netCDF4.Variable'>
float64 time(time)
    bounds: time_bnds
    units: days since 2007-01-01 00:00:00
    calendar: 360_day
    axis: T
    long_name: time
    standard_name: time
unlimited dimensions: time
current shape = (3600,)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('time_bnds', <class 'netCDF4._netCDF4.Variable'>
float64 time_bnds(time, bnds)
unlimited dimensions: time
current shape = (3600, 2)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('lat', <class 'netCDF4._netCDF4.Variable'>
float64 lat(lat)
    bounds: lat_bnds
    units: degrees_north
    axis: Y
    long_name: latitude
    standard_name: latitude
unlimited dimensions:
current shape = (73,)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('lat_bnds', <class 'netCDF4._netCDF4.Variable'>
float64 lat_bnds(lat, bnds)
unlimited dimensions:
current shape = (73, 2)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('lon', <class 'netCDF4._netCDF4.Variable'>
float64 lon(lon)
    bounds: lon_bnds
    units: degrees_east
    axis: X
    long_name: longitude
    standard_name: longitude
unlimited dimensions:
current shape = (147,)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('lon_bnds', <class 'netCDF4._netCDF4.Variable'>
float64 lon_bnds(lon, bnds)
unlimited dimensions:
current shape = (147, 2)
filling on, default _FillValue of 9.969209968386869e+36 used
), ('pr', <class 'netCDF4._netCDF4.Variable'>
float32 pr(time, lat, lon)
    standard_name: precipitation_flux
    long_name: Precipitation
    comment: at surface; includes both liquid and solid phases from all types of clouds (both large-scale and convective)
    units: kg m-2 s-1
    cell_methods: time: mean
    associated_files: baseURL: http://cmip-pcmdi.llnl.gov/CMIP5/dataLocation gridspecFile: gridspec_atmos_fx_WRFv3-5_rcp85_r0i0p0.nc
unlimited dimensions: time
current shape = (3600, 73, 147)
filling on, default _FillValue of 9.969209968386869e+36 used
)])
In [8]:
print (ds.variables['lon'][:])     # data
[  83.    83.5   84.    84.5   85.    85.5   86.    86.5   87.    87.5
   88.    88.5   89.    89.5   90.    90.5   91.    91.5   92.    92.5
   93.    93.5   94.    94.5   95.    95.5   96.    96.5   97.    97.5
   98.    98.5   99.    99.5  100.   100.5  101.   101.5  102.   102.5
  103.   103.5  104.   104.5  105.   105.5  106.   106.5  107.   107.5
  108.   108.5  109.   109.5  110.   110.5  111.   111.5  112.   112.5
  113.   113.5  114.   114.5  115.   115.5  116.   116.5  117.   117.5
  118.   118.5  119.   119.5  120.   120.5  121.   121.5  122.   122.5
  123.   123.5  124.   124.5  125.   125.5  126.   126.5  127.   127.5
  128.   128.5  129.   129.5  130.   130.5  131.   131.5  132.   132.5
  133.   133.5  134.   134.5  135.   135.5  136.   136.5  137.   137.5
  138.   138.5  139.   139.5  140.   140.5  141.   141.5  142.   142.5
  143.   143.5  144.   144.5  145.   145.5  146.   146.5  147.   147.5
  148.   148.5  149.   149.5  150.   150.5  151.   151.5  152.   152.5
  153.   153.5  154.   154.5  155.   155.5  156. ]
In [9]:
print (ds.variables['lon'].long_name)    # attribute
longitude
In [10]:
lons = ds.variables['lon'][:]
In [11]:
lats = ds.variables['lat'][:]
In [12]:
pr = ds.variables['pr'][1, :]    # time start index is 1 in this case
In [13]:
pr_units = ds.variables['pr'].units   # get an attribute of a variable
In [14]:
ds.close()   # close datasaet

Plotting netCDF data

In [15]:
import matplotlib.pyplot as plt   # import matplotlib
In [16]:
from mpl_toolkits.basemap import Basemap
In [17]:
lon_0 = lons.mean()
In [18]:
lat_0 = lats.mean()
In [19]:
m = Basemap(projection = 'merc', resolution = 'l',\
            llcrnrlat = lats.min(), urcrnrlat = lats.max(), \
            llcrnrlon = lons.min(), urcrnrlon = lons.max(), \
            lat_ts = lat_0)
In [20]:
lon, lat = np.meshgrid(lons, lats)
xi, yi = m(lon, lat)
In [21]:
# Plot Data
cs = m.pcolor(xi,yi,np.squeeze(pr))

# Add Grid Lines
m.drawparallels(np.arange(-80., 81., 10.), labels=[1,0,0,0], fontsize=10)
m.drawmeridians(np.arange(-180., 181., 10.), labels=[0,0,0,1], fontsize=10)

# Add Coastlines, States, and Country Boundaries
m.drawcoastlines()
m.drawstates()
m.drawcountries()

# Add Colorbar
cbar = m.colorbar(cs, location='bottom', pad="10%")
cbar.set_label(pr_units)

# Add Title
plt.title('Precipitation')

plt.show()