def load(ifile_fp, varname, gridfile): """Time average ifile and return var, dims""" path, ifile = os.path.split(ifile_fp) data = cd.loadvar(ifile_fp, varname, cdostr='timmean') tmask = cd.loadvar(gridfile, 'tmask') if data.ndim == 3: data = data * tmask else: data = data * tmask[0, :, :].squeeze() return np.ma.masked_equal(data, 0)
def save_reanalysis_trends(var, rean, start_date, end_date, datapath): """Compute reanalysis trends and save to HDF5 """ lr = len(rean) slopes = np.zeros((180, 360, lr)) cdo_str = '-seldate,' + start_date + ',' + end_date + ' -selvar,' + var + ' ' tail = '_' + var + '.mon.mean.nc' # Loop over the reanalyses for i, r in enumerate(rean): ifile = os.path.join(datapath, 'remap_' + r + tail) cdo.trend(input=(cdo_str + ifile) , output="int.nc " + r + "_slope.nc") slopes[:,:,i] = cd.loadvar(r + '_slope.nc', var) os.system('rm -f int.nc ' + r + '_slope.nc') os.system('rm -f int.nc ' + r + '_slope.nc') # Store the DataFrame in HDF5 out_file = os.path.join(datapath, 'reanalysis_trends.h5') h5f = h5py.File(out_file, 'a') sy = start_date.split('-')[0] ey = end_date.split('-')[0] ds_path = os.path.join(var, sy + '_' + ey) ds_name = os.path.join(ds_path, 'rean_' + var + '_trend_' + sy + '_' + ey) h5f.create_dataset(ds_name, data=slopes) h5f.create_dataset(ds_path + '/reanalysis_names', data=rean) #h5f[ds_name].dims.create_scale(h5f[ds_path + 'model_names'], 'model_names') #f[ds_name].dims[2].attach_scale(h5f[ds_path + 'model_names']) h5f.close()
def save_reanalysis_trends(var, rean, start_date, end_date, datapath): """Compute reanalysis trends and save to HDF5 """ lr = len(rean) slopes = np.zeros((180, 360, lr)) cdo_str = '-seldate,' + start_date + ',' + end_date + ' -selvar,' + var + ' ' tail = '_' + var + '.mon.mean.nc' # Loop over the reanalyses for i, r in enumerate(rean): ifile = os.path.join(datapath, 'remap_' + r + tail) cdo.trend(input=(cdo_str + ifile), output="int.nc " + r + "_slope.nc") slopes[:, :, i] = cd.loadvar(r + '_slope.nc', var) os.system('rm -f int.nc ' + r + '_slope.nc') os.system('rm -f int.nc ' + r + '_slope.nc') # Store the DataFrame in HDF5 out_file = os.path.join(datapath, 'reanalysis_trends.h5') h5f = h5py.File(out_file, 'a') sy = start_date.split('-')[0] ey = end_date.split('-')[0] ds_path = os.path.join(var, sy + '_' + ey) ds_name = os.path.join(ds_path, 'rean_' + var + '_trend_' + sy + '_' + ey) h5f.create_dataset(ds_name, data=slopes) h5f.create_dataset(ds_path + '/reanalysis_names', data=rean) #h5f[ds_name].dims.create_scale(h5f[ds_path + 'model_names'], 'model_names') #f[ds_name].dims[2].attach_scale(h5f[ds_path + 'model_names']) h5f.close()
def genweights(gridfile): """Return weights based on grid area (2D) and volume (3D). """ # Load grid dimensions and tmask e1t = cd.loadvar(gridfile, 'e1t') e2t = cd.loadvar(gridfile, 'e2t') e3t = cd.loadvar(gridfile, 'e3t') tmask = cd.loadvar(gridfile, 'tmask') # tile e1 and e2 areas to 3D e1t3 = np.tile(e1t, [e3t.shape[0], 1, 1]) e2t3 = np.tile(e2t, [e3t.shape[0], 1, 1]) vol = e1t3 * e2t3 * e3t * tmask vol = np.ma.masked_equal(vol, 0) weights3d = vol / vol.sum() area = e1t.squeeze() * e2t.squeeze() * tmask[0, :, :] area = np.ma.masked_equal(area, 0) weights2d = area / area.sum() return weights2d, weights3d
def calc_sam(psl_file, varname, start_date='1800-01-01', end_date='2013-12-31'): """ Compute the SAM index as the pressure difference between 40 and 65S Parameters: ----------- psl_file : str The name of the **zonal meaned** SLP netcdf file to compute the SAM from. Can be a full path. varname : str The name of the Sea Level Pressure variable in psl_file. Returns: ------- sam : array The calculated SAM index """ # Extract the pressure at 40 and 65S (head, tail) = os.path.split(psl_file) ofile_40s = os.path.join(head, 'p40s_' + tail) ofile_60s = os.path.join(head, 'p65s_' + tail) ofile_sam = os.path.join(head, 'SAM_' + tail) cdo.remapnn('lon=0/lat=-40.0', input=psl_file, output=ofile_40s) cdo.remapnn('lon=0/lat=-65.0', input=psl_file, output=ofile_60s) # Compute the SAM index cdo.sub(input=ofile_40s + ' ' + ofile_60s, output=ofile_sam, options='-f nc -b 64') # load the data and make dataframes sam = cd.loadvar(ofile_sam, varname, start_date=start_date, end_date=end_date) # cleanup for f in [ofile_40s, ofile_60s, ofile_sam]: os.remove(f) return sam + 0.0
import numpy as np import scipy as sp from mpl_toolkits.basemap import Basemap, addcyclic import matplotlib.pyplot as plt import matplotlib as mpl import brewer2mpl from discrete_cmap import discrete_cmap from netCDF4 import Dataset,num2date,date2num plt.ion() plt.close('all') font = {'size' : 10} plt.rc('font', **font) # load in the CCMP data ifile_ccmp = '/raid/ra40/data/ncs/ccmp/ccmp_slope_199801-201112.nc' slope_ccmp_uwnd = cd.loadvar(ifile_ccmp, 'uwnd')*120. slope_ccmp_wspd = cd.loadvar(ifile_ccmp, 'wspd')*120. slope_ccmp_uwnd = np.ma.masked_outside(slope_ccmp_uwnd, -2,2) slope_ccmp_wspd = np.ma.masked_outside(slope_ccmp_wspd, -2,2) dims = {'lat' : np.arange(-89.5,90.1,1), 'lon' : np.arange(0,361,1) } fig, axa = plt.subplots(2,1, sharex=True, sharey=True, figsize=(7,7), squeeze=True) fig.subplots_adjust(right=0.825, top=0.65, hspace=0.1, wspace=0.05) vmin = -1
def plot_zonmean_trends(datapath): # Load the CMIP5 data h5f = h5py.File(datapath + 'cmip5_trends.h5','r') psl_slope_c5 = h5f['psl/1979_2004/c5_psl_trend_1979_2004'][:]*120 uas_slope_c5_88 = h5f['uas/1988_2011/c5_uas_trend_1988_2011'][:]*120 uflx_slope_c5_88 = h5f['tauu/1988_2011/c5_tauu_trend_1988_2011'][:]*120*100 h5f.close() # load in the reanlaysis data rlc = [ 'k' , 'y', 'g' , 'b' , 'c' , 'm' ] h5f = h5py.File(datapath + 'reanalysis_trends.h5','r') psl_slope_rean = h5f['slp/1979_2004/rean_slp_trend_1979_2004'][:]*120 uas_slope_rean_88 = h5f['u10m/1988_2011/rean_u10m_trend_1988_2011'][:]*120 uflx_slope_rean_88 = h5f['uflx/1988_2011/rean_uflx_trend_1988_2011'][:]*120*100 rean = h5f['uflx/1988_2011/reanalysis_names'][:] h5f.close() # The HadSLPr2 data is in the rean hdf psl_slope_hadslp = psl_slope_rean[:,:,6] # load in the CCMP data ifile_ccmp = datapath + 'slope_remap_CCMP_198701-201112.nc' #despite name, starts 88 slope_ccmp = cd.loadvar(ifile_ccmp, 'uwnd')*120. slope_ccmp = np.ma.masked_outside(slope_ccmp, -1,1) uflx_slope_ccmp = cd.loadvar(ifile_ccmp, 'upstr')*120. uflx_slope_ccmp = np.ma.masked_outside(uflx_slope_ccmp, -15,15) uflx_slope_ccmp = uflx_slope_ccmp*1.2*1.4e-3*120 # load in the Marshall SAM data df = pd.read_csv(datapath + 'marshall_sam.csv', index_col=0, parse_dates=True) df = pt.time_lim(df, pd.datetime(1979,1,1), pd.datetime(2004,12,31)) dft = pt.ols(df, units='decades') dims = {'lat' : np.arange(-89.5,89.6,1), 'lon' : np.arange(0,360,1) } fig, (axt, axm, axb) = plt.subplots(3,1, sharex=True, figsize=(7,7)) fig.subplots_adjust(right=0.5, hspace=0.05) modlatplot( psl_slope_c5.mean(axis=2), axt) axt.plot(dims['lat'], psl_slope_hadslp.mean(axis=(1)), 'k--', linewidth=3 , label='HadSLP2r') axt.plot(dims['lat'], slope_ccmp.mean(axis=1)*np.nan, 'k-.' , linewidth=3, label='CCMP') # put on the trends in marshall axt.plot(-40, dft.slp40.slope*100.0, 'kx', markersize=15, markeredgewidth=3 , zorder=10) axt.plot(-65, dft.slp65.slope*100.0, 'kx', markersize=15, markeredgewidth=3 , label='Marshall', zorder=10) modlatplot( uas_slope_c5_88.mean(axis=2), axm) axm.plot(dims['lat'], slope_ccmp.mean(axis=1), 'k-.', linewidth=3, zorder=9) modlatplot( uflx_slope_c5_88.mean(axis=2), axb) axb.plot(dims['lat'], uflx_slope_ccmp.mean(axis=1), 'k-.', linewidth=3, zorder=9) for i,r in enumerate(rean): axt.plot(dims['lat'], psl_slope_rean[:,:,i].mean(axis=1), linestyle='-' , color=rlc[i], linewidth=2, label=r) axm.plot(dims['lat'], uas_slope_rean_88[:,:,i].mean(axis=1), linestyle='-' , color=rlc[i], linewidth=2) axb.plot(dims['lat'], uflx_slope_rean_88[:,:,i].mean(axis=1), linestyle='-' , color=rlc[i], linewidth=2) axt.legend(bbox_to_anchor=(1.6,1), frameon=False, numpoints=1, fontsize=12) axb.set_xlabel('Latitude') ylabs = ['Pa decade$^{-1}$', 'm s$^{-1}$ decade$^{-1}$', r'Pa decade$^{-1}\times 10^{-2}$' ] for i, ax in enumerate((axt, axm, axb)): ax.set_xlim([-80, -20]) ax.plot([-90, 0], [0, 0], 'k-') ax.set_ylabel(ylabs[i]) axt.set_ylim([-135, 90]) axm.set_ylim([-0.325, 0.325]) axb.set_ylim([-1.5, 1.7]) xp=-78.5 axt.text(xp, 70, 'a)') axm.text(xp, 0.26, 'b)') axb.text(xp, 1.4, 'c)') xp=-43 axt.text(xp, 65, '1979-2004') axm.text(xp, 0.25, '1988-2011') axb.text(xp, 1.325, '1988-2011') plt.savefig('../plots/zonmean_trends.pdf' , bbox_inches = 'tight', dpi=300)
def plot_trend_maps(datapath): # Load the CMIP5 data h5f = h5py.File(datapath + 'cmip5_trends.h5', 'r') uas_slope_c5 = h5f['uas/1988_2011/c5_uas_trend_1988_2011'][:] * 120 #names2 = h5f['uas/1988_2011/model_names'][:] h5f.close() # load in the reanalysis data h5f = h5py.File(datapath + 'reanalysis_trends.h5', 'r') slopes = h5f['u10m/1988_2011/rean_u10m_trend_1988_2011'][:] * 120 rean = h5f['u10m/1988_2011/reanalysis_names'][:] h5f.close() # load in the CCMP data which despite filename, starts 88 ifile_ccmp = datapath + 'slope_remap_CCMP_198701-201112.nc' slope_ccmp = cd.loadvar(ifile_ccmp, 'uwnd') slope_ccmp = slope_ccmp * 120. slope_ccmp = np.ma.masked_outside(slope_ccmp, -1, 1) dims = {'lat': np.arange(-89.5, 90.1, 1), 'lon': np.arange(0, 361, 1)} fig, axa = plt.subplots(8, 2, sharex=True, sharey=True, figsize=(7, 7), squeeze=True) fig.subplots_adjust(right=0.63, hspace=0.1, wspace=0.05) vmin = -1 vmax = 1 ncols = 11 cmap_anom = brewer2mpl.get_map('RdBu', 'diverging', ncols, reverse=True).mpl_colormap cmap_anom = discrete_cmap(ncols, cmap_anom) m =\ Basemap(llcrnrlon=0,llcrnrlat=-90,urcrnrlon=360,urcrnrlat=0,projection='mill') lons, lats = np.meshgrid(dims['lon'], dims['lat']) x, y = m(lons, lats) xpt, ypt = m(20, -88.5) cot = m.pcolor(x, y, slope_ccmp, vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[0, 0], rasterized=True) axa[0, 0].text(xpt, ypt, 'CCMP') # put on reanalyses for i, r in enumerate(rean): m.pcolor(x, y, slopes[:, :, i], vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[i + 1, 0], rasterized=True) anom = slopes[:, :, i] - slope_ccmp anom = np.ma.masked_outside(anom, -1.0, 1.0) m.pcolor(x, y, anom, vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[i + 1, 1], rasterized=True) rmse = np.sqrt(np.mean(anom[0:89, :]**2)) axa[i + 1, 0].text(xpt, ypt, r.upper()) axa[i + 1, 1].text(xpt, ypt, str(np.round(rmse, 2))) # put on cmip5 m.pcolor(x, y, uas_slope_c5.mean(axis=0), vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[7, 0], rasterized=True) anom = uas_slope_c5.mean(axis=0) - slope_ccmp anom = np.ma.masked_outside(anom, -1.0, 1.0) m.pcolor(x, y, anom, vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[7, 1], rasterized=True) rmse = np.sqrt(np.mean(anom[0:89, :]**2)) c5_25_precentile = np.percentile(uas_slope_c5, 2.5, axis=0) c5_975_precentile = np.percentile(uas_slope_c5, 97.5, axis=0) ds = 4 # downsample for stippling mask = ((slope_ccmp[::ds, ::ds] > c5_975_precentile[::ds, ::ds]) | (slope_ccmp[::ds, ::ds] < c5_25_precentile[::ds, ::ds])) x2 = x[::ds, ::ds] y2 = y[::ds, ::ds] m.plot(x2[mask], y2[mask], '.k', alpha=0.75, markersize=0.2, ax=axa[7, 1], zorder=1) axa[7, 0].text(xpt, ypt, 'CMIP5 mean') axa[7, 1].text(xpt, ypt, str(np.round(rmse, 2))) for i, ax in enumerate(axa.flatten()): ax.autoscale(enable=True, axis='both', tight=True) m.drawcoastlines(linewidth=1.25, ax=ax) m.fillcontinents(color='0.8', ax=ax, zorder=2) if i % 2 == 0: m.drawparallels(np.arange(-80, 81, 20), labels=[1, 0, 0, 0], linewidth=0, ax=ax) m.drawmeridians(np.arange(0, 360, 90), labels=[0, 0, 0, 1], linewidth=0, yoffset=0.5e6, ax=axa[7, 0]) m.drawmeridians(np.arange(0, 360, 90), labels=[0, 0, 0, 1], linewidth=0, yoffset=0.5e6, ax=axa[7, 1]) box = axa[0, 0].get_position() tl = fig.add_axes( [box.x0 * 1.1 + box.width * 1., box.y0, 0.02, box.height]) bounds = np.linspace(vmin, vmax, ncols) plt.colorbar(cot, cax=tl, label='m s$^{-1}$\ndecade$^{-1}$', spacing='proportional', boundaries=bounds) fig.delaxes(axa[0, 1]) axa[0, 0].set_title('u10m trends 1988-2011') plt.savefig('../plots/uas_trend_maps_1988-2011.pdf', bbox_inches='tight', dpi=300)
import numpy as np import scipy as sp from mpl_toolkits.basemap import Basemap, addcyclic import matplotlib.pyplot as plt import matplotlib as mpl import brewer2mpl from discrete_cmap import discrete_cmap from netCDF4 import Dataset, num2date, date2num plt.ion() plt.close('all') font = {'size': 10} plt.rc('font', **font) # load in the CCMP data ifile_ccmp = '/raid/ra40/data/ncs/ccmp/ccmp_slope_199801-201112.nc' slope_ccmp_uwnd = cd.loadvar(ifile_ccmp, 'uwnd') * 120. slope_ccmp_wspd = cd.loadvar(ifile_ccmp, 'wspd') * 120. slope_ccmp_uwnd = np.ma.masked_outside(slope_ccmp_uwnd, -2, 2) slope_ccmp_wspd = np.ma.masked_outside(slope_ccmp_wspd, -2, 2) dims = {'lat': np.arange(-89.5, 90.1, 1), 'lon': np.arange(0, 361, 1)} fig, axa = plt.subplots(2, 1, sharex=True, sharey=True, figsize=(7, 7), squeeze=True) fig.subplots_adjust(right=0.825, top=0.65, hspace=0.1, wspace=0.05)
def plot_trend_maps(datapath): # Load the CMIP5 data h5f = h5py.File(datapath + 'cmip5_trends.h5','r') uas_slope_c5 = h5f['uas/1988_2011/c5_uas_trend_1988_2011'][:]*120 #names2 = h5f['uas/1988_2011/model_names'][:] h5f.close() # load in the reanalysis data h5f = h5py.File(datapath + 'reanalysis_trends.h5','r') slopes = h5f['u10m/1988_2011/rean_u10m_trend_1988_2011'][:]*120 rean = h5f['u10m/1988_2011/reanalysis_names'][:] h5f.close() # load in the CCMP data which despite filename, starts 88 ifile_ccmp = datapath + 'slope_remap_CCMP_198701-201112.nc' slope_ccmp = cd.loadvar(ifile_ccmp, 'uwnd') slope_ccmp = slope_ccmp*120. slope_ccmp = np.ma.masked_outside(slope_ccmp, -1,1) dims = {'lat' : np.arange(-89.5,90.1,1), 'lon' : np.arange(0,361,1) } fig, axa = plt.subplots(8,2, sharex=True, sharey=True, figsize=(7,7), squeeze=True) fig.subplots_adjust(right=0.63, hspace=0.1, wspace=0.05) vmin = -1 vmax = 1 ncols = 11 cmap_anom = brewer2mpl.get_map('RdBu', 'diverging', ncols, reverse=True).mpl_colormap cmap_anom = discrete_cmap(ncols, cmap_anom) m =\ Basemap(llcrnrlon=0,llcrnrlat=-90,urcrnrlon=360,urcrnrlat=0,projection='mill') lons, lats = np.meshgrid(dims['lon'], dims['lat']) x, y = m(lons, lats) xpt, ypt = m(20,-88.5) cot = m.pcolor(x, y, slope_ccmp,vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[0,0], rasterized=True) axa[0,0].text(xpt, ypt, 'CCMP') # put on reanalyses for i, r in enumerate(rean): m.pcolor(x, y, slopes[:,:,i],vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[i+1, 0], rasterized=True) anom = slopes[:,:,i] - slope_ccmp anom = np.ma.masked_outside(anom,-1.0, 1.0) m.pcolor(x, y, anom,vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[i+1, 1], rasterized=True) rmse = np.sqrt( np.mean(anom[0:89,:]**2) ) axa[i+1,0].text(xpt, ypt, r.upper()) axa[i+1,1].text(xpt, ypt, str(np.round(rmse,2))) # put on cmip5 m.pcolor(x, y, uas_slope_c5.mean(axis=0),vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[7, 0], rasterized=True) anom = uas_slope_c5.mean(axis=0) - slope_ccmp anom = np.ma.masked_outside(anom,-1.0, 1.0) m.pcolor(x, y, anom,vmin=vmin, vmax=vmax, cmap=cmap_anom, ax=axa[7, 1], rasterized=True) rmse = np.sqrt( np.mean(anom[0:89,:]**2) ) c5_25_precentile = np.percentile(uas_slope_c5,2.5, axis=0) c5_975_precentile = np.percentile(uas_slope_c5,97.5, axis=0) ds = 4 # downsample for stippling mask = ( (slope_ccmp[::ds,::ds]>c5_975_precentile[::ds,::ds]) | (slope_ccmp[::ds,::ds]<c5_25_precentile[::ds,::ds])) x2 = x[::ds,::ds] y2 = y[::ds,::ds] m.plot(x2[mask], y2[mask], '.k', alpha=0.75, markersize=0.2, ax=axa[7,1], zorder=1) axa[7,0].text(xpt, ypt, 'CMIP5 mean') axa[7,1].text(xpt, ypt, str(np.round(rmse,2))) for i, ax in enumerate(axa.flatten()): ax.autoscale(enable=True, axis='both', tight=True) m.drawcoastlines(linewidth=1.25, ax=ax) m.fillcontinents(color='0.8',ax=ax, zorder=2) if i%2 ==0: m.drawparallels(np.arange(-80,81,20),labels=[1,0,0,0], linewidth=0, ax=ax) m.drawmeridians(np.arange(0,360,90),labels=[0,0,0,1], linewidth=0,yoffset=0.5e6, ax=axa[7,0]) m.drawmeridians(np.arange(0,360,90),labels=[0,0,0,1], linewidth=0,yoffset=0.5e6, ax=axa[7,1]) box = axa[0,0].get_position() tl = fig.add_axes([box.x0*1.1 + box.width * 1., box.y0, 0.02, box.height]) bounds = np.linspace(vmin, vmax, ncols) plt.colorbar(cot, cax=tl, label='m s$^{-1}$\ndecade$^{-1}$', spacing='proportional', boundaries=bounds) fig.delaxes(axa[0,1]) axa[0,0].set_title('u10m trends 1988-2011') plt.savefig('../plots/uas_trend_maps_1988-2011.pdf', bbox_inches='tight', dpi=300)
def plot_zonmean_trends(datapath): # Load the CMIP5 data h5f = h5py.File(datapath + 'cmip5_trends.h5', 'r') psl_slope_c5 = h5f['psl/1979_2004/c5_psl_trend_1979_2004'][:] * 120 uas_slope_c5_88 = h5f['uas/1988_2011/c5_uas_trend_1988_2011'][:] * 120 uflx_slope_c5_88 = h5f[ 'tauu/1988_2011/c5_tauu_trend_1988_2011'][:] * 120 * 100 h5f.close() # load in the reanlaysis data rlc = ['k', 'y', 'g', 'b', 'c', 'm'] h5f = h5py.File(datapath + 'reanalysis_trends.h5', 'r') psl_slope_rean = h5f['slp/1979_2004/rean_slp_trend_1979_2004'][:] * 120 uas_slope_rean_88 = h5f['u10m/1988_2011/rean_u10m_trend_1988_2011'][:] * 120 uflx_slope_rean_88 = h5f[ 'uflx/1988_2011/rean_uflx_trend_1988_2011'][:] * 120 * 100 rean = h5f['uflx/1988_2011/reanalysis_names'][:] h5f.close() # The HadSLPr2 data is in the rean hdf psl_slope_hadslp = psl_slope_rean[:, :, 6] # load in the CCMP data ifile_ccmp = datapath + 'slope_remap_CCMP_198701-201112.nc' #despite name, starts 88 slope_ccmp = cd.loadvar(ifile_ccmp, 'uwnd') * 120. slope_ccmp = np.ma.masked_outside(slope_ccmp, -1, 1) uflx_slope_ccmp = cd.loadvar(ifile_ccmp, 'upstr') * 120. uflx_slope_ccmp = np.ma.masked_outside(uflx_slope_ccmp, -15, 15) uflx_slope_ccmp = uflx_slope_ccmp * 1.2 * 1.4e-3 * 120 # load in the Marshall SAM data df = pd.read_csv(datapath + 'marshall_sam.csv', index_col=0, parse_dates=True) df = pt.time_lim(df, pd.datetime(1979, 1, 1), pd.datetime(2004, 12, 31)) dft = pt.ols(df, units='decades') dims = {'lat': np.arange(-89.5, 89.6, 1), 'lon': np.arange(0, 360, 1)} fig, (axt, axm, axb) = plt.subplots(3, 1, sharex=True, figsize=(7, 7)) fig.subplots_adjust(right=0.5, hspace=0.05) modlatplot(psl_slope_c5.mean(axis=2), axt) axt.plot(dims['lat'], psl_slope_hadslp.mean(axis=(1)), 'k--', linewidth=3, label='HadSLP2r') axt.plot(dims['lat'], slope_ccmp.mean(axis=1) * np.nan, 'k-.', linewidth=3, label='CCMP') # put on the trends in marshall axt.plot(-40, dft.slp40.slope * 100.0, 'kx', markersize=15, markeredgewidth=3, zorder=10) axt.plot(-65, dft.slp65.slope * 100.0, 'kx', markersize=15, markeredgewidth=3, label='Marshall', zorder=10) modlatplot(uas_slope_c5_88.mean(axis=2), axm) axm.plot(dims['lat'], slope_ccmp.mean(axis=1), 'k-.', linewidth=3, zorder=9) modlatplot(uflx_slope_c5_88.mean(axis=2), axb) axb.plot(dims['lat'], uflx_slope_ccmp.mean(axis=1), 'k-.', linewidth=3, zorder=9) for i, r in enumerate(rean): axt.plot(dims['lat'], psl_slope_rean[:, :, i].mean(axis=1), linestyle='-', color=rlc[i], linewidth=2, label=r) axm.plot(dims['lat'], uas_slope_rean_88[:, :, i].mean(axis=1), linestyle='-', color=rlc[i], linewidth=2) axb.plot(dims['lat'], uflx_slope_rean_88[:, :, i].mean(axis=1), linestyle='-', color=rlc[i], linewidth=2) axt.legend(bbox_to_anchor=(1.6, 1), frameon=False, numpoints=1, fontsize=12) axb.set_xlabel('Latitude') ylabs = [ 'Pa decade$^{-1}$', 'm s$^{-1}$ decade$^{-1}$', r'Pa decade$^{-1}\times 10^{-2}$' ] for i, ax in enumerate((axt, axm, axb)): ax.set_xlim([-80, -20]) ax.plot([-90, 0], [0, 0], 'k-') ax.set_ylabel(ylabs[i]) axt.set_ylim([-135, 90]) axm.set_ylim([-0.325, 0.325]) axb.set_ylim([-1.5, 1.7]) xp = -78.5 axt.text(xp, 70, 'a)') axm.text(xp, 0.26, 'b)') axb.text(xp, 1.4, 'c)') xp = -43 axt.text(xp, 65, '1979-2004') axm.text(xp, 0.25, '1988-2011') axb.text(xp, 1.325, '1988-2011') plt.savefig('../plots/zonmean_trends.pdf', bbox_inches='tight', dpi=300)