In [2]:
%load_ext load_style
%load_style talk.css
In [3]:
%matplotlib inline
eofs is a Python library developed by Andrew Dawson which provides a very convenient interface for performing EOF decomposition of geophysical (ocean / atmosphere) fields
It has 3 interfaces
:
standard
: expects numpy arrays as inputscdms
: cdms2 objects (cdms2 is a class for opening netcdf files [amongst other formats]) part of the cdat-lite package or UV-CDAT distribution)iris
: iris cubesWe are going to use xray here, and thus use the standard interface, passing the underlying numpy arrays
In [4]:
from eofs.standard import Eof
In [5]:
import os, sys
import pandas as pd
import numpy as np
from numpy import ma
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap as bm
In [6]:
dpath = os.path.join(os.environ['HOME'],'data/SST/ER_SST/V4')
#dpath = os.path.join(os.environ['HOME'],'data/SST/ER_SST/')
In [7]:
def plot_field(X, lat, lon, vmin, vmax, step, cmap=plt.get_cmap('jet'), ax=False, title=False, grid=False):
if not ax:
f, ax = plt.subplots(figsize=(10, (X.shape[0] / float(X.shape[1])) * 10))
m.ax = ax
im = m.contourf(lons, lats, X, np.arange(vmin, vmax+step, step), latlon=True, cmap=cmap, extend='both', ax=ax)
m.drawcoastlines()
if grid:
m.drawmeridians(np.arange(0, 360, 60), labels=[0,0,0,1])
m.drawparallels([-40, 0, 40], labels=[1,0,0,0])
m.colorbar(im)
if title:
ax.set_title(title)
In [8]:
import xray; print(xray.__version__)
In [9]:
ncfname = os.path.join(dpath,'ersst.realtime.nc')
In [10]:
dset = xray.open_dataset(ncfname)
In [12]:
dset
Out[12]:
In [13]:
dsub = dset.sel(time=slice('1980','2014'), lat=slice(-40,40), lon=slice(120,290))
In [12]:
lat = dsub['lat'].values
lon = dsub['lon'].values
sst = dsub['anom'].values.squeeze() # because of zlev
In [13]:
lons, lats = np.meshgrid(lon, lat)
In [14]:
sst.shape
Out[14]:
In [15]:
coslat = np.cos(np.deg2rad(lat))
wgts = np.sqrt(coslat)[..., np.newaxis]
In [16]:
solver = Eof(sst, weights=wgts)
In [17]:
eof1 = solver.eofsAsCorrelation(neofs=1)
In [18]:
pc1 = solver.pcs(npcs=1, pcscaling=1)
In [19]:
eof1.shape
Out[19]:
In [20]:
m = bm(projection='cyl',llcrnrlat=-40,urcrnrlat=40,\
llcrnrlon=120,urcrnrlon=290,\
lat_ts=0,resolution='c')
In [21]:
plot_field(eof1.squeeze(), lats, lons, -1, 1, 0.1, cmap=plt.get_cmap('RdBu_r'), \
title="EOF #1", grid=True)
In [22]:
pc1 = pd.Series(pc1.squeeze(), index=dsub['time'].values)
In [23]:
pc1.plot(figsize=(10,5))
Out[23]: