Created by Ivan Lima on Mon Oct 11 2021 08:54:21 -0400
import xarray as xr
import pandas as pd
import numpy as np
import holoviews as hv
import os, datetime, my_bokeh_themes
import hvplot.pandas
from cesm_utils import fixtime, spd
print('Last updated on {}'.format(datetime.datetime.now().ctime()))
Last updated on Wed Jul 20 11:41:17 2022
from bokeh.plotting import show
hv.extension('bokeh')
from pencil_cases import *
datadir = '/home/ivan/Data/Postproc/1DPOP_CESM2'
# datadir = '/mnt/chromeos/removable/WD/Data/Postproc/1DPOP_CESM2/'
start_yr = 1851 # use "real" year to keep pandas datetime functionality
case_list = ['cesm2.B1850.f09_g17.1dpop.010', 'cesm2.B1850.f09_g17.1dpop.011', 'cesm2.B1850.f09_g17.1dpop.012',
'cesm2.B1850.f09_g17.1dpop.013', 'cesm2.B1850.f09_g17.1dpop.014', 'cesm2.B1850.f09_g17.1dpop.015']
for case in case_list:
print('{}: {}'.format(case, case_info[case]))
def plot_tseries(region, varname):
# read time series data
data_dict = {}
cols = []
for case in case_list:
col_name = '.'.join(case.split('.')[-2:])
cols.append(col_name)
with xr.open_dataset(os.path.join(datadir, '{}.ts_{}.nc'.format(case, region)),
decode_times=False) as ds:
ds = fixtime(ds, start_yr)
ds['time'] = ds.time.to_index().to_datetimeindex()
# convert to annual averages
data_dict[col_name] = ds[varname].resample(time='A').mean().to_series()
df = pd.DataFrame(data_dict)
df.columns.name = 'Case'
ds_ctrl = xr.open_dataset(os.path.join(datadir, 'b.e21.B1850.f09_g17.CMIP6-piControl.001.ts_{}.nc'.format(region)),
decode_times=False)
mean = ds_ctrl[varname].mean(dim='time').values.item()
std = ds_ctrl[varname].std(dim='time').values.item()
df['pi control'] = mean
df['lo'] = mean - std
df['hi'] = mean + std
df['min'] = ds_ctrl[varname].min(dim='time').values.item()
df['max'] = ds_ctrl[varname].max(dim='time').values.item()
# create plots
aspect, height = 1.1, 350
p_tseries = df[cols + ['pi control']].hvplot(aspect=aspect, frame_height=height, grid=True, shared_axes=False,
xlabel='time', ylabel='{}'.format(ds[varname].units),title=varname)
p_std = df[['lo','hi']].hvplot.area(y='lo', y2='hi', alpha=0.2, shared_axes=False, aspect=aspect, frame_height=height,
grid=True, color='green')
p_minmax = df[['min','max']].hvplot.area(y='min', y2='max', alpha=0.2, shared_axes=False, aspect=aspect, frame_height=height,
grid=True,color='lightgreen')
return p_tseries * p_std * p_minmax
ds = xr.open_dataset(os.path.join(datadir, '{}.ts_near_global.nc'.format(case_list[0])), decode_times=False)
cesm2.B1850.f09_g17.1dpop.010: 1D + T, S, U & V restoring (tau = 15 days) + EBM off + start year = 1161 cesm2.B1850.f09_g17.1dpop.011: 1D + G-terms (corrected) + SSS restoring (tau = 30 days) + EBM off + start year = 1161 cesm2.B1850.f09_g17.1dpop.012: 1D + G-terms (corrected) + SSS restoring (tau = 365 days) + EBM off + start year = 1161 cesm2.B1850.f09_g17.1dpop.013: 1D + G-terms (corrected) + SSS restoring (tau = 30 days) + EBM off + start year = 6 restoring run cesm2.B1850.f09_g17.1dpop.014: 1D + G-terms (corrected) + SSS restoring (tau = 365 days) + EBM off + start year = 6 restoring run cesm2.B1850.f09_g17.1dpop.015: 1D + T, S, U & V restoring (tau = 30 days) + EBM off + start year = 1161
The green shaded areas in the plots below represent the pi control mean plus/minus one standard deviation: $\bar{x} \pm \sigma$. The light green shaded area represents the pi control min and max range.
plist_ng = hv.Layout()
for vname in ds.data_vars.keys():
plist_ng += plot_tseries('near_global',vname)
show(hv.render(plist_ng.cols(2).opts(shared_axes=False)))
plist_na = hv.Layout()
for vname in ds.data_vars.keys():
plist_na += plot_tseries('north_atl',vname)
show(hv.render(plist_na.cols(2).opts(shared_axes=False)))
plist_tp = hv.Layout()
for vname in ds.data_vars.keys():
plist_tp += plot_tseries('trop_pac',vname)
show(hv.render(plist_tp.cols(2).opts(shared_axes=False)))
plist_ls = hv.Layout()
for vname in ds.data_vars.keys():
plist_ls += plot_tseries('lab_sea',vname)
show(hv.render(plist_ls.cols(2).opts(shared_axes=False)))
plist_ar = hv.Layout()
for vname in ds.data_vars.keys():
plist_ar += plot_tseries('arctic',vname)
show(hv.render(plist_ar.cols(2).opts(shared_axes=False)))
plist_so = hv.Layout()
for vname in ds.data_vars.keys():
plist_so += plot_tseries('socean',vname)
show(hv.render(plist_so.cols(2).opts(shared_axes=False)))
def plot_annual_cycle(region, varname):
# read time series data
data_dict = {}
cols = []
for case in case_list:
col_name = '.'.join(case.split('.')[-2:])
cols.append(col_name)
with xr.open_dataset(os.path.join(datadir, '{}.ts_{}.nc'.format(case, region)),
decode_times=False) as ds:
ds = fixtime(ds, start_yr)
ds['time'] = ds.time.to_index().to_datetimeindex()
# convert to monthly climatology
data_dict[col_name] = ds[varname].groupby(ds.time.dt.month).mean().to_series()
df = pd.DataFrame(data_dict)
# create plots
aspect, height = 1.1, 350
p_tseries = df.hvplot(aspect=aspect, frame_height=height, grid=True, shared_axes=False, xlabel='month',
ylabel='{}'.format(ds[varname].units),title=varname)
return p_tseries
plist_ng = hv.Layout()
for vname in ds.data_vars.keys():
plist_ng += plot_annual_cycle('near_global',vname)
show(hv.render(plist_ng.cols(2).opts(shared_axes=False)))
plist_na = hv.Layout()
for vname in ds.data_vars.keys():
plist_na += plot_annual_cycle('north_atl',vname)
show(hv.render(plist_na.cols(2).opts(shared_axes=False)))
plist_tp = hv.Layout()
for vname in ds.data_vars.keys():
plist_tp += plot_annual_cycle('trop_pac',vname)
show(hv.render(plist_tp.cols(2).opts(shared_axes=False)))
plist_ls = hv.Layout()
for vname in ds.data_vars.keys():
plist_ls += plot_annual_cycle('lab_sea',vname)
show(hv.render(plist_ls.cols(2).opts(shared_axes=False)))
plist_ar = hv.Layout()
for vname in ds.data_vars.keys():
plist_ar += plot_annual_cycle('arctic',vname)
show(hv.render(plist_ar.cols(2).opts(shared_axes=False)))
plist_so = hv.Layout()
for vname in ds.data_vars.keys():
plist_so += plot_annual_cycle('socean',vname)
show(hv.render(plist_so.cols(2).opts(shared_axes=False)))
# import panel as pn
# row = pn.Row(plist_so.cols(2).opts(shared_axes=False))
# row.embed()
# display(plist_so.cols(2).opts(shared_axes=False))