[Fig. 1] Motivation for the study#

Reproduces Fig 1 of the paper

[1]:
%load_ext autoreload
%autoreload 2
import pens
import pandas as pd
import numpy as np
import xarray as xr
import pyleoclim as pyleo
import matplotlib.pyplot as plt
plt.style.use('default')
pens.set_style('journal_nogrid')

1. Reconstructions vs simulations#

[2]:
path = '../data/gmt_MCruns_ensemble_full_LMRv2.1.nc'
LMR = pens.EnsembleTS().load_nc(path, var='gmt')
LMR.label = 'LMR v2.1'
LMR.value_name = 'GMST'
LMR.value_unit = '\N{DEGREE SIGN}C'
LMR.time_unit = 'year CE'
LMR.plot_qs()
[2]:
(<Figure size 1000x400 with 1 Axes>,
 <Axes: title={'center': 'LMR v2.1'}, xlabel='time [year CE]', ylabel='GMST [°C]'>)
../_images/notebooks_eg24-Fig1_motivation_3_1.png
[3]:
df = pd.read_table('../data/PMIP3_GMST.txt')
# create a new pandas.DataFrame to store the processed data
dfn = df.copy()

# remove the data columns for CESM and GISS ensemble members
for i in range(10):
    dfn = dfn.drop([f'CESM_member_{i+1}'], axis=1)

dfn = dfn.drop(['GISS-E2-R_r1i1p127.1'], axis=1)
dfn = dfn.drop(['GISS-E2-R_r1i1p127'], axis=1)
dfn = dfn.drop(['GISS-E2-R_r1i1p121'], axis=1)

# calculate the ensemble mean for CESM and GISS, and add the results into the table
dfn['CESM'] = df[[
    'CESM_member_1',
    'CESM_member_2',
    'CESM_member_3',
    'CESM_member_4',
    'CESM_member_5',
    'CESM_member_6',
    'CESM_member_7',
    'CESM_member_8',
    'CESM_member_9',
    'CESM_member_10',
]].mean(axis=1)

dfn['GISS'] = df[[
    'GISS-E2-R_r1i1p127.1',
    'GISS-E2-R_r1i1p127',
    'GISS-E2-R_r1i1p121',
]].mean(axis=1)

# display the processed data
dfn
[3]:
Year bcc_csm1_1 CCSM4 FGOALS_gl FGOALS_s2 IPSL_CM5A_LR MPI_ESM_P CSIRO HadCM3 CESM GISS
0 850 -0.570693 -0.431830 NaN -0.620995 -0.475963 -0.170230 NaN -0.620517 0.049553 0.127429
1 851 -0.698903 -0.411177 NaN -0.753160 -0.742970 -0.303124 -0.398695 -0.553043 0.193858 0.138796
2 852 -0.575440 -0.404802 NaN -0.743508 -0.758939 -0.422623 -0.406343 -0.560791 0.185033 0.098170
3 853 -0.724757 -0.552719 NaN -0.869331 -0.746460 -0.335177 -0.353557 -0.438949 0.120470 -0.054552
4 854 -0.724328 -0.734938 NaN -0.826238 -0.684093 -0.650792 -0.416140 -0.812194 -0.081349 -0.407169
... ... ... ... ... ... ... ... ... ... ... ...
1161 2011 1.013544 NaN NaN NaN NaN NaN NaN NaN NaN NaN
1162 2012 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1163 2013 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1164 2014 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1165 2015 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

1166 rows × 11 columns

[4]:
# store each pyleoclim.Series() object into a dictionary and plot
ts_dict = {}
for name in dfn.columns[1:]:
    ts_dict[name] = pyleo.Series(
        time=dfn['Year'].values,  # the time axis
        value=dfn[name].values,   # the value axis
        label=name,                  # optional metadata: the nickname of the series
        time_name='Time',            # optional metadata: the name of the time axis
        time_unit='yrs',             # optional metadata: the unit of the time axis
        value_name='GMST',     # optional metadata: the name of the value axis
        value_unit='\N{DEGREE SIGN}C',              # optional metadata: the unit of the value axis
        verbose=False)

ts_list = [v for k, v in ts_dict.items()]  # a pythonic way to convert the pyleo.Series items in the dictionary to a list
ms_pmip = pyleo.MultipleSeries(ts_list)
fig, ax = ms_pmip.plot(lgd_kwargs={
        'bbox_to_anchor': (1.25, 1),  # move the legend to the right side
    })
../_images/notebooks_eg24-Fig1_motivation_5_0.png
[5]:
fig, ax = LMR.line_density(figsize=(8,4),xlim=(850,2000))
ms_pmip.plot(lgd_kwargs={'bbox_to_anchor': (1.25, 1)}, ax=ax, linewidth=1)
[5]:
<Axes: xlabel='Time [yrs]', ylabel='GMST [°C]'>
../_images/notebooks_eg24-Fig1_motivation_6_1.png

2. Comparing reconstructions#

[6]:
path = '../data/nhmt_MCruns_ensemble_full_LMRv2.1.nc'
LMR_nht = pens.EnsembleTS().load_nc(path, var='nhmt')
LMR_nht.label = 'LMR v2.1'
LMR_nht.time_name = 'Year CE'
LMR_nht.plot_qs(ylabel='NHT [\N{DEGREE SIGN}C]')
[6]:
(<Figure size 1000x400 with 1 Axes>,
 <Axes: title={'center': 'LMR v2.1'}, xlabel='Year CE', ylabel='NHT [°C]'>)
../_images/notebooks_eg24-Fig1_motivation_8_1.png

