Salinity min, max and range

Created by Ivan Lima on Mon Aug 24 2020 09:02:31 -0400

In [1]:
%matplotlib inline
import xarray as xr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os, datetime, warnings, cmocean
from matplotlib import colors
from cesm_utils import fixtime, da2ma, spd
from mpl_utils import center_cmap
warnings.filterwarnings('ignore')
plt.rcParams['figure.dpi'] = 100
print('Last updated on {}'.format(datetime.datetime.now().ctime()))
Last updated on Fri Sep  4 13:21:37 2020

Map of absolute min values

In [2]:
from cartopy import crs as ccrs
from cartopy import feature as cfeature

datadir = '/media/ivan/WD/Data/Postproc/1DPOP'

ds_2D_min = xr.open_dataset(os.path.join(datadir, 'cesm.1dpop.07.abs.min_2D.nc'), decode_times=False)
ds_2D_min = fixtime(ds_2D_min, 2051)

tlat, tlon = ds_2D_min.TLAT, ds_2D_min.TLONG
tlat, tlon = np.c_[tlat,tlat[:,0]], np.c_[tlon,tlon[:,0]]

def surf_map(da, title, cmap=plt.cm.viridis, log=False, center_cm=False, vmin=None):
    fig, ax = plt.subplots(subplot_kw={'projection':ccrs.Robinson(central_longitude=210)}, figsize=(9,6.4))
    ax.set_global()
    ax.coastlines(linewidth=0.5)
    if log:
        norm = norm=colors.LogNorm()
    else:
        norm = None    
    pm = ax.pcolormesh(tlon, tlat, da, transform=ccrs.PlateCarree(), norm=norm, cmap=cmap, vmin=vmin)
    if center_cm:
        center_cmap(pm)
#     print(pm.get_clim())
    _ = ax.set_title('{} absolute {}'.format(da.name, title))
    cb = fig.colorbar(pm, ax=ax, orientation='horizontal', pad=0.05)
    cb.set_label(ds_2D_min[da.name].units)

da_min = ds_2D_min['SALT'].min(dim=['time'])
# da_min = da_min.where(da_min<40)
surf_map(da_min, 'min', cmocean.cm.haline, vmin=20)

Map of absolute max values

In [3]:
ds_2D_max = xr.open_dataset(os.path.join(datadir, 'cesm.1dpop.07.abs.max_2D.nc'), decode_times=False)
ds_2D_max = fixtime(ds_2D_max, 2051)

da_max = ds_2D_max['SALT'].max(dim=['time'])
surf_map(da_max, 'max', cmocean.cm.haline, vmin=30)

Map of absolute max - absolute min

In [4]:
da = da_max - da_min
surf_map(da, 'range', cmocean.cm.balance, center_cm=True)

Position of absolute min values

In [5]:
stacked = ds_2D_min.SALT.stack(z=('nlat','nlon'))
ntime = ds_2D_min.dims['time']

minind = stacked.argmin(axis=1)
minpos = stacked['z'][minind]
imin = [minpos.values[t][0] for t in range(ntime)]
jmin = [minpos.values[t][1] for t in range(ntime)]
lonmin = [minpos.TLONG[t].item() for t in range(ntime)]
latmin = [minpos.TLAT[t].item() for t in range(ntime)]

minlon, maxlon = 5, 30
minlat, maxlat =  52, 66
lonc = (minlon + maxlon)/2.
latc = (minlat + maxlat)/2.
proj = ccrs.EquidistantConic(central_longitude=lonc,central_latitude=latc)
# proj = ccrs.PlateCarree()

# fig, ax = plt.subplots(subplot_kw={'projection':ccrs.Robinson(central_longitude=210)}, figsize=(9,6.4))
# ax.set_global()
# ax.add_feature(cfeature.LAND, facecolor='#b0b0b0')
fig, ax = plt.subplots(subplot_kw={'projection':proj}, figsize=(9,6.4))
ax.set_extent([minlon,maxlon,minlat,maxlat])
ax.coastlines(linewidth=0.5)
gl = ax.gridlines(xlocs=np.arange(-180,180,10),ylocs=np.arange(0,90,5),draw_labels=True)
gl.xlabels_top, gl.ylabels_right = False, False
da_min_baltic = da_min.where(ds_2D_min.REGION_MASK<0)
pm = ax.pcolormesh(tlon, tlat, da_min_baltic, transform=ccrs.PlateCarree(), cmap=cmocean.cm.haline,
                   vmin=4.25, vmax=7.5)
for lon, lat in sorted(set([p for p in zip(lonmin,latmin)])):
    print('lat = {:.2f}N, lon = {:.2f}E'.format(lat, lon))
    _ = ax.plot(lon, lat, 'C3o', transform=ccrs.PlateCarree(), alpha=0.75)

_ = ax.set_title('position of salinity minima')
cb = fig.colorbar(pm, ax=ax, orientation='vertical')
cb.set_label(ds_2D_min.SALT.units)
lat = 55.09N, lon = 10.44E
lat = 54.65N, lon = 10.60E
lat = 54.33N, lon = 11.81E
lat = 54.46N, lon = 12.86E
lat = 55.04N, lon = 13.74E
lat = 54.13N, lon = 14.07E
lat = 54.39N, lon = 16.17E
lat = 62.57N, lon = 18.24E
lat = 61.05N, lon = 18.29E
lat = 60.14N, lon = 18.90E
lat = 59.68N, lon = 19.18E
lat = 62.74N, lon = 19.21E
lat = 54.78N, lon = 19.34E
lat = 61.83N, lon = 19.94E
lat = 62.91N, lon = 20.18E
lat = 59.38N, lon = 20.47E
lat = 63.08N, lon = 21.16E
lat = 57.99N, lon = 21.24E
lat = 59.54N, lon = 21.49E
lat = 59.07N, lon = 21.76E
lat = 64.80N, lon = 21.78E
lat = 64.98N, lon = 22.73E
lat = 64.52N, lon = 23.20E
lat = 59.85N, lon = 23.53E
lat = 59.39N, lon = 23.81E
lat = 59.54N, lon = 24.84E
lat = 69.45N, lon = 65.66E
lat = 0.40N, lon = 310.44E
lat = 0.67N, lon = 310.44E

Time series of absolute min values

In [6]:
ds_min = xr.open_dataset(os.path.join(datadir, 'cesm.1dpop.07.abs.min.nc'), decode_times=False)
ds_min = fixtime(ds_min, 2051)
ds_min['time'] = ds_min.time.to_index().to_datetimeindex()

fig, ax = plt.subplots()
_ = ds_min.SALT.to_series().plot(ax=ax)
_ = ax.set(title='SALT absolute min', ylabel=ds_min['SALT'].units)