Download data


In [ ]:
import os
import iris
import numpy as np


def get_data(var='salinity', name='sea_water_salinity',
             clim_type='annual', resolution='1deg',
             longitude=lambda cell: 0 <= cell <=360,
             latitude=lambda cell: -90 <= cell <= 90,
             depth=lambda cell: 0<= cell <= 5500):
    coord_values = dict(longitude=longitude, latitude=latitude)
    constraint = iris.Constraint(coord_values=coord_values,
                                 name=name)
    uri = "http://data.nodc.noaa.gov/thredds/dodsC/woa/WOA09/NetCDFdata"
    fname = "%s_%s_%s.nc" % (var, clim_type, resolution)
    url = '%s/%s' % (uri, fname)
    cube = iris.load_cube(url, constraint=constraint)
    
    if clim_type == 'annual':
        cube = cube.collapsed('time', iris.analysis.MEAN)
    return cube


def load(name):
    fname = '../../data/woa09_%s_seasonal.nc' % name
    if not os.path.isfile(fname):
        cube = get_data(var=name, name=variables[name],
                        clim_type='seasonal', resolution='1deg')
        iris.save(cube, fname)
    else:
        cube = iris.load_cube(fname)
    return cube
    

variables = dict(salinity='sea_water_salinity',
                 temperature='sea_water_temperature',
                 silicate='mole_concentration_of_silicate_in_sea_water',
                 phosphate='mole_concentration_of_phosphate_in_sea_water',
                 nitrate='mole_concentration_of_nitrate_in_sea_water',
                 oxygen_saturation='Objectively Analyzed Climatology',
                 dissolved_oxygen='Objectively Analyzed Climatology',
                 apparent_oxygen_utilization='Objectively Analyzed Climatology')


seasonal = dict()
for name in variables.keys():
    seasonal.update({name: load(name)})

In [ ]:
import os
import iris
import numpy as np


def get_data(var='salinity', name='sea_water_salinity',
             clim_type='annual', resolution='1deg',
             longitude=lambda cell: 0 <= cell <=360,
             latitude=lambda cell: -90 <= cell <= 90,
             depth=lambda cell: 0<= cell <= 5500):
    coord_values = dict(longitude=longitude, latitude=latitude)
    constraint = iris.Constraint(coord_values=coord_values,
                                 name=name)
    uri = "http://data.nodc.noaa.gov/thredds/dodsC/woa/WOA09/NetCDFdata"
    fname = "%s_%s_%s.nc" % (var, clim_type, resolution)
    url = '%s/%s' % (uri, fname)
    cube = iris.load_cube(url, constraint=constraint)
    
    if clim_type == 'annual':
        cube = cube.collapsed('time', iris.analysis.MEAN)
    return cube


def load(name):
    fname = '../../data/woa09_%s_annual.nc' % name
    if not os.path.isfile(fname):
        cube = get_data(var=name, name=variables[name],
                        clim_type='annual', resolution='1deg')
        iris.save(cube, fname)
    else:
        cube = iris.load_cube(fname)
    return cube
    

variables = dict(salinity='sea_water_salinity',
                 temperature='sea_water_temperature',
                 silicate='mole_concentration_of_silicate_in_sea_water',
                 phosphate='mole_concentration_of_phosphate_in_sea_water',
                 nitrate='mole_concentration_of_nitrate_in_sea_water',
                 oxygen_saturation='Objectively Analyzed Climatology',
                 dissolved_oxygen='Objectively Analyzed Climatology',
                 apparent_oxygen_utilization='Objectively Analyzed Climatology')


annual = dict()
for name in variables.keys():
    annual.update({name: load(name)})

Figures


In [ ]:
import iris.plot as iplt
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import matplotlib.ticker as mticker

from oceans.colormaps import cm
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER


def plot_horizontal_slice(cube, depth=0, cmap=cm.odv):
    fig, ax = plt.subplots(subplot_kw=dict(projection=ccrs.PlateCarree(central_longitude=-150)),
                           figsize=(10, 5))    
    idx = cube.coord('depth').nearest_neighbour_index(depth)
    cs = iplt.pcolormesh(cube[idx, ...], cmap=cmap)
    if not (levels is None):
        cs.set_clim(levels[0], levels[-1])
    cbar = fig.colorbar(cs, extend='both', shrink=0.75, pad=0.02, fraction=0.1,
                        orientation='vertical')
    ax.set_global()
    ax.coastlines(resolution='110m', color='k')
    ax.add_feature(cfeature.LAND, facecolor='0.75')
    # Gridlines.
    gl = ax.gridlines(draw_labels=True)
    gl.xlabels_top = False
    gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    # Work around writing longitude position twice (e.g.: 180W and 180E).
    gl.xlocator = mticker.FixedLocator([-60, -120, -180, 120, 60, 0])
    ax.set_title("Slice at depth %s meters" % depth)
    return fig, ax, cbar

Salinity anomaly for austral summer (surface)


In [ ]:
data = annual['salinity'] - seasonal['salinity'][2, ...]
levels = np.arange(-1, 1, 0.2)
fig, ax, cbar = plot_horizontal_slice(data, depth=0)

Temperature animaly for austral summer (surface)


In [ ]:
data = annual['temperature'] - seasonal['temperature'][2, ...]
levels = np.arange(-1, 1, 0.2)
fig, ax, cbar = plot_horizontal_slice(data, depth=0)