Now load the data from NOAA file:

[7]:
path = '../data/buentgen2021recon.txt'
df = pd.read_csv(path,skiprows=115,delimiter='\t')
df.head()
[7]:
YearCE R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 Rmean Rmed
0 1 -0.669554 -0.303244 -0.467243 -1.314425 -0.370 -0.573300 -0.685931 0.00 -0.225631 -0.379775 -0.435605 NaN -0.355480 -0.862583 -0.430486 -0.505233 -0.433045
1 2 -0.448115 -0.532993 -0.556450 -1.058694 -0.219 -0.408151 -0.787994 -0.01 -0.217959 0.194776 -0.196139 NaN -0.534690 -0.920016 0.068531 -0.401921 -0.428133
2 3 -0.519438 -0.488938 -0.572936 -1.226653 -0.154 -0.455268 -0.824891 -0.15 -0.326339 -0.144989 -0.299773 NaN -0.628520 -0.793734 -0.085305 -0.476485 -0.472103
3 4 -0.231091 -0.312583 -0.505674 -1.496090 -0.107 -0.382701 -0.723426 -0.03 -0.181019 0.031611 -0.250385 NaN -0.006623 -1.092359 0.024871 -0.375891 -0.240738
4 5 -0.585517 -0.314294 -0.558424 -1.038842 -0.080 -0.566686 -0.641757 -0.20 0.035370 -0.014277 -0.241596 NaN -0.102210 -0.967983 -0.651108 -0.423380 -0.436359
[8]:
fs = (8,4)
fig, ax = LMR_nht.line_density(ylabel='NHT (\N{DEGREE SIGN}C)',label='LMR 2.1', figsize=fs)
cols = df.columns[1:16]
clr = plt.cm.tab20b(np.linspace(0,1,len(cols))) # define colors

for i, col in enumerate(cols):
    ax.plot(df['YearCE'],df[col],lw=1,alpha=0.2,color=clr[i],label=col)

LMR_nht.get_median().plot(color='black', linewidth=1, label = 'LMR 2.1 median', ax=ax)
ax.set_ylim(-3, 1)
ax.set_ylabel('NHT (\N{DEGREE SIGN}C)')
ax.legend(ncol=5, frameon=True, framealpha=0.5)
ax.set_title("a)",loc='left')
plt.tight_layout()
#fig.savefig('../figures/nht_comparison_spaghetti.pdf')
../_images/notebooks_eg24-Fig1_motivation_11_0.png
[9]:
fig, ax = LMR_nht.line_density(ylabel='NHT (\N{DEGREE SIGN}C)',label='LMR 2.1')
ax.plot(df['YearCE'],df['Rmed'],lw=1,alpha=0.6,color='tab:red',label='Büntgen et al (2021), median')
ax.set_ylim(-2, 1)
ax.legend()
ax.set_title("b)",loc='left')
fig.set_size_inches(9,4)
#fig.savefig('../figures/nht_comparison_density.pdf')
../_images/notebooks_eg24-Fig1_motivation_12_0.png

Assembling Figure 1#

[10]:
_ , ylabel = LMR.make_labels()
xlabel = 'Year CE'
fig, axs = plt.subplots(3,1,figsize = (8,10),sharex=True)
# panel a
LMR.line_density(ax=axs[0],ylim=[-.75,.75])
LMR.get_median().plot(color='gold',label='median',ax=axs[0])
lgd1 = axs[0].legend(ncol=2, loc='upper left')
axs[0].add_artist(lgd1)
LMR.plot_traces(ax=axs[0], indices = [9,89], alpha=0.65,
                xlabel = '', ylabel=ylabel, xlim=[1,2000])
axs[0].set_title('a) ' + LMR.label + ' distribution and traces',
                 fontweight='bold', loc='left')

# panel b
LMR.line_density(ax=axs[1]) #xlim=(850,2000)
ms_pmip.plot(ax=axs[1], linewidth=1, xlabel = '', lgd_kwargs=
             {'bbox_to_anchor': (0.3, 0.95), 'frameon':True,
              'framealpha':1.0, 'fontsize':9})
axs[1].set_title('b) Comparison to PMIP3 models', fontweight='bold', loc='left')

# panel c
LMR_nht.line_density(ax=axs[2],ylabel='NHT [\N{DEGREE SIGN}C]',label='LMR 2.1')
axs[2].plot(df['YearCE'],df['Rmed'],lw=1,alpha=0.6,color='tab:red',label='Büntgen et al (2021), median')
axs[2].set_ylim(-1.5, 1)
axs[2].legend()
axs[2].set_title('c) Comparison to other reconstructions', fontweight='bold', loc='left')
[10]:
Text(0.0, 1.0, 'c) Comparison to other reconstructions')
../_images/notebooks_eg24-Fig1_motivation_14_1.png
[11]:
fig.savefig('../figures/Fig1_motivation.pdf',dpi=300)

Let’s export the top panel for inclusion in presentations:

[12]:
fig_a, ax = plt.subplots(1,1,figsize = (8,3))
LMR.line_density(ax=ax,ylim=[-.75,.75])
LMR.plot_traces(ax=ax, indices = [9,89], alpha=0.65, xlim=[1,2000])
ax.set_title(LMR.label + ' distribution and traces',
                 fontweight='bold', loc='left')
ax.set_xlabel(xlabel)
[12]:
Text(0.5, 0, 'Year CE')
../_images/notebooks_eg24-Fig1_motivation_17_1.png

NB: indices are NOT quantiles. This particular example is somewhat of a fluke.