commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -1460,159 +1503,159 @@
 def calc_model_mean(cfg, short_names_in, data_dict):
 
     debug = False
     calculate_model_mean = True
     if calculate_model_mean:
         short_names, exps, datasets = {}, {}, {}
         for (dataset, short_name, exp, ensemble) in  data_dict.keys():
             if mod_exp_ens_skips.get((dataset, exp, ensemble), False):
                 continue
             if exp == 'ssp534-over': continue
 
             # if dataset in data_dict_skips.keys():
             #     if ensemble in data_dict_skips[dataset]:
             #         continue
             if short_name in ['areacello', 'areacella']:continue
             if short_name not in short_names_in:continue
             if dataset in ['CMIP6', ]: continue
             short_names[short_name] = True
             exps[exp] = True
             datasets[dataset] = True
 
         print(calc_model_mean,short_names, exps, datasets)
         for short_name, exp, dataset in product(short_names.keys(), exps.keys(), datasets.keys()):
             if short_name in ['areacello', 'areacella']:
                 continue
             if short_name not in short_names_in:continue
 
             if dataset in ['CMIP6', ]: continue
             if debug:
                 if dataset == 'ACCESS-ESM1-5' and exp == 'ssp126' and short_name =='tas': pass
                 else: continue
             else:
                 if  data_dict.get((dataset, short_name, exp, 'ensemble_mean'), False): # exists already
                     continue
 
             print('calculate_model_mean',  short_name, exp, dataset)
             cubes = []
             for (dataset_i,short_name_i, exp_i, ensemble_i),cube in  data_dict.items():
                 if dataset != dataset_i: continue
                 if short_name != short_name_i: continue
                 if exp_i != exp: continue
                 if ensemble_i == 'ensemble_mean': continue
                 if short_name in ['co2', 'luegt', 'tls', 'atmos_carbon']: # 'emissions', 'cumul_emissions',
                      pass
                      #continue
                 #rint("calculate_model_mean: including:", dataset_i,short_name_i, exp_i, ensemble_i)
                 else:
                     cube = regrid_time(cube, 'yr')
                 cubes.append(cube)
 
             if debug: print('debug', short_name, exp, dataset, len(cubes)) #ubes)
             if not len(cubes):
                 continue
 
             if len(cubes) == 1:
                 data_dict[(dataset, short_name, exp, 'ensemble_mean')] = cubes[0]
                 data_dict[(dataset, short_name, exp, 'ensemble_min')] = cubes[0]
                 data_dict[(dataset, short_name, exp, 'ensemble_max')] = cubes[0]
 
 
                 continue
             if isinstance(cubes[0], dict):
                 data_dict[(dataset, short_name, exp, 'ensemble_mean')] = make_mean_of_dict_list(cubes, short_name)
                 data_dict[(dataset, short_name, exp, 'ensemble_min')] = make_mean_of_dict_list(cubes, short_name, metric='min')
                 data_dict[(dataset, short_name, exp, 'ensemble_max')] = make_mean_of_dict_list(cubes, short_name, metric='max')
             else:
                 data_dict[(dataset, short_name, exp, 'ensemble_mean')] = make_mean_of_cube_list(cubes)
                 data_dict[(dataset, short_name, exp, 'ensemble_min')] = make_mean_of_cube_list(cubes, metric='min')
                 data_dict[(dataset, short_name, exp, 'ensemble_max')] = make_mean_of_cube_list(cubes, metric='max')
 
             if debug:
                 print('debug:, mean cube data:', data_dict[(dataset, short_name, exp, 'ensemble_mean')].data)
                 for c,cu  in enumerate(cubes):
                     print('debug:',c, cu.data)
 
             # test:
             if len(cubes) > 1:
                 for c,cu in enumerate(cubes):
                     if isinstance(cu, dict):continue
                     if np.array_equal(data_dict[(dataset, short_name, exp, 'ensemble_mean')].data, cu.data):
                         print('ERROR: ensemble mean cube is identical to one of the input cubes.')
                         print('mean cube:', data_dict[(dataset, short_name, exp, 'ensemble_mean')].data[:3], '...')
                         print('mean cube:', cu.data[:3], '...')
                         print('source:', short_name, exp, dataset, len(cubes))
                         assert 0
 
     #print_data_dict(data_dict)
     #save_data_dict(data_dict, data_dict_shelve)
     #assert 0
 
     calculate_cmip6_mean = True
     if calculate_cmip6_mean:
         # Calculate the mean of multiple datasets ensemble_means
         short_names, exps, datasets = {}, {}, {}
         for (dataset, short_name, exp, ensemble) in  data_dict.keys():
             if short_name in ['areacello', 'areacella']:continue
             if short_name not in short_names_in:continue
 
             if mod_exp_ens_skips.get((dataset, exp, ensemble), False):
                 continue
             if exp == 'ssp534-over': continue
 
             # if dataset in data_dict_skips.keys():
             #     if ensemble in data_dict_skips[dataset]:
             #         continue
 
             short_names[short_name] = True
             exps[exp] = True
             datasets[dataset] = True
 
         for short_name, exp in product(short_names.keys(), exps.keys()):
             cubes = []
             if short_name in ['areacello', 'areacella']:continue
             print("calculate_cmip6_mean: including:", short_name, exp)
             if data_dict.get(('CMIP6', short_name, exp, 'ensemble_mean'), False): continue
 
             for (dataset_i,short_name_i, exp_i, ensemble_i),cube in  data_dict.items():
                 if dataset_i == 'CMIP6': continue
                 if short_name != short_name_i: continue
                 if exp_i != exp: continue
                 if ensemble_i != 'ensemble_mean': continue
                 if short_name in ['co2', 'luegt', 'tls', 'atmos_carbon']: #  'emissions', 'cumul_emissions',
                      pass #ue
                 else:
                     cube = regrid_time(cube, 'yr')
                 cubes.append(cube)
                 print("calculate_cmip6_mean: including:", dataset_i,short_name_i, exp_i, ensemble_i)
 
             print('calculate_cmip6_mean:', short_name, exp, len(cubes))
             if not len(cubes):
                 continue
             if len(cubes) == 1:
                 data_dict[('CMIP6', short_name, exp, 'ensemble_mean')] = cubes[0]
                 continue
 
             print('calculating:make_mean_of_cube_list', ('CMIP6', short_name, exp, 'ensemble_mean'))
             if isinstance(cubes[0], dict):
                 data_dict[('CMIP6', short_name, exp, 'ensemble_mean')] = make_mean_of_dict_list(cubes, short_name)
                 data_dict[('CMIP6', short_name, exp, 'ensemble_min')] = make_mean_of_dict_list(cubes, short_name, metric='min')
                 data_dict[('CMIP6', short_name, exp, 'ensemble_max')] = make_mean_of_dict_list(cubes, short_name, metric='max')
             else:
                 data_dict[('CMIP6', short_name, exp, 'ensemble_mean')] = make_mean_of_cube_list(cubes)
                 data_dict[('CMIP6', short_name, exp, 'ensemble_min')] = make_mean_of_cube_list(cubes, metric='min')
                 data_dict[('CMIP6', short_name, exp, 'ensemble_max')] = make_mean_of_cube_list(cubes, metric='max')
 
-#    if 'tls' in short_names_in:
-#        data_dict = calc_tls(cfg, data_dict)
+    if 'tls' in short_names_in: # calculate it again to make sure there's ensemble_min, max.
+        data_dict = calc_tls(cfg, data_dict)
         #rint(data_dict.keys())
 
 #    if 'atmos_carbon' in short_names_in:
 #        data_dict = calc_atmos_carbon(cfg, data_dict)
 
         #rint(data_dict.keys())
 
     #print_data_dict(data_dict)
     #assert 0
     return data_dict
 
 
commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -935,96 +950,124 @@
 def calculate_cumulative(data_dict, short_name, cumul_name, new_units=''):
     """
     Calculate the cumulative sum of the annual data.
     """
     hist_datas = {}
     tmp_dict={}
     for (dataset, short, exp, ensemble), cube in data_dict.items():
         if short_name != short:
             continue
         if exp not in ['historical', ]:
             continue
         print('calculate_cumulative', (dataset, short, exp, ensemble)) #, cube.units)
         hist_cumul_cube = cube.copy()
         times = diagtools.cube_time_to_float(hist_cumul_cube)
         #print(hist_cumul_cube.data)
         #print(np.cumsum(np.ma.masked_invalid(hist_cumul_cube.data)))
 
         hist_cumul_cube.data = np.cumsum(np.ma.masked_invalid(hist_cumul_cube.data))
         tmp_dict[(dataset, cumul_name, exp, ensemble)] = hist_cumul_cube
         print('adding to hist_datas:', (dataset, ensemble))
         hist_datas[(dataset, ensemble)] = {'time': times, 'data': hist_cumul_cube.data}
 
     # For models (like UKESM), where the hist and ssp have different ensemble ids:
     for mod, ens in data_dict_linked_hist.items():
         print(mod, ens)
         for ens_ssp, ens_hist in ens.items():
              print(mod, ens_ssp, ens_hist)
              hist_datas[(mod, ens_ssp)] = hist_datas[(mod, ens_hist)]
 
-    #calculate the cumulative value, and add the historical point to it.
     # Fails are ensembles thaqt need to be ignored to
     fails = {}
+
+    # Look to see if any historical ensemble members do not have any future scenarios associated with them.
+    exps_check =  ['ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
+    do_hist_check= False
+    for (dataset, short, exp, ensemble), cube in data_dict.items():
+        if not do_hist_check: continue
+        if short_name != short:
+            continue
+        if exp not in ['historical', ]: continue
+        counts = 0.
+        if dataset in data_dict_linked_hist: continue
+        for exp2 in exps_check:
+            if data_dict.get((dataset, short, exp2, ensemble), False):
+                continue
+            counts+=1
+        if counts == len(exps_check):
+            fails[(dataset, exp, ensemble)] = True
+            print('Did not find and spps:', (dataset, short, exp, ensemble))
+    if len(fails.keys()):
+        print ('Add this to the list at the start of this code:')
+        for ind, bol in fails.items():
+            print('     ', ind, ': True, # historical without any ssps!')
+        assert 0
+
+
+    #calculate the cumulative value, and add the historical point to it.
+
     for (dataset, short, exp, ensemble), cube in data_dict.items():
         if short_name != short:
             continue
         if exp in ['historical', ]:
             continue
         print('calculate_cumulative', (dataset, short, exp, ensemble), cube.data.shape )
         cumul_cube = cube.copy()
         times = diagtools.cube_time_to_float(cumul_cube)
         #f isinstance(ensemble, str):
         hist_dat = hist_datas.get((dataset,ensemble), False)
         if fails.get((dataset, exp, ensemble), False): continue
         if hist_dat is False:
             print('looking for ', ensemble)
             hist_dat = hist_datas.get((dataset,ensemble), False)
             for ens in ensemble:
                 if hist_dat: continue
                 #if len(hist_dat): continue
                 hist_dat = hist_datas.get((dataset, ens), False)
             #if not hist_dat:
                 print('unable to find', (dataset, exp, ensemble))
             #    assert 0
         if hist_dat is False:
             print('failed:', cube)
             print('Unable to find hist_dat:', (dataset, short, exp, ensemble))
             for (dax, shortx, expx, ensemblex) in data_dict.keys():
                 if dax != dataset: continue
                 if shortx != short_name: continue
                 #if expx != 'historical': continue
                 print('candidates:', (dax, shortx, expx, ensemblex))
             #ssert 0
             fails[(dataset, exp, ensemble)] = True
             continue
 
         hist_point = get_threshold_point(hist_dat, np.min(times))
         print('found hist point:', hist_point, hist_dat['data'][hist_point], np.min(times))
         if hist_point is None:
             print('Problem with hist point:', hist_point)
             print('hist_dat:', hist_dat)
             print('times', times)
             assert 0
         hist_cumul = hist_dat['data'][hist_point]
 
         #hist_point = get_threshold_point(hist_datas[ensemble], np.min(times))
         #hist_cumul = hist_datas[ensemble]['data'][hist_point]
         print('iter 4:', cumul_cube.data.shape, hist_cumul.shape)
 
         cumul_cube.data = cumul_cube.data
         print(hist_cumul, np.cumsum(np.ma.masked_invalid(cumul_cube.data)), times)
         print((dataset, short, exp, ensemble))
         print('iter 5:', cumul_cube.data.shape, hist_cumul.shape)
         cumul_cube.data = np.cumsum(np.ma.masked_invalid(cumul_cube.data)) + hist_cumul
 
         if len(new_units) >0:
             cumul_cube.units = cf_units.Unit(new_units)
         tmp_dict[(dataset, cumul_name, exp, ensemble)] = cumul_cube
+
+
     if len(fails.keys()):
         print ('Add this to the list at the start of this code:')
         for ind, bol in fails.items():
             print('     ', ind, ': True, # No historical run on jasmin')
         assert 0
     data_dict.update(tmp_dict)
     return data_dict
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4966,226 +5068,243 @@
-def do_ecs_scatterplot(cfg, data_dict, thresholds_dict, x_axis = 'ecs', fig = None, ax = None):
+def do_ecs_scatterplot(cfg, data_dict, thresholds_dict, x_axis = 'ecs', include_1=False, fig = None, ax = None):
 
     save_single_plot= False
     if fig is None or ax is None:
         fig = plt.figure()
         fig.set_size_inches(8, 7)
         gs = gridspec.GridSpec(1, 2, figure=fig, hspace=0.5, width_ratios=[6,1])
         ax = fig.add_subplot(gs[0, 0])
         ax_leg = fig.add_subplot(gs[0, 1])
         save_single_plot = True
     plt.sca(ax)
         #gs = gridspec.GridSpec(2, 3, figure=fig, hspace=0.5)
 
     model_colours = {'CMIP6': 'black'}
 
     datasets = {}
     exps = {}
     for (dataset, short_name, exp, ensemble), thresholds in thresholds_dict.items():
         if model_colours.get(dataset, False): continue
         datasets[dataset] = True
 
     cmap = mplcm.get_cmap('jet')
     for i,dataset in enumerate(sorted(datasets)):
         model_colours[dataset] = cmap(float(i)/(len(datasets)-1.))
 
-    marker_styles = {1.5: None, 2.: 's', 3.: 'o', 4:'^', 5.:None}
+    #threshold_marker_styles = {1.: 'v', 1.5: None, 2.: 's', 3.: 'o', 4:'^', 5.:None}
 
 #    if x_axis == 'emissions':
 #        short_name_1 = ''
     if x_axis == 'ecs':
         short_name_1='ecs'
         ECS_data = load_ecs_data()
 
     ensemble_alpha = {'ensemble_mean':1.}
     sizes = {'ensemble_mean':60}
     gaps = {}
     linregdat = {}
     for (dataset, short_name, exp, ensemble), thresholds in thresholds_dict.items():
         if short_name != 'tas': continue
         if ensemble != 'ensemble_mean': continue
         if ensemble in ['ensemble_min', 'ensemble_max']: continue
         if dataset == 'CMIP6': continue
         exps[exp] = exp_colours_fill[exp]
         model_colour = model_colours[dataset]
         exp_colour = exp_colours_fill[exp]
         #dgecolor= exp_colours_fill[exp]
         alpha= ensemble_alpha.get(ensemble, 1.  )
         #data = data_dict[(dataset, short_name_1, exp, ensemble)]
         if x_axis == 'ecs':
             model_ecs = ECS_data[dataset]
 
         for threshold, time in thresholds.items():
+            if not include_1 and int(threshold)==1: continue
 #           if time is None: continue # no GWT.
-            ms = marker_styles.get(threshold, None)
+            ms = threshold_marker_styles.get(threshold, None)
             size = sizes.get(ensemble, 60 )
             if dataset == 'CMIP6': size = 100.
 
             if ms == '^': size = size*1.3
 
             if not ms: continue
             if threshold==2. and time is None:
 #                x = 2105
                 y = model_ecs
                 print('gap', (dataset, short_name, exp, ensemble), threshold, time)
                 gaps[(dataset, exp)]= model_ecs
                 #s = 'x'
 #                plt.scatter(x,y, c = (0,0,0,0), edgecolor=exp_colour, linewidth=2, marker = ms, alpha = 0.7, s=size, zorder=1)
                 continue
             if time is None: continue
             x = time.year + 0.5
             y =model_ecs
 
             plt.scatter(x,y, c = exp_colour, marker = ms, alpha = alpha, s=size, zorder=1)
             if linregdat.get((exp, threshold), False):
                 linregdat[(exp, threshold)].append((x,y))
             else:
                 linregdat[(exp, threshold)] = [(x,y), ]
 
             #plt.scatter(x,y, c = colour, marker = ms, edgecolor=edgecolor, linewidth=2.5, alpha = alpha, s=size, zorder=1)
-    xlims = [2000., 2100.,]
+    if include_1:
+        xlims = [1970., 2100.,]
+    else: 
+        xlims = [2000., 2100.,]
     # outside plot dots.
     x_times = {dataset:2105 for dataset in datasets}
     for (dataset, exp) in sorted(gaps.keys()):
         if exp == 'historical': continue
         y = gaps[(dataset, exp)]
         x = x_times[dataset]
         if x > xlims[1]: xlims[1] = x +5.
         exp_colour = exp_colours_fill[exp]
 
         plt.scatter(x,y, c = 'w', edgecolor=exp_colour, linewidth=2, marker = 'D', s=60, zorder=1)
         x_times[dataset] += 5.
 
     # vertical line
     plt.axvline(2100, c='k', ls='-', lw=1., zorder=-1)
     ylims = ax.get_ylim()
 
     # Add linear regression lines:
     fn = cfg['work_dir']+'/new_recipe.yml'
-
     fn = diagtools.folder([cfg['plot_dir'], 'ecs_scatter',])
-    fn += '_'.join(['ecs_vs_time',]) + '.txt'
+    if include_1:
+        fn += '_'.join(['ecs_vs_time','1gwt']) + '.txt'
+    else:
+        fn += '_'.join(['ecs_vs_time',]) + '.txt'
     txt = '    \\begin{tabular}{|ll|ccccc|}\n'
     txt = latexhline(txt)
     txt += latexrow(['SSP', 'GWT', 'Slope, ','Inverse slope', 'R', 'err', 'N'])
     txt = latexendline(txt)
     txt = latexhline(txt)
 
 # latexendline = lambda a: ''.join([a, '\\\\', '\n'])
 # latexhline = lambda a: ''.join([a, '\hline', '\n'])
 # latexrow = lambda a: ' & '.join(a)
 
-
-    line_styles = {2:'dashed', 3.:'dashdot', 4.:'dotted',}
+    line_styles = {1.: 'solid',2:'dashed', 3.:'dashdot', 4.:'dotted',}
     for (exp, threshold) in sorted(linregdat.keys()):
         xy_dats = linregdat[(exp, threshold)]
         xy_dats = sorted(xy_dats)
         x_es = [x for (x,y ) in xy_dats]
         y_es = [y for (x,y ) in xy_dats]
         if len(x_es) <2: continue
 
         # lines between  data
         #plt.plot(x_es, y_es, c=exp_colour, lw=0.7)
 
         # linear regression
 
         linr = scipy.stats.linregress(x_es, y_es)
         slope, intercept = linr[0], linr[1]
         if np.isnan(slope): continue
         txt += latexrow([ exp, str(threshold),
                          str(linr[0])[:7],
                          str(1./linr[0])[:6],
                          str(linr[2])[:7],
                          str(linr[4])[:7], str(len(x_es))])
         txt = latexendline(txt)
 
-        linx = np.arange(2020., 2101., 1.)
+        if include_1:
+            linx = np.arange(1970., 2101., 1.)
+
+        else:
+            linx = np.arange(2020., 2101., 1.)
         liny = slope*linx + intercept
         exp_colour = exp_colours_fill[exp]
         plt.plot(linx, liny, c=exp_colour, lw=1.7, ls=line_styles[threshold])
 
 
     print('Saved to: ', fn)
     out = open(fn, 'w')
     out.write(txt)
     out.close()
 
 
     # boring plotting settings:
     ax.set_xlim(xlims)
     ax.set_ylim(ylims)
     ax.set_xlabel('Global Warming Threshold Year')
     ax.set_ylabel(''.join(['Equilibrium Climate Sensitivity ', r'$\degree$', 'C']))
 
     # Only show ticks on the left and bottom spines
     ax.spines['top'].set_visible(False)
     ax.spines['right'].set_visible(False)
     ax.get_xaxis().tick_bottom()
     ax.get_yaxis().tick_left()
 
     # h lines:
+    if include_1:
+        x_loc = 1970.5
+    else:
+        x_loc = 2000.5
+
     for model in sorted(datasets.keys()):
         if model == 'CMIP6': continue
         ecs = ECS_data[model]
         plt.axhline(ecs, c='k', ls='-', lw=0.75, zorder=-1)
         if model in ['CanESM5-CanOE', '']:
             gap = -0.015
             va='top'
         else:
             va = 'bottom'
             gap=0.0051
-        ax.text(2000.5, ecs+gap, model, horizontalalignment='left',
+        ax.text(x_loc, ecs+gap, model, horizontalalignment='left',
              verticalalignment=va)
 
     #plt.suptitle('Equilibrium Climate Sensitivity against Global Warming Threshold')
     if not save_single_plot: return fig, ax
 
     # Legend part:
     plt.sca(ax_leg)
 
-    for thresh, style in marker_styles.items():
+    for thresh, style in threshold_marker_styles.items():
         if style is None: continue
         lab = ''.join([str(int(thresh)), r'$\degree$', 'C'])
         ax_leg.scatter([], [], marker=style, c='w', edgecolor='k',linewidth=2.5, s=80, label=lab)
 
     ax_leg.scatter([], [], marker='D', c='w', edgecolor='k',linewidth=2.5, s=80, label='No GWT')
 
     for exp in sorted(exps.keys()):
         if exp=='historical': continue
         color = exps[exp]
         if color is None: continue
         lab = sspify(exp)
         ax_leg.scatter([], [], marker='s', c=color, s=80, label=lab)
         #'ax_leg.scatter([], [], marker='s', c='w', edgecolor=color,linewidth=2.5, s=80, label=lab)
 
 
 #    for model, color in model_colours.items():
 #        lab = model
 #        ax_leg.scatter([], [], marker='s', c=color, edgecolor='k', linewidth=1.5, s=80, label=lab)
 
     for thresh, style in line_styles.items():
         # = {2.:'dotted', 3:'dashed', 4.:'dashdot'}
         lab = ''.join([str(int(thresh)), r'$\degree$', 'C fit'])
         plt.plot([], [], c='k', lw=1.5, ls=style, label=lab)
 
     legd = ax_leg.legend(#keys, labels,
         bbox_to_anchor=(1.5, 0.5), #
         numpoints=1, labelspacing=0.8,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'ecs_scatter',])
-    path += '_'.join(['ecs_vs_time',]) + image_extention
+    if include_1:
+        path += '_'.join(['ecs_vs_time','1gwt']) + image_extention
+    else:
+        path += '_'.join(['ecs_vs_time',]) + image_extention
     print('saving:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4851,115 +4884,184 @@
-def do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis = 'ocean', fig = None, ax = None):
+def do_emission_scatterplot(cfg, data_dict, thresholds_dict, y_axis = 'ocean', x_axis='gwt_year', fig = None, ax = None):
 
     save_single_plot= False
     if fig is None or ax is None:
         fig = plt.figure()
-        fig.set_size_inches(8, 7)
+        fig.set_size_inches(9, 7)
         gs = gridspec.GridSpec(1, 2, figure=fig, hspace=0.5, width_ratios=[4,1])
         ax = fig.add_subplot(gs[0, 0])
         ax_leg = fig.add_subplot(gs[0, 1])
         save_single_plot = True
     plt.sca(ax)
         #gs = gridspec.GridSpec(2, 3, figure=fig, hspace=0.5)
 
     model_colours = {'CMIP6': 'black'}
 
     datasets = {}
     exps = {}
     for (dataset, short_name, exp, ensemble), thresholds in thresholds_dict.items():
         if model_colours.get(dataset, False): continue
         datasets[dataset] = True
 
     cmap = mplcm.get_cmap('jet')
     for i,dataset in enumerate(sorted(datasets)):
         model_colours[dataset] = cmap(float(i)/(len(datasets)-1.))
 
-    marker_styles = {1.5: None, 2.: 's', 3.: 'o', 4:'^', 5.:None}
+    #threshold_marker_styles = {1. 'v', 1.5: None, 2.: 's', 3.: 'o', 4:'^', 5.:None}
 
 #    if x_axis == 'emissions':
 #        short_name_1 = ''
-    if x_axis == 'land':
+    if y_axis in ['land', 'land_pc']:
           short_name_1 = 'tls'
-    if x_axis == 'ocean':
+    if y_axis in ['ocean', 'ocean_pc']:
         short_name_1 = 'fgco2gt_cumul'
-    if x_axis == 'atmosphere':
+    if y_axis == 'atmosphere':
         short_name_1 = 'atmos_carbon'
 
+
     ensemble_alpha = {'ensemble_mean':1.}
     sizes = {'ensemble_mean':60}
     for (dataset, short_name, exp, ensemble), thresholds in thresholds_dict.items():
         if short_name != 'tas': continue
         if ensemble != 'ensemble_mean': continue
         if ensemble in ['ensemble_min', 'ensemble_max']: continue
         exps[exp] = exp_colours_fill[exp]
         colour = model_colours[dataset]
         edgecolor= exp_colours_fill[exp]
         alpha= ensemble_alpha.get(ensemble, 1.  )
         data = data_dict[(dataset, short_name_1, exp, ensemble)]
-        if x_axis == 'ocean':
+
+        if y_axis == 'gwt_year':
+            assert 0 # you monster.
+
+        if y_axis in ['ocean', 'ocean_pc']:
             y_time = cube_to_years(data)
             y_data = data.data
         else:
             y_time = data['time']
             y_data = data[short_name_1]
 
+        if x_axis in ['ocean', 'ocean_pc']:
+            datax = data_dict[(dataset, 'fgco2gt_cumul', exp, ensemble)]
+            x_time = cube_to_years(datax)
+            x_data = datax.data
+        elif x_axis == 'gwt_year':
+            try: x_data = cube_to_years(data)
+            except: x_data = data['time']
+        else:
+            x_time = data['time']
+            x_data = data[short_name_1]
+
+        if '_pc' in [x_axis[-3:], y_axis[-3:]]:
+            print(data_dict[(dataset, 'fgco2gt_cumul', exp, ensemble)].data.shape)
+            print(data_dict[(dataset, 'tls', exp, ensemble)]['tls'].shape)
+            print(data_dict[(dataset, 'atmos_carbon', exp, ensemble)]['atmos_carbon'].shape)
+            total = data_dict[(dataset, 'fgco2gt_cumul', exp, ensemble)].data[-85:] + data_dict[(dataset, 'tls', exp, ensemble)]['tls'][-85:] + data_dict[(dataset, 'atmos_carbon', exp, ensemble)]['atmos_carbon'][-85:]
+
+            if x_axis in ['ocean_pc',]:
+                x_data = x_data[-85:]
+                x_time = x_time[-85:]
+            if y_axis in ['land_pc',]:
+                y_data = y_data[-85:]
+                y_time = y_time[-85:]
+
+            if '_pc' == x_axis[-3:]:
+                x_data = 100.* (x_data/total)
+            if '_pc' == y_axis[-3:]:
+                y_data = 100.* (y_data/total)
+            for t, xd, yd, to in zip(x_time, x_data, y_data, total): print(t, xd, yd, to )
+
         for threshold, time in thresholds.items():
             if time is None: continue # no GWT.
-            ms = marker_styles.get(threshold, None)
+            
+            ms = threshold_marker_styles.get(threshold, None)
             size = sizes.get(ensemble, 60 )
             if dataset == 'CMIP6': size = 100.
 
             if ms == '^': size = size*1.3
 
             if not ms: continue
-            x = time.year + 0.5
-            index = np.argmin(np.abs(y_time - x))
+            t = time.year + 0.49
+
+            if x_axis in ['ocean', 'ocean_pc']:
+                index = np.argmin(np.abs(x_time - t))
+                if index in [-1, ]: 
+                    print(threshold, time, index, 'error',(dataset, short_name, exp, ensemble), t, x_time.min()) 
+                    assert 0 
+                x = x_data[index]
+            else:
+                x = time.year + 0.5
+
+            index = np.argmin(np.abs(y_time - t))
+            if index in [-1,  ]:
+                print(threshold, time, index, 'error',(dataset, short_name, exp, ensemble), t, y_time.min())
+                assert 0
+
+
             y = y_data[index]
 
             plt.scatter(x,y, c = colour, marker = ms, edgecolor=edgecolor, linewidth=2.5, alpha = alpha, s=size)
 
-    plt.suptitle('CMIP6 GWTs in the '+x_axis)
+    #plt.suptitle('CMIP6: '+x_axis+' vs '+y_axis)
+
+    labels = {'ocean': 'Ocean sink, Pg',
+        'ocean_pc': 'Ocean sink, %',
+        'land': 'Land sink, Pg',
+        'land_pc': 'Land sink, %',
+        'gwt_year': 'Global Warming Level Year',
+        }
+    ax.set_xlabel(labels.get(x_axis, ''))
+    ax.set_ylabel(labels.get(y_axis, ''))
+
+    if x_axis == 'ocean' and y_axis == 'land' or x_axis == 'ocean_pc' and y_axis == 'land_pc':
+        lims = []
+        if x_axis == 'ocean': lims.append(0.)
+        lims.extend(ax.get_xlim())
+        lims.extend(ax.get_ylim())
+        lims = [np.min(lims), np.max(lims)]
+        ax.set_xlim(lims)
+        ax.set_ylim(lims)
+        plt.plot(lims, lims, c='k', lw=0.5, ls=':')
+        ax.set_aspect('equal', adjustable='box')
+
     if not save_single_plot: return fig, ax
 
 
     plt.sca(ax_leg)
 
-    for thresh, style in marker_styles.items():
+    for thresh, style in threshold_marker_styles.items():
         if style is None: continue
         lab = ''.join([str(int(thresh)), r'$\degree$', 'C'])
         ax_leg.scatter([], [], marker=style, c='w', edgecolor='k',linewidth=2.5, s=80, label=lab)
 
     for exp in sorted(exps.keys()):
         if exp=='historical': continue
         color = exps[exp]
         if color is None: continue
         lab = sspify(exp)
         ax_leg.scatter([], [], marker='s', c='w', edgecolor=color,linewidth=2.5, s=80, label=lab)
 
     for model, color in model_colours.items():
         lab = model
         ax_leg.scatter([], [], marker='s', c=color, edgecolor='k', linewidth=1.5, s=80, label=lab)
 
     legd = ax_leg.legend(#keys, labels,
         bbox_to_anchor=(1.5, 0.5), #
         numpoints=1, labelspacing=0.8,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
-
-
-
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'emissions_scatter',])
-    path += '_'.join(['emssions_scatter', x_axis]) + image_extention
+    path += '_'.join(['emssions_scatter', x_axis, y_axis]) + image_extention
     print('saving:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 
commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -2266,41 +2309,41 @@
 def get_long_name(name):
     """
     Get a title friendly longname.
     """
     longnames = {
         'tas' : 'Temperature, K',
         'tas_norm' : 'Normalised Temperature, '+r'$\degree$' + 'C',
         'co2' : 'Atmospheric CO'+r'$_{2}$',
         # 'emissions' : 'Anthropogenic emissions',
         # 'cumul_emissions': 'Cumulative Anthropogenic emissions',
         'luegt': 'Land Use Emissions',
-        'tls': 'True Land Sink',
+        'tls': 'S'+r'$_{Land}$',
         'rh': 'Heterotrophic respiration',
         'intpp' : 'Marine Primary Production',
         'intdic' : 'Dissolved Inorganic Carbon',
         'intpoc' : 'Particulate Organic Carbon',
         'epc100' : 'POC flux at 100m',
         'npp'   : 'Net Primary Production on Land',
         'fgco2' : 'Air sea Flux of CO'+r'$_{2}$',
         'frc':  'Carbon Flux at sea floor',
         'fric':  'Inorganic Carbon Flux at sea floor',
         'froc':  'Organic Carbon Flux at sea floor',
         'nbp': 'Net Biome Production',
-        'nbpgt_cumul': 'Cumulative Global Total Net Biome Production, Pg',
-        'fgco2gt_cumul': 'Cumulative Global Total Air sea Flux of CO'+r'$_{2}$'+', Pg',
-        'atmos_carbon': 'Remnant Atmospheric Anthropogenic CO'+r'$_{2}$'+', Pg',
+        'nbpgt_cumul': 'Cumulative Total Net Biome Production, Pg',
+        'fgco2gt_cumul': 'Cumulative Total Air sea Flux of CO'+r'$_{2}$'+', Pg',
+        'atmos_carbon': 'Atmospheric Anthropogenic CO'+r'$_{2}$'+', Pg',
         # units:
         'Pg yr^-1': 'Pg yr'+r'$^{-1}$',
 
     }
     long_name = ''
     if name.find('gt_norm') > -1:
         long_name += 'Normalised Global Total '
         name = name[name.find('gt_norm')]
     elif name[-2:] == 'gt':
         long_name += 'Global Total '
         name = name[:-2]
 
     return long_name + longnames.get(name, name)
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -2354,316 +2359,316 @@
 def load_ensemble(data_dict, short_name, exp, ensemble):
     dat = data_dict.get(('CMIP6', short_name, exp, ensemble), False)
     for ens in ensemble:
         if dat: continue
         dat = data_dict.get(('CMIP6', short_name, exp, ens), False)
     return dat
 
 
 # def make_ts_envellope_figure(
 #         cfg, data_dict, thresholds_dict,
 #         x='time',
 #         y='npp',
 #         plot_dataset='CMIP6',
 #         fill = 'ensemble_means',
 #         markers='thresholds',
 #         fig=None,
 #         ax=None,
 #     ):
 #     """
 #     make a time series envellope figure.
 #     x axis and y axis are determined by the short_names provuided in x and y
 #     vars.
 #     Markers are placed at certain points when the tas goes above thresholds.
 #
 #     fill = 'ensemble_means': plots only ensemble means
 #     fill = 'all_ensembles:' plots all ensembles, nut not ensemble means.
 #
 #     plot_dataset = 'CMIP6': All datasets
 #     plot_dataset = 'model': Only an ensemble of that model.
 #
 #     Parameters
 #     ----------
 #     cfg: dict
 #         the opened global config dictionairy, passed by ESMValTool.
 #     """
 #     if x !='time':return
 #     draw_line=True
 #     exps = {}
 #     ensembles = {}
 #     datasets = {}
 #     for (dataset, short_name, exp, ensemble)  in data_dict.keys():
 #          exps[exp] = True
 #          ensembles[ensemble] = True
 #          datasets[dataset] = True
 #
 #     if plot_dataset != 'CMIP6':
 #         if isinstance(plot_dataset, str):
 #             datasets = {plot_dataset:True}
 #         else:
 #             datasets = {pd:True for pd in plot_dataset}
 #             plot_dataset = '_'.join(plot_dataset)
 #
 #     # set path:
 #     image_extention = diagtools.get_image_format(cfg)
 #     path = diagtools.folder([cfg['plot_dir'], 'envellope_ts_figure'])
 #     path += '_'.join([x, y, markers, fill, plot_dataset]) + image_extention
 #     #if os.path.exists(path): return
 #
 #     exp_colours = {'historical':'black',
 #                    'ssp119':'green',
 #                    'ssp126':'dodgerblue',
 #                    'ssp245':'blue',
 #                    'ssp370':'purple',
 #                    'ssp434':'magenta',
 #                    'ssp585': 'red',
 #                    'ssp534-over':'orange',
 #                    'historical-ssp119':'green',
 #                    'historical-ssp126':'dodgerblue',
 #                    'historical-ssp245':'blue',
 #                    'historical-ssp370':'purple',
 #                    'historical-ssp434':'magenta',
 #                    'historical-ssp585': 'red',
 #                    'historical-ssp585-ssp534-over':'orange'}
 #
-#     marker_styles = {1.5: '*', 2.:'o', 3.:'D', 4.:'s', 5.:'X'}
+#     threshold_marker_styles = {1.5: '*', 2.:'o', 3.:'D', 4.:'s', 5.:'X'}
 #
 #     #if ensemble_mean: ensembles = ['ensemble_mean', ]
 #     exps = sorted(exps.keys())
 #     exps.reverse()
 #     print(exps, ensembles)
 #     print(data_dict.keys())
 #
 #     if fig == None:
 #         fig = plt.figure()
 #         ax = fig.add_subplot(111)
 #         make_figure_here = True
 #     else:
 #         make_figure_here = False
 #         plt.sca(ax)
 #
 #     x_label,y_label = [], []
 #     #number_of_lines=0
 #
 #     label_dicts = {
 #         'tas': ' '.join(['Temperature, K',]), # ''.join([r'$\degree$', 'C'])]),
 #         'tas_norm': ' '.join(['Normalised Temperature,', ''.join([r'$\degree$', 'C'])]),
 #         'co2': ' '.join(['Atmospheric co2, ppm']),
 #         'emissions': ' '.join(['Anthropogenic emissions, Pg/yr']),
 #         'cumul_emissions': ' '.join(['Cumulative Anthropogenic emissions, Pg']),
 #         'luegt': ' '.join(['Land use emissions, Pg']),
 #         'tls': ' '.join(['True Land Sink, Pg']),
 #         'atmos_carbon': 'Remnant Anthropogenic CO2, Pg',
 #     }
 #
 #     # Only drawy line and markers for CMIP6 ensemble_mean.
 #     #dataset_1 = plot_dataset
 #     #ensemble_1 = 'ensemble_mean'
 #
 #     envellopes = {exp: {} for exp in exps}
 #     for exp_1, ensemble_1,dataset_1 in product(exps, ensembles,datasets):
 #         x_data, y_data = [], []
 #         x_times, y_times = [], []
 #         for (dataset, short_name, exp, ensemble), cube in data_dict.items():
 #             if short_name not in [x,y]: continue
 #             if exp != exp_1: continue
 #             if ensemble != ensemble_1: continue
 #             if dataset != dataset_1: continue
 #
 #             if fill == 'ensemble_means' and ensemble_1 != 'ensemble_mean':
 #                 #  plots only ensemble means.
 #                 continue
 #             #if fill == 'all_ensembles' and ensemble_1 == 'ensemble_mean':
 #             #    #  plots all ensembles, nut not ensemble means.
 #             #    continue
 #
 #             print('found:', (dataset, short_name, exp, ensemble))
 #             if x == 'time' and short_name == y:
 #                 x_label = 'Year'
 #                 if isinstance(cube, iris.cube.Cube):
 #                     x_data = diagtools.cube_time_to_float(cube)
 #                     x_times = x_data.copy()
 #                     #print('setting x time to ',short_name, exp, ensemble)
 #                 else:
 #                     x_data = cube['time']
 #                     x_times = x_data.copy()
 #                     #print('setting x time to ',short_name, exp, ensemble)
 #             elif x == short_name and x in label_dicts.keys():
 #                 x_data = cube[x].copy()
 #                 x_times = cube['time'].copy()
 #                 #print('setting x time to ',short_name, exp, ensemble)
 #                 x_label = label_dicts[x]
 #
 #             elif short_name == x:
 #                 x_data = np.array(cube.data.copy())
 #                 x_times = diagtools.cube_time_to_float(cube)
 #                 #print('setting x axis to ',short_name, exp, ensemble, np.min(x_data), np.max(x_data))
 #                 x_label = ' '.join([get_long_name(x), str(cube.units)])
 #
 #             if y == 'time':
 #                #print('what kind of crazy person plots time on y axis?')
 #                 assert 0
 #             elif y == short_name and y in label_dicts.keys():
 #                 #['co2', 'emissions', 'cumul_emissions', 'luegt']:
 #                 y_data = cube[y].copy()
 #                 y_times = cube['time'].copy()
 #                 y_label = label_dicts[y]
 #                 #print('setting y time to ',short_name, exp, ensemble)
 #             elif short_name == y:
 #                 #print(short_name, 'is a cube for y ts plot..')
 #                 y_data = cube.data.copy()
 #                 y_times = diagtools.cube_time_to_float(cube)
 #                 #print('setting y time to ',short_name, exp, ensemble, y_data)
 #                 y_label = ' '.join([get_long_name(y), str(cube.units)])
 #
 #         if 0 in [len(x_data), len(y_data), len(x_times), len(y_times)]:
 #             #print('no data found',(exp_1, ensemble_1,dataset_1),  x,'vs',y, 'x:', len(x_data), 'y:',len(y_data))
 #             continue
 #
 #         if len(x_data) != len(x_times) or len(y_data) != len(y_times):
 #             print('x:', len(x_data), len(x_times), 'y:', len(y_data), len(y_times))
 #             assert 0
 #
 #         # calculate the datasety for the fills
 #         for xd, yd in zip(x_data, y_data):
 #             if 'x' == 'time': xd = int(xd)
 #             if xd < 1851.:
 #                 print(plot_dataset, fill, (exp_1, ensemble_1, dataset_1, short_name), xd, yd)
 #             if plot_dataset=='CMIP6':
 #                 if dataset_1 == 'CMIP6':
 #                     # include everything except 'CMIP6 ensemble means.'
 #                     continue
 #             else:
 #                 if dataset_1 != plot_dataset:
 #                     continue
 #             if fill == 'ensemble_means' and ensemble_1 != 'ensemble_mean':
 #                 #  plots only ensemble means.
 #                 continue
 #             if fill == 'all_ensembles' and ensemble_1 == 'ensemble_mean':
 #                 #  plots all ensembles, nut not ensemble means.
 #                 continue
 #
 #             if envellopes[exp_1].get(xd, False):
 #                 envellopes[exp_1][xd].append(yd)
 #             else:
 #                 envellopes[exp_1][xd] = [yd, ]
 #             print('made it!',exp_1, ensemble_1, fill, xd,yd)
 #
 #         # Only draw line for plot_dataset
 #         if draw_line and dataset_1 == plot_dataset:
 #             x_times = np.ma.array(x_times)
 #             y_times = np.ma.array(y_times)
 #             #number_of_lines+=1
 #             if plot_dataset=='CMIP6':
 #                 lw=1.3
 #             else:
 #                 lw=0.5
 #             plt.plot(x_data,
 #                  y_data,
 #                  lw=lw,
 #                  color=exp_colours[exp_1])
 #
 #         # Only plot markers for plot_dataset ensemble_mean
 #         if markers == 'thresholds' and dataset_1 == plot_dataset and ensemble_1 == 'ensemble_mean':
 #             try: threshold_times = thresholds_dict[(dataset_1, 'tas', exp_1, ensemble_1)]
 #             except:
 #                threshold_times = {}
 #             ms = 8
 #             for threshold, time in threshold_times.items():
 #                 if not time:
 #                     continue
 #                 x_point = get_threshold_point({'time':x_times}, time.year)
 #                 y_point = get_threshold_point({'time':y_times}, time.year)
 #
 #                 plt.plot(x_data[x_point],
 #                          y_data[y_point],
-#                          marker_styles[threshold],
+#                          threshold_marker_styles[threshold],
 #                          markersize = ms,
 #                          fillstyle='none',
 #                          color=exp_colours[exp_1])
 #                 plt.plot(x_data[x_point],
 #                          y_data[y_point],
 #                          'o',
 #                          markersize = 2,
 #                          #fillstyle='none',
 #                          color=exp_colours[exp_1])
 #
 #     #add_env = True
 #     for exp, ranges in envellopes.items():
 #          times, mins, maxs = [], [], []
 #          # This won't work if the ranges aren't the same!
 #          for t in sorted(ranges.keys()):
 #              times.append(t)
 #              mins.append(np.min(ranges[t]))
 #              maxs.append(np.max(ranges[t]))
 #          print('enveloppe', exp, times, mins, maxs)
 #          if not len(times):
 #              continue
 #          ax.fill_between(
 #              times,
 #              mins,
 #              maxs,
 #              lw=0,
 #              alpha=0.5,
 #              color=exp_colours[exp])
 #
 #     #print(x,y,fill, plot_dataset, envellopes)
 #
 #     if not envellopes:
 #         print('No lines plotted')
 #         plt.close()
 #         return
 #
 #     exp_colours_leg = {'historical':'black',
 #                    'ssp119':'green',
 #                    'ssp126':'dodgerblue',
 #                    'ssp245':'blue',
 #                    'ssp370':'purple',
 #                    #'ssp434':'magenta',
 #                    'ssp585': 'red',}
 #                    #'ssp534-over':'orange'}
 #
 #     plot_details = {}
 #     for exp,color in sorted(exp_colours_leg.items()):
 #         plot_details[exp] = {
 #                     'c': color,
 #                     'ls': '-',
 #                     'lw': 2.,
 #                     'label': exp
 #                 }
-#     for thres,ms in sorted(marker_styles.items()):
+#     for thres,ms in sorted(threshold_marker_styles.items()):
 #         plot_details[str(thres)] = {
 #                     'c': 'black',
 #                     'marker': ms,
 #                     'fillstyle':'none',
 #                     'label': '>' + str(thres)+u'\u00B0C'
 #                 }
 #
 #     diagtools.add_legend_outside_right(
 #                 plot_details, plt.gca(), column_width=0.175)
 #
 #     # set labels:
 #     plt.xlabel(x_label)
 #     plt.ylabel(y_label)
 #
 #     # set title:
 #     if x == 'time':
 #         title = get_long_name(y)
 #     else:
 #         title = ' '.join([get_long_name(x), 'by', get_long_name(y)])
 #
 #     if plot_dataset != 'all_models':
 #         title += ' '+plot_dataset
 #
 #     plt.title(title)
 #
 #     print('saving figure:', path)
 #     if make_figure_here:
 #         plt.savefig(path)
 #         plt.close()
 #     else:
 #         return fig, ax
 
 
 
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -1673,114 +1678,114 @@
-def load_thresholds(cfg, data_dict, short_names = ['tas', ], thresholds = [1.5, 2., 3., 4., 5.], ):
+def load_thresholds(cfg, data_dict, short_names = ['tas', ], thresholds = [1., 1.5, 2., 3., 4., 5.], ):
     """
     Load thresholds  as a dict.
 
     Dict is :
     data_dict[(dataset, short_name, exp, ensemble) ] = {threshold: year}
     """
     # If the threshold shelve exists already, just use that.
     overwrite_shelve = False
     thresholds_shelve = diagtools.folder([cfg['work_dir'], 'thresholds_dict'])+'thresholds.shelve'
     if not overwrite_shelve and glob.glob(thresholds_shelve+'*'):
         print('opening:', thresholds_shelve)
         sh = shelve.open(thresholds_shelve)
         thresholds_dict = sh['thresholds_dict']
         sh.close()
         return thresholds_dict
 
     # Calculate baseline tas for 1850-1900.
     thresholds_dict = {}
     baselines = {}
     baseline_cubes = {}
 
     debug = False # testing for 'ACCESS-ESM1-5', ssp126
 
     for (dataset, short_name, exp, ensemble), cube in data_dict.items():
         if short_name not in short_names:
              continue
 
         if exp != 'historical': continue
         if debug:
             if dataset == 'ACCESS-ESM1-5': pass
             else: continue
 
         baseline_cubes[(dataset, short_name, ensemble)] = cube
         baselines[(dataset, short_name, ensemble)] = calculate_anomaly(cube, [1850, 1900], calc_average=True)
         if debug: print('calculate anomaly:', cube)
         if debug: print('baseline: ', baselines[(dataset, short_name, ensemble)])
 
 
     # Do the work here.
     for (dataset, short_name, exp, ensemble), cube in data_dict.items():
         if short_name not in short_names:
              continue
         if debug:
             if dataset == 'ACCESS-ESM1-5' and  exp == 'ssp126': pass
             else: continue
         print('calculating threshold:', (dataset, short_name, exp, ensemble))
         if debug:
             print('debug mode:', (dataset, short_name, exp, ensemble))
 
         # find the baseline:
         baseline = baselines.get((dataset, 'tas', ensemble), False)
 
         if baseline is False and dataset in data_dict_linked_ens.keys():
            new_ens = data_dict_linked_ens[dataset].get(ensemble, False)
            baseline = baselines.get((dataset, 'tas', new_ens), False)
 
 
 #        if baseline is False:
 #            baseline = baselines.get((dataset, 'tas', ensemble.replace('f2', 'f3')), False)
 
         if baseline is False:
              print('No Baseline found', (dataset, short_name, exp, ensemble), 'available baselines are:')
              for bs_index in baselines.keys():
                  if bs_index[0] != dataset: continue
                  print(bs_index, ':', baselines.get(bs_index, 0.))
              assert 0
 
         for ens in ensemble:
             if baseline: continue
             baseline =  baselines.get((dataset, 'tas', ens), False)
 
         # calculate the moving average/normalised tmep
         cube2 = moving_average(cube.copy(), '21 years')
         cube2.data = cube2.data - baseline
         if debug:
             print('cube2.data', cube2.data)
 
         # ERROR: So the exceedence year is always set to the first cube in the series.
         # is that because the mean of multiple cubes is failing, or because the calculation is only done with the first cube?
         # looks like the ensemble mean cube is identical to the first cube.
 
         # Calculate the exceedance year:
         thresholds_dict[(dataset, short_name, exp, ensemble)] = {}
         for threshold in thresholds:
             time = get_threshold_exceedance_date(cube2, threshold)
 
             thresholds_dict[(dataset, short_name, exp, ensemble)][threshold] = time
             print("load_thresholds: Found Threshold:",(dataset, short_name, exp, ensemble), threshold, ':', time)
             if time is None: continue
             if float(threshold)>=2. and time.year == 2015:
                 thresholds_dict[(dataset, short_name, exp, ensemble)][threshold] = None
                 print('Bad time!')
                 print('baseline', baseline)
                 print('baseline_cube', baseline_cubes[(dataset, 'tas', ensemble)].data - baseline)
 
                 print('data', cube2.data)
                 #assert 0
 
     for i, index in enumerate(thresholds_dict.keys()):
         print('thresholds:', i, index)
         for thresh, year in thresholds_dict[index].items():
             if year:
                 print('\t',thresh, year.year)
             else: print('\t',thresh, year)
     #assert 0
 
     print('Saving:', thresholds_shelve)
     sh = shelve.open(thresholds_shelve)
     sh['thresholds_dict'] = thresholds_dict
     sh.close()
     return thresholds_dict
 
 
commit ad22a8ec32adaf8adac284f6ecc17e5f178f65d5
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 25 09:18:08 2022 +0100

    working here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5634,259 +5634,259 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
         # data_dict = calc_model_mean(cfg, short_names, data_dict)
         # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
         # plot_data_dict(cfg, data_dict)
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
             do_count_and_sensitivity_table = True
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
-            do_timeseries_megaplot =  False #True 
+            do_timeseries_megaplot = True 
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
 
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
                 for dataset in datasets:
                     timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
                             plot_dataset=dataset )
 #                for plot_styles in [
 #                       'CMIP6_range', 'all_models_range', 'all_models_means',
 #                       'all_ensembles',  'CMIP6_mean'
 #                       ]:
 #                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
 #                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
             do_cumulative_plot = True 
             if do_cumulative_plot:
                #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
             do_cumulative_panes = False 
             if do_cumulative_panes:
                 plot_styles = ['percentages', 'values']
 
                 for plot_style in plot_styles: # = ['percentages', 'values']
                   for threshold in ['2.0', ]: #'1.0',  '3.0', '4.0']:
                     make_ensemble_barchart_pane(
                         cfg, data_dict, thresholds_dict,
                         threshold = threshold,
                         do_legend=True,
                         plot_style= plot_style,
                         ensemble_key = 'ensemble_mean',
                         group_by = 'ecs',
                         stacked_hists=False,
                         )
 
             do_horizontal_plot = True 
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
             do_cumulative_ts_megaplot = True #False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
 #            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
 #            if do_make_cumulative_timeseries_pair:
 #                plot_types = ['pair', ]
 #                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
 #                for pt, exp in product(plot_types, ssps):
 #                      make_cumulative_timeseries_pair(cfg, data_dict,
 #                          thresholds_dict,
 #                          ssp=exp,
 #                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
             do_ecs_scatter = True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict, include_1=True)
 
 
             do_emission_scatter = True #False
             if do_emission_scatter:
                 do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean_pc', y_axis='land_pc')
 
                 for y_axis in ['ocean', 'land', 'atmosphere']:
                     do_emission_scatterplot(cfg, data_dict, thresholds_dict, y_axis=y_axis)
                 do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean', y_axis='land')
 
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 

commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5597,259 +5634,259 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
         # data_dict = calc_model_mean(cfg, short_names, data_dict)
         # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
         # plot_data_dict(cfg, data_dict)
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
-            do_count_and_sensitivity_table = False # True
+            do_count_and_sensitivity_table = True
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
-            do_timeseries_megaplot = False # True 
+            do_timeseries_megaplot =  False #True 
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
 
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
                 for dataset in datasets:
                     timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
                             plot_dataset=dataset )
 #                for plot_styles in [
 #                       'CMIP6_range', 'all_models_range', 'all_models_means',
 #                       'all_ensembles',  'CMIP6_mean'
 #                       ]:
 #                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
 #                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
-            do_cumulative_plot = False #True 
+            do_cumulative_plot = True 
             if do_cumulative_plot:
                #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
-            do_cumulative_panes = 0 #True  
+            do_cumulative_panes = False 
             if do_cumulative_panes:
                 plot_styles = ['percentages', 'values']
 
                 for plot_style in plot_styles: # = ['percentages', 'values']
                   for threshold in ['2.0', ]: #'1.0',  '3.0', '4.0']:
                     make_ensemble_barchart_pane(
                         cfg, data_dict, thresholds_dict,
                         threshold = threshold,
                         do_legend=True,
                         plot_style= plot_style,
                         ensemble_key = 'ensemble_mean',
                         group_by = 'ecs',
                         stacked_hists=False,
                         )
 
-            do_horizontal_plot = 0 #True 
+            do_horizontal_plot = True 
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
             do_cumulative_ts_megaplot = True #False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
 #            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
 #            if do_make_cumulative_timeseries_pair:
 #                plot_types = ['pair', ]
 #                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
 #                for pt, exp in product(plot_types, ssps):
 #                      make_cumulative_timeseries_pair(cfg, data_dict,
 #                          thresholds_dict,
 #                          ssp=exp,
 #                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
-            do_ecs_scatter = 0 #True
+            do_ecs_scatter = True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict, include_1=True)
 
 
             do_emission_scatter = True #False
             if do_emission_scatter:
                 do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean_pc', y_axis='land_pc')
 
                 for y_axis in ['ocean', 'land', 'atmosphere']:
                     do_emission_scatterplot(cfg, data_dict, thresholds_dict, y_axis=y_axis)
                 do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean', y_axis='land')
 
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5478,252 +5597,259 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
         # data_dict = calc_model_mean(cfg, short_names, data_dict)
         # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
         # plot_data_dict(cfg, data_dict)
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
-            do_count_and_sensitivity_table = True
+            do_count_and_sensitivity_table = False # True
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
-            do_timeseries_megaplot = False
+            do_timeseries_megaplot = False # True 
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
 
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
                 for dataset in datasets:
                     timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
                             plot_dataset=dataset )
 #                for plot_styles in [
 #                       'CMIP6_range', 'all_models_range', 'all_models_means',
 #                       'all_ensembles',  'CMIP6_mean'
 #                       ]:
 #                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
 #                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
-            do_cumulative_plot = False
+            do_cumulative_plot = False #True 
             if do_cumulative_plot:
                #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
-            do_cumulative_panes = True
+            do_cumulative_panes = 0 #True  
             if do_cumulative_panes:
                 plot_styles = ['percentages', 'values']
 
                 for plot_style in plot_styles: # = ['percentages', 'values']
+                  for threshold in ['2.0', ]: #'1.0',  '3.0', '4.0']:
                     make_ensemble_barchart_pane(
                         cfg, data_dict, thresholds_dict,
-                        threshold = '2.0', 
+                        threshold = threshold,
                         do_legend=True,
                         plot_style= plot_style,
                         ensemble_key = 'ensemble_mean',
                         group_by = 'ecs',
                         stacked_hists=False,
                         )
 
-            do_horizontal_plot = False
+            do_horizontal_plot = 0 #True 
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
-            do_cumulative_ts_megaplot = False#False
+            do_cumulative_ts_megaplot = True #False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
 #            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
 #            if do_make_cumulative_timeseries_pair:
 #                plot_types = ['pair', ]
 #                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
 #                for pt, exp in product(plot_types, ssps):
 #                      make_cumulative_timeseries_pair(cfg, data_dict,
 #                          thresholds_dict,
 #                          ssp=exp,
 #                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
-            do_ecs_scatter = True
+            do_ecs_scatter = 0 #True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
+                do_ecs_scatterplot(cfg, data_dict, thresholds_dict, include_1=True)
+
 
             do_emission_scatter = True #False
             if do_emission_scatter:
-                for x_axis in ['ocean', 'land', 'atmosphere']:
-                    do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis=x_axis)
+                do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean_pc', y_axis='land_pc')
+
+                for y_axis in ['ocean', 'land', 'atmosphere']:
+                    do_emission_scatterplot(cfg, data_dict, thresholds_dict, y_axis=y_axis)
+                do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis='ocean', y_axis='land')
+
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 

commit 88250a26063f9f224ff7edac3bf44bd20eeaebcf
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jul 6 11:06:07 2022 +0100

    working here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5450,250 +5478,252 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
         # data_dict = calc_model_mean(cfg, short_names, data_dict)
         # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
         # plot_data_dict(cfg, data_dict)
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
             do_count_and_sensitivity_table = True
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
             do_timeseries_megaplot = False
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
 
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
                 for dataset in datasets:
                     timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
                             plot_dataset=dataset )
 #                for plot_styles in [
 #                       'CMIP6_range', 'all_models_range', 'all_models_means',
 #                       'all_ensembles',  'CMIP6_mean'
 #                       ]:
 #                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
 #                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
             do_cumulative_plot = False
             if do_cumulative_plot:
                #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
             do_cumulative_panes = True
             if do_cumulative_panes:
                 plot_styles = ['percentages', 'values']
 
                 for plot_style in plot_styles: # = ['percentages', 'values']
                     make_ensemble_barchart_pane(
-                        cfg, data_dict, thresholds_dict,threshold = 2.0, do_legend=True,
+                        cfg, data_dict, thresholds_dict,
+                        threshold = '2.0', 
+                        do_legend=True,
                         plot_style= plot_style,
                         ensemble_key = 'ensemble_mean',
                         group_by = 'ecs',
                         stacked_hists=False,
                         )
 
             do_horizontal_plot = False
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
             do_cumulative_ts_megaplot = False#False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
 #            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
 #            if do_make_cumulative_timeseries_pair:
 #                plot_types = ['pair', ]
 #                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
 #                for pt, exp in product(plot_types, ssps):
 #                      make_cumulative_timeseries_pair(cfg, data_dict,
 #                          thresholds_dict,
 #                          ssp=exp,
 #                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
             do_ecs_scatter = True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
 
             do_emission_scatter = True #False
             if do_emission_scatter:
                 for x_axis in ['ocean', 'land', 'atmosphere']:
                     do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis=x_axis)
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 

commit dc70598456f1f16e21d04d82b5ed4a3028d97864
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Thu Jun 30 10:04:45 2022 +0100

    Update diagnostic_gwt_timeseries.py

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5495,237 +5450,250 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
         # data_dict = calc_model_mean(cfg, short_names, data_dict)
         # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
         # plot_data_dict(cfg, data_dict)
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
         # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
             # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
             # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
-            do_count_and_sensitivity_table = True 
+            do_count_and_sensitivity_table = True
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
             do_timeseries_megaplot = False
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
 
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
                 for dataset in datasets:
                     timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
                             panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
                             plot_dataset=dataset )
 #                for plot_styles in [
 #                       'CMIP6_range', 'all_models_range', 'all_models_means',
 #                       'all_ensembles',  'CMIP6_mean'
 #                       ]:
 #                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
 #                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
-            do_cumulative_plot = True 
+            do_cumulative_plot = False
             if do_cumulative_plot:
                #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
+            do_cumulative_panes = True
+            if do_cumulative_panes:
+                plot_styles = ['percentages', 'values']
+
+                for plot_style in plot_styles: # = ['percentages', 'values']
+                    make_ensemble_barchart_pane(
+                        cfg, data_dict, thresholds_dict,threshold = 2.0, do_legend=True,
+                        plot_style= plot_style,
+                        ensemble_key = 'ensemble_mean',
+                        group_by = 'ecs',
+                        stacked_hists=False,
+                        )
+
             do_horizontal_plot = False
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
             do_cumulative_ts_megaplot = False#False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
 #            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
 #            if do_make_cumulative_timeseries_pair:
 #                plot_types = ['pair', ]
 #                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
 #                for pt, exp in product(plot_types, ssps):
 #                      make_cumulative_timeseries_pair(cfg, data_dict,
 #                          thresholds_dict,
 #                          ssp=exp,
 #                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
             do_ecs_scatter = True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
 
             do_emission_scatter = True #False
             if do_emission_scatter:
                 for x_axis in ['ocean', 'land', 'atmosphere']:
                     do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis=x_axis)
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5366,234 +5495,237 @@
 def main(cfg):
     """
     Load the config file and some metadata, then make plots.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
 
     """
 
     #jobtype = 'debug'
     jobtype = 'cumulative_plot'
 
     if jobtype == 'cumulative_plot':
         short_names = ['tas', 'tas_norm',
                        'co2', #'emissions', #'cumul_emissions',
                        'nbp', 'nbpgt', 'nbpgt_cumul',
                        #'gpp', 'gppgt',
                        #'intpp',  'intppgt',
                        'fgco2','fgco2gt', 'fgco2gt_cumul',
                        'luegt', #  land-use emissions gt
                        'tls', #true land sink = nbp + land-use emissions
                        'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ] #'atmos_carbon', 'tas_norm', 'cumul_emissions', 'fgco2gt_cumul','nbpgt_cumul', ]
 
         short_names_y = short_names.copy()
 
 #    if jobtype == 'bulk':
 #        short_names = ['tas', 'tas_norm', 'co2', 'emissions', #'cumul_emissions'
 #                       'nbp', 'nbpgt', 'gpp', 'gppgt',
 #                       'intpp', 'fgco2', 'intppgt','fgco2gt',
 #                       'fgco2gt_cumul',
 #                       'nbpgt_cumul'
 #                       'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                       'atmos_carbon', # remant antrho carbon in atmosphere
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas_norm', 'fgco2gt_cumul','nbpgt_cumul', ]
 #        short_names_y = short_names.copy()
 
     if jobtype == 'debug':
         short_names = [
                        #'emissions', 'cumul_emissions',
                        'co2', 'atmos_carbon',
                        'tas',
 #                      'nbp', #'nbpgt', 'nbpgt_cumul',
 #                      #'gpp', 'gppgt',
 #                      'fgco2',#'fgco2gt', 'fgco2gt_cumul',
 #                      'bgc', #'bgcgt',
 #                      #'luegt', #  land-use emissions gt
 #                       'tls', #true land sink = nbp + land-use emissions
 #                      'atmos_carbon', # remant antrho carbon in atmosphere
                        ]
         short_names_x = ['time', ]#ssions',]#'time', 'emissions', 'cumul_emissions',]#'cumul_emissions', 'gppgt'] #'time', ]#'co2', 'emissions', 'tas_norm', 'fgco2gt', 'nbpgt']
         short_names_y = short_names.copy()
 
 
 #    if jobtype == 'full':
 #        short_names = ['tas', 'tas_norm', 'co2',
 #                       'npp', 'nppgt', 'rhgt', 'exchange',
 #                       'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'intppgt_norm',
 #                       'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc',
 #                       'intppgt','fgco2gt', 'epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',
 #                       ]
 #        short_names_x = ['time', 'co2', 'tas', 'tas_norm', 'fgco2gt',
 #                        'intpp', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'nppgt', 'fgco2gt', 'rhgt', 'exchange']
 #        short_names_y = ['nppgt', 'nppgt_norm','rhgt_norm','exchange_norm','fgco2gt_norm', 'co2',
 #                         'intpp', 'fgco2', 'epc100', 'intdic', 'intpoc', 'fric', 'froc', 'fgco2gt', 'intppgt','epc100gt', 'intdicgt', 'intpocgt', 'fricgt', 'frocgt',]
 #
     pairs = []
 
     for do_ma in [True, ]:#False]:
         data_dict = load_timeseries(cfg, short_names)
         data_dict = load_scenario_carbon(cfg, data_dict)
         # data_dict = calc_emissions(cfg, data_dict)
-
-        #data_dict = calc_model_mean(cfg, short_names, data_dict)
-
-        #data_dict = fix_indices(data_dict)
+        # data_dict = calc_model_mean(cfg, short_names, data_dict)
+        # data_dict = fix_indices(data_dict)
 
         thresholds_dict = load_thresholds(cfg, data_dict)
         datasets = {}
         for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
             datasets[dataset] = True
 
-        #plot_data_dict(cfg, data_dict)
-        #ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
-        #ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
-        #ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
+        # plot_data_dict(cfg, data_dict)
+        # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '4.0', land_carbon = 'tls')
+        # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '3.0', land_carbon = 'tls')
+        # ake_bar_chart(cfg, data_dict, thresholds_dict, threshold = '2.0', land_carbon = 'tls')
 
         if jobtype in ['cumulative_plot', 'debug']:
-            #make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
-            #make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
-            #make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
-            #make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
+            # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls')
+            # make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'nbpgt')
+            # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical-ssp585',)
+            # make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp='historical',)
 
-            do_count_and_sensitivity_table = False
+            do_count_and_sensitivity_table = True 
             if do_count_and_sensitivity_table:
                 make_count_and_sensitivity_table(cfg, data_dict, thresholds_dict)
 
-            do_timeseries_megaplot = True
+            do_timeseries_megaplot = False
             if do_timeseries_megaplot:
                 # master
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
                         panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
                 timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean'],
-                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', ],) # defaults
-
-
-                for plot_styles in [
-                       'CMIP6_range', 'all_models_range', 'all_models_means',
-                       'all_ensembles',  'CMIP6_mean'
-                       ]:
-                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
-                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
-                            panes = [pane, ])
+                            panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
+
+                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_models_range', 'all_models_means',],
+                            panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ], )
+                for dataset in datasets:
+                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['all_ensembles', 'all_models_means'],
+                            panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'tls', 'luegt', 'nbpgt_cumul', ],
+                            plot_dataset=dataset )
+#                for plot_styles in [
+#                       'CMIP6_range', 'all_models_range', 'all_models_means',
+#                       'all_ensembles',  'CMIP6_mean'
+#                       ]:
+#                    for pane in ['tas_norm','atmos_carbon','tls', 'fgco2gt_cumul',]:
+#                        timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
+#                            panes = [pane, ])
 
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', ],) # defaults
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['luegt', ],) # defaults
 #
 #                timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=['CMIP6_range', 'CMIP6_mean', 'all_models_means', 'all_ensembles'],
 #                        panes = ['atmos_carbon', 'nbpgt_cumul', 'luegt', 'tas', 'nbpgt','tls'],) # defaults
 #
 #                for plot_styles in [['CMIP6_range', 'CMIP6_mean'],
 #                       'CMIP6_range', ['all_models_range', 'all_models_means'],
 #                       'all_ensembles',  'CMIP6_mean',
 #                       ['all_ensembles','all_models_range',],
 #                       ]:
 #            #plot_styles: ambition:
 #            #    ['ensemble_mean', ] default behaviour before
 #            #    CMIP6_mean: Only CMIP6 multi model mean
 #            #    CMIP6_range: range bewteen each model mean shown
 #            #    CMIP6_full_range: full range between individual model ensemble menmbers
 #            #    all_models_means: Each individual models mean is plotted.
 #            #    all_models_range: Each individual models range is plotted
 #            #    all_ensembles: Every single ensemble member is shown.
 #                    continue
 #                    # panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas_norm', 'atmos_carbon', 'fgco2gt_cumul', 'nbpgt_cumul', ],) # defaults
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'co2', 'tls', 'fgco2gt', 'luegt', 'nbpgt'])
 #                    timeseries_megaplot(cfg, data_dict, thresholds_dict,plot_styles=plot_styles,
 #                        panes = ['tas', 'atmos_carbon','tls', 'fgco2', 'lue', 'nbp'])
 
-            do_cumulative_plot = False
+            do_cumulative_plot = True 
             if do_cumulative_plot:
-
+               #vertical bar chart
                 plot_styles = ['percentages', 'values']
                 ens_styles = ['ensemble_mean', 'all_ens']
                 group_bys = ['ecs', ] #'group_by_ssp', 'ecs'] # 'group_by_model'
                 for plot_style, ens, group_by in product(plot_styles, ens_styles, group_bys):
                     make_ensemble_barchart(cfg, data_dict, thresholds_dict, plot_style=plot_style, ensemble_key=ens, group_by=group_by)
 
             do_horizontal_plot = False
             if do_horizontal_plot:
                 # Horizontal bar charts with allocartions:
                 for plotdataset in sorted(datasets.keys()):
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, plot_dataset=plotdataset)
                     make_cumulative_vs_threshold(cfg, data_dict, thresholds_dict, land_carbon = 'tls', LHS_panes = {}, thresholds=['2075', '2050', '2025'], plot_dataset=plotdataset)
 
 
-            do_cumulative_ts_megaplot = False
+            do_cumulative_ts_megaplot = False#False
             # Massive plot that has like 12 panes.
             if do_cumulative_ts_megaplot:
                 make_cumulative_timeseries_megaplot(cfg, data_dict,
                                        thresholds_dict,
                                        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                                        plot_types = ['pair', 'area_over_zero'],
                                        ensemble = 'ensemble_mean')
                 datasets = {}
                 for (dataset, short_name, exp, ensemble),cube  in data_dict.items():
                     datasets[dataset] = True
                 for dataset in datasets.keys():
                     make_cumulative_timeseries_megaplot(cfg, data_dict,
                              thresholds_dict,
                              ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
                              plot_types = ['pair', 'area_over_zero'],
                              ensemble = 'ensemble_mean',
                              dataset=dataset)
 
-            do_make_cumulative_timeseries_pair = False
+#            do_make_cumulative_timeseries_pair = False
 #           # This is all done in a single plot with make_cumulative_timeseries_megaplot
-            if do_make_cumulative_timeseries_pair:
-                plot_types = ['pair', ]
-                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
-                for pt, exp in product(plot_types, ssps):
-                      make_cumulative_timeseries_pair(cfg, data_dict,
-                          thresholds_dict,
-                          ssp=exp,
-                          ensemble = 'ensemble_mean')
+#            if do_make_cumulative_timeseries_pair:
+#                plot_types = ['pair', ]
+#                ssps = ['ssp119',] #'historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585']
+#                for pt, exp in product(plot_types, ssps):
+#                      make_cumulative_timeseries_pair(cfg, data_dict,
+#                          thresholds_dict,
+#                          ssp=exp,
+#                          ensemble = 'ensemble_mean')
 #                      continue
 #                   make_cumulative_timeseries(cfg, data_dict, thresholds_dict, ssp=exp, plot_type = pt)
 #               #continue
 
             print(datasets)
 
             do_ecs_scatter = True
             if do_ecs_scatter:
                 do_ecs_scatterplot(cfg, data_dict, thresholds_dict)
 
-            do_emission_scatter = False
+            do_emission_scatter = True #False
             if do_emission_scatter:
                 for x_axis in ['ocean', 'land', 'atmosphere']:
                     do_emission_scatterplot(cfg, data_dict, thresholds_dict, x_axis=x_axis)
 
 
         return
         for x in short_names_x:
             for y in short_names_y:
                 make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                            markers='thresholds', do_moving_average=False,
                            plot_dataset='all_models',
                            ensemble_mean=True )
 
         for x in short_names_x:
             for y in short_names_y:
                 for plot_dataset in datasets:
                     #if plot_dataset.find('UKESM')==-1: continue
                     if x == y:
                         continue
                     print('main:', do_ma, x, y)
                     make_ts_figure(cfg, data_dict, thresholds_dict, x=x, y=y,
                                markers='thresholds', do_moving_average=False,
                                plot_dataset=plot_dataset,
                                ensemble_mean=False)
 
     logger.info('Success')
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4316,357 +4334,368 @@
 def make_cumulative_timeseries(cfg, data_dict,
       thresholds_dict,
       ssp='historical-ssp126',
       dataset = 'CMIP6',
       ensemble = 'ensemble_mean',
       plot_type = 'pc', # 'pc', 'area_over_zero are the two in the megaplot.
       plot_thresholds = [1.5, 2.,3.,4.,5.],
       do_leg= True,
       fig = None, gs = None, ax= None,
 ):
     """
     Make a plot showing the time series of carbon allocation.
     """
     if None in [fig, ax]:
         fig = plt.figure()
         fig.set_size_inches(12, 6)
         gs = gridspec.GridSpec(1, 1,figure=fig )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
         ax =  fig.add_subplot(gs[0, 0])
         save = True
     else:
         save = False
     plt.sca(ax)
 
    # load data.
     cube_keys = ['fgco2gt_cumul', 'nbpgt_cumul']
     colours = {#'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     #colours = {'cumul_emissions': 'grey', 'fgco2gt_cumul':'blue', 'nbpgt_cumul':'orange', 'tls':'green', 'luegt':'red'}
     if ensemble == 'ensemble_mean':
         ensembles = ['ensemble_mean',]
     else: assert 0
     if isinstance(dataset, str):
          datasets = [dataset, ]
     else: assert 0
 
     if ssp[:3] == 'ssp':
          exps = ['historical', ssp, '-'.join(['historical', ssp])]
     elif ssp == 'historical': exps = ['historical', ]
 
     data = {k:{} for k in colours.keys()}
     for ssp_it, ensemble, key, dset in product(exps, ensembles, colours.keys(),datasets):
         print('load data', (dset, key, ssp_it, ensemble))
         tmp_data = data_dict.get((dset, key, ssp_it, ensemble), False)
         if not tmp_data:
             print('Did not find:', (dset, key, ssp_it, ensemble))
             continue
         print('load data: found:', (dset, key, ssp_it, ensemble))
         if key in cube_keys:
             tmp_data = {'time': diagtools.cube_time_to_float(tmp_data),
                              key: tmp_data.data}
 
         tmp_data = zip_time(tmp_data, key)
         data[key] = data[key] | tmp_data # combine two dicts (python 3.9 and later)
         print('load data', (key, ssp_it, ensemble),':', len(data[key].keys()))
 
     print(dataset, ssp, 'loaded data:',data.keys())
     # add atmos_stock:
     tmp_times, tmp_dat = unzip_time(data['atmos_carbon'])
     data['atmos_carbon'] = zip_time({'time':tmp_times, 'atmos_carbon':tmp_dat}, 'atmos_carbon')
 
     # found=0
     # for key in ['nbpgt_cumul', 'fgco2gt_cumul']:
     #     print('adding atmospheric stock', key)
     #     key_times, key_dat = unzip_time(data[key])
     #     print(dataset, ssp, tmp_dat, key_dat, key_times, tmp_times)
     #     if len(tmp_times) != len(key_times):
     #         print('error:', len(tmp_times), '!=', len(key_times))
     #         print('carbon_times:', tmp_times[0], tmp_times[-1])
     #         print(key, 'times', key_times[0], key_times[-1])
     #         assert 0
     #         continue
     #     tmp_dat = tmp_dat - key_dat
     #     found+=1
     # if found==0:return fig, ax
 
     #data['atmos_carbon'] = zip_time({'time':tmp_times, 'atmos_carbon':tmp_dat}, 'atmos_carbon')
     #colours['atmos_carbon'] = 'purple'
 
     thresholds = {}
     for ssp_it, ensemble, dset in product(exps, ensembles, datasets):
         dicts = thresholds_dict.get((dset, 'tas', ssp_it, ensemble), False)
         if not dicts:continue
         thresholds= thresholds|dicts
 
     # plot simple time series:
 #    if plot_type == 'simple_ts':
 #        for key, dat in data.items():
 #            times, dat_list = unzip_time(dat)
 #            #if key == 'tls':
 #            #    times, dat = times[:-1], dat[:-1]
 #            plt.plot(times,
 #                dat_list,
 #                lw=2,
 #                color=colours[key],
 #                label = key)
 #        plt.axhline(y=0., c='k', ls='--')
 #        if do_leg: plt.legend()
 #
 #    # plot simple time series:
 #    if plot_type == 'sink_source':
 #        for key, dat in data.items():
 #            times, dat_list = unzip_time(dat)
 #            if key in ['fgco2gt_cumul', 'nbpgt_cumul', 'tls', 'luegt']:
 #                dat_list = -1*dat_list
 #            plt.plot(times,
 #                dat_list,
 #                lw=2,
 #                color=colours[key],
 #                label = key)
 #        plt.axhline(y=0., c='k', ls='--')
 #        if do_leg: plt.legend()
 
     lat, lad = unzip_time(data['tls'])
     ont, ond = unzip_time(data['fgco2gt_cumul'])
     #        lut, lud = unzip_time(data['luegt'])
     nbt, nbd = unzip_time(data['nbpgt_cumul'])
     att, atd = unzip_time(data['atmos_carbon'])
     [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
     emt = lat[:]
     emd = lad + ond + atd
     aligned_interpolated_data_shelve = diagtools.folder([cfg['work_dir'], 'aligned_interpolated_data'])+'aligned_interpolated_data.shelve'
     sh = shelve.open(aligned_interpolated_data_shelve)
     sh['lat'] = lat
     sh['lad'] = lad
     sh['ont'] = ont
     sh['ond'] = ond
     sh['nbt'] = nbt
     sh['nbd'] = nbd
     sh['att'] = att
     sh['atd'] = atd
     sh['emt'] = emt
     sh['emd'] = emd
     sh.close()
 
 
     # plot simple time series:
     if plot_type in ['area', 'area_over_zero']:
         #colours = {'cumul_emissions': 'grey', 'fgco2gt_cumul':'blue', 'nbpgt_cumul':'orange', 'tls':'green'}
         print(data.keys())
         # emt, emd = unzip_time(data['cumul_emissions'])
         lat, lad = unzip_time(data['tls'])
         ont, ond = unzip_time(data['fgco2gt_cumul'])
 #        lut, lud = unzip_time(data['luegt'])
         nbt, nbd = unzip_time(data['nbpgt_cumul'])
         att, atd = unzip_time(data['atmos_carbon'])
 
         [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
 
 
         if plot_type in ['area',] :
             ond = -1.* ond
             lad = -1.*(lad + ond)
         if plot_type in ['area_over_zero',] :
             atd_t = atd + lad + ond # air land sea.
             lad_t = lad + ond
             ond_t = ond
 #            lad = lad+ond
  #           atd = atd + lad# air land sea.
 
             # print('emissions times:', emt[:5], emt[-5:])
 #            print('LUE times:', lut[:5], lut[-5:])
             #print('emissions data:', emd[:5], emd[-5:])
 #            print('LUE data :', lud[:5], lud[-5:])
             # print('sizes:', len(emt), len(emd), len(lut), len(lud))
 #            if np.max(lut) > np.max(att):
 #                lut = lut[:-1] # Remove 2015.5 (not in histor period)
 #                lud = lud[:-1]
 
 #            plt.plot(emt, emd+lud, 'k-', lw=1.3,label='Emissions+LUE')
 #            plt.plot(lat, lad, 'k--', lw=1.3, label='LUE')
         # water:
         # plt.plot(
         #     ont,
         #     ond,
         #     lw=2,
         #     color=colours['fgco2gt_cumul'],
         #     label = )
         ax.fill_between(# zero and blue line
             ont,
             np.zeros_like(ond_t),
             ond_t, # zero and blue line
             lw=0,
             label='Ocean',
             color=colours['fgco2gt_cumul'])
 
         # land:
         # plt.plot(
         #     lat,
         #     lad,
         #     lw=2,
         #     color=colours['tls'],
         #     label = 'True Land Sink')
         ax.fill_between( # blue line and land line
             lat,
             ond_t, # ocean line
             lad_t, # land + ocean
             #lw=2,
             color=colours['tls'],
             label = 'Land')
 
         # atmos
         # plt.plot(
         #     att,
         #     atd,
         #     lw=2,
         #     color=colours['cumul_emissions'],
         #     label = 'Atmosphere')
         ax.fill_between( # atmos anthro stock
             lat,
             lad_t, # land + ocean
             atd_t, # land ocean and air
             #lw=2,
             color=colours['atmos_carbon'],
             label = 'Atmosphere')
         #ax.set_xlim([2010., 2100])
         ax.set_ylabel('Cumulative carbon, Pg')
         if plot_type in ['area',]:
             plt.axhline(y=0., c='k', ls='--')
 
     # plot simple time series:
     if plot_type in ['pc', 'triple'] :
         colours = {'atmos_carbon': 'silver', 'fgco2gt_cumul':'dodgerblue', 'nbpgt_cumul':'orange', 'tls':'mediumseagreen'}
         # emt, emd = unzip_time(data['cumul_emissions'])
         lat, lad = unzip_time(data['tls'])
         ont, ond = unzip_time(data['fgco2gt_cumul'])
         #lut, lud = unzip_time(data['luegt'])
         nbt, nbd = unzip_time(data['nbpgt_cumul'])
         att, atd = unzip_time(data['atmos_carbon'])
         [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
 
         total = ond + lad + atd
         water_land_line = (ond/total)*100.
         land_air_line = 100. *(ond + lad)/total
 
         water_land_line = np.ma.masked_invalid(water_land_line)
         land_air_line = np.ma.masked_invalid(land_air_line)
         # water:
         plt.plot(
             [], [],
             lw=6,
             color=colours['fgco2gt_cumul'],
             label = 'Air sea Flux of CO2')
         ax.fill_between(# zero and blue line
             att,
             0.* water_land_line, # zero and blue line
             water_land_line,
             color=colours['fgco2gt_cumul'])
 
         # land:
         plt.plot([],[],
             lw=6,
             color=colours['tls'],
             label = 'True Land Sink')
         ax.fill_between( # blue line and land line
             att,
             water_land_line,
             land_air_line,
             lw=2,
             color=colours['tls'])
 
         # atmos
         plt.plot([], [],
             lw=6,
             color=colours['atmos_carbon'],
             label = 'Atmosphere')
         ax.fill_between( # atmos anthro stock
             att,
             land_air_line,
             land_air_line*0. +100.,
             lw=2,
             color=colours['atmos_carbon'])
 
         #plt.axhline(y=0., c='k', ls='--')
         ax.set_ylabel('Percentage')
         #x.set_xlim([2010., 2100])
         ax.set_ylim([0., 100.])
 
-    if ssp in ['historical', ]:
-        if plot_type in ['pc', ]:
+
+    if plot_type in ['pc', ]:
+
+        if ssp in ['historical', ]:
             plt.plot([1959.,1980., 2000., 2012.], [56., 56., 56., 56.,], c='k', ls=':', label = 'Raupach 2014' )
             plt.plot([1959.,1980., 2000., 2012.], [25., 25., 25., 25.,], c='navy', ls='-.', label = 'Watson 2020')
 
-        else:
             plt.plot([], [], c='k', ls=':', label = 'Raupach 2014' )
             plt.plot([], [], c='navy', ls='-.', label = 'Watson 2020'  )
+        else:
+            ipcc_data = {'ssp119': [70., 70.],
+                         'ssp126': [65., 65. ],
+                         'ssp245': [54., 54.],
+                         'ssp370': [44., 44.],
+                         'ssp585': [38., 38.],}
+            add_ipcc = True
+            if add_ipcc:
+                plt.plot([2095.,2100., ], ipcc_data[ssp], c='k', ls='-', lw=2.1,  label = 'SPM.7',) # cmap_ssp_ocean[ssp.upper()]
+
 
     if do_leg:plt.legend(fontsize='small')
 
     threshold_stlye='new'
     if threshold_stlye=='old':
         print(thresholds)
         for thres, dt in thresholds.items():
             if dt is None: continue
             print('adding threshold lineL', thres, dt)
             if thres not in plot_thresholds: continue
 
             plt.axvline(x=float(dt.year)+0.5, c='k', ls=':' )
             x = float(dt.year) +0.02 *(np.max(ax.get_xlim()) - np.min(ax.get_xlim()))
             y = np.max(ax.get_ylim())- 0.11 * (np.max(ax.get_ylim()) - np.min(ax.get_ylim()))
             plt.text(x, y, 'GWT: ' +str(thres), ha='right', va='top', rotation=90) #fontsize=8, fontweight='bold',rotation=90)
 
 
    # threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
-    threshold_colours = {1.5: 'black', 2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
+    #threshold_colours = {1.: 'black', 1.5: 'black', 2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
 
     if threshold_stlye=='new':
         print(thresholds)
         for thres, dt in thresholds.items():
             if dt is None: continue
             if thres not in plot_thresholds: continue
             print('adding new threshold lineL', thres, dt)
             index = np.argmin(np.abs(dt.year- att))
             #print(dt.year, emt, index, emt[index], atd[index], emd[index],lud[index])
             x=float(dt.year)+0.5
             if plot_type == 'pc':
                 ymax=1.
             elif plot_type == 'area_over_zero':
                  ymax = atd_t[index]/2000.
             plt.axvline(
                 x=x,
                 ymin=0.,
                 ymax = ymax,
                 c=threshold_colours[thres],
                 alpha=0.7,
                 lw=1.7,
                 ls='-',)
 
             if plot_type == 'pc':
                 if thres == 1.5:
                     txt = ''.join(['1.5', r'$\degree$', 'C - ', str(int(dt.year))])
                 else: txt = str(int(thres)) + r'$\degree$'+'C - '+str(int(dt.year))
                 plt.text(x+2.4, 5, txt,
                     c = threshold_colours[thres],
                     ha='left', # Left puts txt on right of line. Right puts txt on left of line.
                     va='bottom', # top puts txt below x axes.
                     rotation=90)
                    # fontsize=8, fontweight='bold',rotation=90)
 
     plt.title(ssp_title_dict.get(ssp, None))
 
     # save plot.
     if save:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries'])
         path += '_'.join(['allocation_timeseries', plot_type, ssp]) + image_extention
         print('saving figure:', path)
         plt.savefig(path)
         plt.close()
     else: return fig, ax
 
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4222,357 +4333,357 @@
 def make_cumulative_timeseries(cfg, data_dict,
       thresholds_dict,
       ssp='historical-ssp126',
       dataset = 'CMIP6',
       ensemble = 'ensemble_mean',
       plot_type = 'pc', # 'pc', 'area_over_zero are the two in the megaplot.
       plot_thresholds = [1.5, 2.,3.,4.,5.],
       do_leg= True,
       fig = None, gs = None, ax= None,
 ):
     """
     Make a plot showing the time series of carbon allocation.
     """
     if None in [fig, ax]:
         fig = plt.figure()
         fig.set_size_inches(12, 6)
         gs = gridspec.GridSpec(1, 1,figure=fig )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
         ax =  fig.add_subplot(gs[0, 0])
         save = True
     else:
         save = False
     plt.sca(ax)
 
    # load data.
     cube_keys = ['fgco2gt_cumul', 'nbpgt_cumul']
     colours = {#'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     #colours = {'cumul_emissions': 'grey', 'fgco2gt_cumul':'blue', 'nbpgt_cumul':'orange', 'tls':'green', 'luegt':'red'}
     if ensemble == 'ensemble_mean':
         ensembles = ['ensemble_mean',]
     else: assert 0
     if isinstance(dataset, str):
          datasets = [dataset, ]
     else: assert 0
 
     if ssp[:3] == 'ssp':
          exps = ['historical', ssp, '-'.join(['historical', ssp])]
     elif ssp == 'historical': exps = ['historical', ]
 
     data = {k:{} for k in colours.keys()}
     for ssp_it, ensemble, key, dset in product(exps, ensembles, colours.keys(),datasets):
         print('load data', (dset, key, ssp_it, ensemble))
         tmp_data = data_dict.get((dset, key, ssp_it, ensemble), False)
         if not tmp_data:
             print('Did not find:', (dset, key, ssp_it, ensemble))
             continue
         print('load data: found:', (dset, key, ssp_it, ensemble))
         if key in cube_keys:
             tmp_data = {'time': diagtools.cube_time_to_float(tmp_data),
                              key: tmp_data.data}
 
         tmp_data = zip_time(tmp_data, key)
         data[key] = data[key] | tmp_data # combine two dicts (python 3.9 and later)
         print('load data', (key, ssp_it, ensemble),':', len(data[key].keys()))
 
     print(dataset, ssp, 'loaded data:',data.keys())
     # add atmos_stock:
     tmp_times, tmp_dat = unzip_time(data['atmos_carbon'])
     data['atmos_carbon'] = zip_time({'time':tmp_times, 'atmos_carbon':tmp_dat}, 'atmos_carbon')
 
     # found=0
     # for key in ['nbpgt_cumul', 'fgco2gt_cumul']:
     #     print('adding atmospheric stock', key)
     #     key_times, key_dat = unzip_time(data[key])
     #     print(dataset, ssp, tmp_dat, key_dat, key_times, tmp_times)
     #     if len(tmp_times) != len(key_times):
     #         print('error:', len(tmp_times), '!=', len(key_times))
     #         print('carbon_times:', tmp_times[0], tmp_times[-1])
     #         print(key, 'times', key_times[0], key_times[-1])
     #         assert 0
     #         continue
     #     tmp_dat = tmp_dat - key_dat
     #     found+=1
     # if found==0:return fig, ax
 
     #data['atmos_carbon'] = zip_time({'time':tmp_times, 'atmos_carbon':tmp_dat}, 'atmos_carbon')
     #colours['atmos_carbon'] = 'purple'
 
     thresholds = {}
     for ssp_it, ensemble, dset in product(exps, ensembles, datasets):
         dicts = thresholds_dict.get((dset, 'tas', ssp_it, ensemble), False)
         if not dicts:continue
         thresholds= thresholds|dicts
 
     # plot simple time series:
 #    if plot_type == 'simple_ts':
 #        for key, dat in data.items():
 #            times, dat_list = unzip_time(dat)
 #            #if key == 'tls':
 #            #    times, dat = times[:-1], dat[:-1]
 #            plt.plot(times,
 #                dat_list,
 #                lw=2,
 #                color=colours[key],
 #                label = key)
 #        plt.axhline(y=0., c='k', ls='--')
 #        if do_leg: plt.legend()
 #
 #    # plot simple time series:
 #    if plot_type == 'sink_source':
 #        for key, dat in data.items():
 #            times, dat_list = unzip_time(dat)
 #            if key in ['fgco2gt_cumul', 'nbpgt_cumul', 'tls', 'luegt']:
 #                dat_list = -1*dat_list
 #            plt.plot(times,
 #                dat_list,
 #                lw=2,
 #                color=colours[key],
 #                label = key)
 #        plt.axhline(y=0., c='k', ls='--')
 #        if do_leg: plt.legend()
 
     lat, lad = unzip_time(data['tls'])
     ont, ond = unzip_time(data['fgco2gt_cumul'])
     #        lut, lud = unzip_time(data['luegt'])
     nbt, nbd = unzip_time(data['nbpgt_cumul'])
     att, atd = unzip_time(data['atmos_carbon'])
     [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
     emt = lat[:]
     emd = lad + ond + atd
     aligned_interpolated_data_shelve = diagtools.folder([cfg['work_dir'], 'aligned_interpolated_data'])+'aligned_interpolated_data.shelve'
     sh = shelve.open(aligned_interpolated_data_shelve)
     sh['lat'] = lat
     sh['lad'] = lad
     sh['ont'] = ont
     sh['ond'] = ond
     sh['nbt'] = nbt
     sh['nbd'] = nbd
     sh['att'] = att
     sh['atd'] = atd
     sh['emt'] = emt
     sh['emd'] = emd
     sh.close()
 
 
     # plot simple time series:
     if plot_type in ['area', 'area_over_zero']:
         #colours = {'cumul_emissions': 'grey', 'fgco2gt_cumul':'blue', 'nbpgt_cumul':'orange', 'tls':'green'}
         print(data.keys())
         # emt, emd = unzip_time(data['cumul_emissions'])
         lat, lad = unzip_time(data['tls'])
         ont, ond = unzip_time(data['fgco2gt_cumul'])
 #        lut, lud = unzip_time(data['luegt'])
         nbt, nbd = unzip_time(data['nbpgt_cumul'])
         att, atd = unzip_time(data['atmos_carbon'])
 
         [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
 
 
         if plot_type in ['area',] :
             ond = -1.* ond
             lad = -1.*(lad + ond)
         if plot_type in ['area_over_zero',] :
             atd_t = atd + lad + ond # air land sea.
             lad_t = lad + ond
             ond_t = ond
 #            lad = lad+ond
  #           atd = atd + lad# air land sea.
 
             # print('emissions times:', emt[:5], emt[-5:])
 #            print('LUE times:', lut[:5], lut[-5:])
             #print('emissions data:', emd[:5], emd[-5:])
 #            print('LUE data :', lud[:5], lud[-5:])
             # print('sizes:', len(emt), len(emd), len(lut), len(lud))
 #            if np.max(lut) > np.max(att):
 #                lut = lut[:-1] # Remove 2015.5 (not in histor period)
 #                lud = lud[:-1]
 
 #            plt.plot(emt, emd+lud, 'k-', lw=1.3,label='Emissions+LUE')
 #            plt.plot(lat, lad, 'k--', lw=1.3, label='LUE')
         # water:
         # plt.plot(
         #     ont,
         #     ond,
         #     lw=2,
         #     color=colours['fgco2gt_cumul'],
         #     label = )
         ax.fill_between(# zero and blue line
             ont,
             np.zeros_like(ond_t),
             ond_t, # zero and blue line
             lw=0,
             label='Ocean',
             color=colours['fgco2gt_cumul'])
 
         # land:
         # plt.plot(
         #     lat,
         #     lad,
         #     lw=2,
         #     color=colours['tls'],
         #     label = 'True Land Sink')
         ax.fill_between( # blue line and land line
             lat,
             ond_t, # ocean line
             lad_t, # land + ocean
             #lw=2,
             color=colours['tls'],
             label = 'Land')
 
         # atmos
         # plt.plot(
         #     att,
         #     atd,
         #     lw=2,
         #     color=colours['cumul_emissions'],
         #     label = 'Atmosphere')
         ax.fill_between( # atmos anthro stock
             lat,
             lad_t, # land + ocean
             atd_t, # land ocean and air
             #lw=2,
             color=colours['atmos_carbon'],
             label = 'Atmosphere')
         #ax.set_xlim([2010., 2100])
         ax.set_ylabel('Cumulative carbon, Pg')
         if plot_type in ['area',]:
             plt.axhline(y=0., c='k', ls='--')
 
     # plot simple time series:
     if plot_type in ['pc', 'triple'] :
         colours = {'atmos_carbon': 'silver', 'fgco2gt_cumul':'dodgerblue', 'nbpgt_cumul':'orange', 'tls':'mediumseagreen'}
         # emt, emd = unzip_time(data['cumul_emissions'])
         lat, lad = unzip_time(data['tls'])
         ont, ond = unzip_time(data['fgco2gt_cumul'])
         #lut, lud = unzip_time(data['luegt'])
         nbt, nbd = unzip_time(data['nbpgt_cumul'])
         att, atd = unzip_time(data['atmos_carbon'])
         [[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]] = align_times([[lat, lad], [ont, ond ], [nbt, nbd], [att, atd]])
 
         total = ond + lad + atd
         water_land_line = (ond/total)*100.
         land_air_line = 100. *(ond + lad)/total
 
         water_land_line = np.ma.masked_invalid(water_land_line)
         land_air_line = np.ma.masked_invalid(land_air_line)
         # water:
         plt.plot(
             [], [],
             lw=6,
             color=colours['fgco2gt_cumul'],
             label = 'Air sea Flux of CO2')
         ax.fill_between(# zero and blue line
             att,
             0.* water_land_line, # zero and blue line
             water_land_line,
             color=colours['fgco2gt_cumul'])
 
         # land:
         plt.plot([],[],
             lw=6,
             color=colours['tls'],
             label = 'True Land Sink')
         ax.fill_between( # blue line and land line
             att,
             water_land_line,
             land_air_line,
             lw=2,
             color=colours['tls'])
 
         # atmos
         plt.plot([], [],
             lw=6,
             color=colours['atmos_carbon'],
             label = 'Atmosphere')
         ax.fill_between( # atmos anthro stock
             att,
             land_air_line,
             land_air_line*0. +100.,
             lw=2,
             color=colours['atmos_carbon'])
 
         #plt.axhline(y=0., c='k', ls='--')
         ax.set_ylabel('Percentage')
         #x.set_xlim([2010., 2100])
         ax.set_ylim([0., 100.])
 
     if ssp in ['historical', ]:
         if plot_type in ['pc', ]:
             plt.plot([1959.,1980., 2000., 2012.], [56., 56., 56., 56.,], c='k', ls=':', label = 'Raupach 2014' )
             plt.plot([1959.,1980., 2000., 2012.], [25., 25., 25., 25.,], c='navy', ls='-.', label = 'Watson 2020')
 
         else:
             plt.plot([], [], c='k', ls=':', label = 'Raupach 2014' )
             plt.plot([], [], c='navy', ls='-.', label = 'Watson 2020'  )
 
     if do_leg:plt.legend(fontsize='small')
 
     threshold_stlye='new'
     if threshold_stlye=='old':
         print(thresholds)
         for thres, dt in thresholds.items():
             if dt is None: continue
             print('adding threshold lineL', thres, dt)
             if thres not in plot_thresholds: continue
 
             plt.axvline(x=float(dt.year)+0.5, c='k', ls=':' )
             x = float(dt.year) +0.02 *(np.max(ax.get_xlim()) - np.min(ax.get_xlim()))
             y = np.max(ax.get_ylim())- 0.11 * (np.max(ax.get_ylim()) - np.min(ax.get_ylim()))
             plt.text(x, y, 'GWT: ' +str(thres), ha='right', va='top', rotation=90) #fontsize=8, fontweight='bold',rotation=90)
 
 
    # threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
     threshold_colours = {1.5: 'black', 2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
 
     if threshold_stlye=='new':
         print(thresholds)
         for thres, dt in thresholds.items():
             if dt is None: continue
             if thres not in plot_thresholds: continue
             print('adding new threshold lineL', thres, dt)
             index = np.argmin(np.abs(dt.year- att))
             #print(dt.year, emt, index, emt[index], atd[index], emd[index],lud[index])
             x=float(dt.year)+0.5
             if plot_type == 'pc':
                 ymax=1.
             elif plot_type == 'area_over_zero':
                  ymax = atd_t[index]/2000.
             plt.axvline(
                 x=x,
                 ymin=0.,
                 ymax = ymax,
                 c=threshold_colours[thres],
                 alpha=0.7,
                 lw=1.7,
                 ls='-',)
 
             if plot_type == 'pc':
                 if thres == 1.5:
-                    txt = ''.join('1.5', r'$\degree$', 'C - ', str(int(dt.year)))
+                    txt = ''.join(['1.5', r'$\degree$', 'C - ', str(int(dt.year))])
                 else: txt = str(int(thres)) + r'$\degree$'+'C - '+str(int(dt.year))
                 plt.text(x+2.4, 5, txt,
                     c = threshold_colours[thres],
                     ha='left', # Left puts txt on right of line. Right puts txt on left of line.
                     va='bottom', # top puts txt below x axes.
                     rotation=90)
                    # fontsize=8, fontweight='bold',rotation=90)
 
     plt.title(ssp_title_dict.get(ssp, None))
 
     # save plot.
     if save:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries'])
         path += '_'.join(['allocation_timeseries', plot_type, ssp]) + image_extention
         print('saving figure:', path)
         plt.savefig(path)
         plt.close()
     else: return fig, ax
 
 
 
commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4702,131 +4739,131 @@
 def make_cumulative_timeseries_megaplot(cfg, data_dict,
        thresholds_dict,
        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
        plot_types = ['pair', 'area_over_zero'],
        ensemble = 'ensemble_mean',
        dataset='CMIP6',):
     """
     Single plot massive thing.
     """
     fig = plt.figure()
     fig.set_size_inches(12, 8)
     gs = gridspec.GridSpec(5, 4, figure=fig,
           height_ratios=[1,1,0.25,1,1], hspace=0.1,
           width_ratios=[1,1,1,0.4], wspace=0.130 )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
 
     ssp_points = {
         'historical':[0, 0], # row, column
         'ssp119':[0, 1],
         'ssp126':[0, 2],
         'ssp245':[3, 0],
         'ssp370':[3, 1],
         'ssp585':[3, 2],
     }
     ax_leg = fig.add_subplot(gs[:, -1])
 
     for ssp in ssps:
         ax1 =  fig.add_subplot(gs[ssp_points[ssp][0], ssp_points[ssp][1]])
         ax2 =  fig.add_subplot(gs[ssp_points[ssp][0]+1,ssp_points[ssp][1]])
 
         fig, ax1 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'area_over_zero',
-            plot_thresholds = [1., 2., 3., 4.],
+            plot_thresholds = [2., 3., 4.],
             fig = fig,
             ax= ax1,
             do_leg=False,
         )
         ax1.set_ylim([0., 2000.])
         ax1.set_xticks([])
         ax1.set_title('')
         ax1.text(0.01, 1.01, sspify(ssp) , horizontalalignment='left',
             verticalalignment='bottom', transform=ax1.transAxes)
 
         fig, ax2 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'pc',
-            plot_thresholds = [1., 2., 3., 4.],
+            plot_thresholds = [2., 3., 4.], #1.
             fig = fig,
             ax= ax2,
             do_leg=False,
         )
         ax2.set_title('')
         #ax1.grid(axis='y')
         #ax2.grid(axis='y')
 
         if ssp_points[ssp][1]>0:
             ax1.set_ylabel('')
             ax2.set_ylabel('')
             ax1.set_yticks([])
             ax2.set_yticks([])
 
 #       if ssp_points[ssp][0]>0:
 #           ax1.set_xlabel('')
 #           ax2.set_xlabel('')
 
         if ssp == 'historical':
             ax1.set_xlim([1860., 2015.])
             ax2.set_xlim([1860., 2015.])
         else:
             ax1.set_xlim([2001., 2100.])
             ax2.set_xlim([2001., 2100.])
 
     plt.sca(ax_leg)
     colours = { #'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     plt.plot([],[], c='silver', lw=8, ls='-', label = 'Atmosphere')
     plt.plot([],[], c='mediumseagreen', lw=8, ls='-', label = 'Land')
     plt.plot([],[], c='dodgerblue', lw=8, ls='-', label = 'Ocean')
 
     #threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
     #threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
     #plt.plot([],[], c=threshold_colours[2.0], ls='-', lw=1.7, label='2'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[3.0], ls='-', lw=1.7, label='3'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[4.0], ls='-', lw=1.7, label='4'+r'$\degree$'+ ' GWT', alpha=0.7,)
 
     #plt.plot([],[], 'k-', lw=1.3,label='Emissions+LUE')
     #plt.plot([],[], 'k--', lw=1.3, label='LUE')
     plt.plot([], [], c='k', ls=':', label = 'Raupach (2014)' )
     plt.plot([], [], c='navy', ls='-.', label = 'Watson (2020)'  )
     add_ipcc = True
     if add_ipcc:
         plt.plot([], [], c='k', ls='-', lw=2.8,  label = 'SPM.7')
 
 
     legd = ax_leg.legend( #keys, labels,
         bbox_to_anchor=(1.7, 0.5),
         numpoints=1, labelspacing=1.2,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
     if dataset == 'CMIP6':
         plt.suptitle('Anthropogenic Carbon Allocation Timeseries')
     else:
         plt.suptitle(dataset+' Anthropogenic Carbon Allocation Timeseries')
 
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries_megaplot'])
     path += '_'.join(['allocation_timeseries', 'megaplot', dataset]) + image_extention
     print('saving figure:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4673,127 +4702,131 @@
 def make_cumulative_timeseries_megaplot(cfg, data_dict,
        thresholds_dict,
        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
        plot_types = ['pair', 'area_over_zero'],
        ensemble = 'ensemble_mean',
        dataset='CMIP6',):
     """
     Single plot massive thing.
     """
     fig = plt.figure()
     fig.set_size_inches(12, 8)
     gs = gridspec.GridSpec(5, 4, figure=fig,
           height_ratios=[1,1,0.25,1,1], hspace=0.1,
           width_ratios=[1,1,1,0.4], wspace=0.130 )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
 
     ssp_points = {
         'historical':[0, 0], # row, column
         'ssp119':[0, 1],
         'ssp126':[0, 2],
         'ssp245':[3, 0],
         'ssp370':[3, 1],
         'ssp585':[3, 2],
     }
     ax_leg = fig.add_subplot(gs[:, -1])
 
     for ssp in ssps:
         ax1 =  fig.add_subplot(gs[ssp_points[ssp][0], ssp_points[ssp][1]])
         ax2 =  fig.add_subplot(gs[ssp_points[ssp][0]+1,ssp_points[ssp][1]])
 
         fig, ax1 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'area_over_zero',
-            plot_thresholds = [2., 3., 4.],
+            plot_thresholds = [1., 2., 3., 4.],
             fig = fig,
             ax= ax1,
             do_leg=False,
         )
         ax1.set_ylim([0., 2000.])
         ax1.set_xticks([])
         ax1.set_title('')
         ax1.text(0.01, 1.01, sspify(ssp) , horizontalalignment='left',
             verticalalignment='bottom', transform=ax1.transAxes)
 
         fig, ax2 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'pc',
-            plot_thresholds = [2., 3., 4.],
+            plot_thresholds = [1., 2., 3., 4.],
             fig = fig,
             ax= ax2,
             do_leg=False,
         )
         ax2.set_title('')
         #ax1.grid(axis='y')
         #ax2.grid(axis='y')
 
         if ssp_points[ssp][1]>0:
             ax1.set_ylabel('')
             ax2.set_ylabel('')
             ax1.set_yticks([])
             ax2.set_yticks([])
 
 #       if ssp_points[ssp][0]>0:
 #           ax1.set_xlabel('')
 #           ax2.set_xlabel('')
 
         if ssp == 'historical':
             ax1.set_xlim([1860., 2015.])
             ax2.set_xlim([1860., 2015.])
         else:
-            ax1.set_xlim([2015., 2100.])
-            ax2.set_xlim([2015., 2100.])
+            ax1.set_xlim([2001., 2100.])
+            ax2.set_xlim([2001., 2100.])
 
     plt.sca(ax_leg)
     colours = { #'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     plt.plot([],[], c='silver', lw=8, ls='-', label = 'Atmosphere')
     plt.plot([],[], c='mediumseagreen', lw=8, ls='-', label = 'Land')
     plt.plot([],[], c='dodgerblue', lw=8, ls='-', label = 'Ocean')
 
     #threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
-    threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
+    #threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
     #plt.plot([],[], c=threshold_colours[2.0], ls='-', lw=1.7, label='2'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[3.0], ls='-', lw=1.7, label='3'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[4.0], ls='-', lw=1.7, label='4'+r'$\degree$'+ ' GWT', alpha=0.7,)
 
     #plt.plot([],[], 'k-', lw=1.3,label='Emissions+LUE')
     #plt.plot([],[], 'k--', lw=1.3, label='LUE')
     plt.plot([], [], c='k', ls=':', label = 'Raupach (2014)' )
     plt.plot([], [], c='navy', ls='-.', label = 'Watson (2020)'  )
+    add_ipcc = True
+    if add_ipcc:
+        plt.plot([], [], c='k', ls='-', lw=2.8,  label = 'SPM.7')
+
 
     legd = ax_leg.legend( #keys, labels,
         bbox_to_anchor=(1.7, 0.5),
         numpoints=1, labelspacing=1.2,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
     if dataset == 'CMIP6':
         plt.suptitle('Anthropogenic Carbon Allocation Timeseries')
     else:
         plt.suptitle(dataset+' Anthropogenic Carbon Allocation Timeseries')
 
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries_megaplot'])
     path += '_'.join(['allocation_timeseries', 'megaplot', dataset]) + image_extention
     print('saving figure:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 
commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3417,526 +3441,539 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
             fig = plt.figure()
 
             gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
             ax0 =  fig.add_subplot(gs[0, 0])
             ax1  =  fig.add_subplot(gs[1, 0])
             ax2  =  fig.add_subplot(gs[2, 0])
             #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
             fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
         stacked_hists = True 
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
+
+
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
+            if not isinstance(landc, float): assert 0
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         'HISTORICAL':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'HISTORICAL':'darkgrey',
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'HISTORICAL':'lightgrey',
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
 
-        print(threshold, xvalues, land,widths, colours_land, label_strs, edge_colours, linewidths)
+        print('threshold:', threshold, 
+              '\nxvalues:', xvalues, 
+              '\nland:', land,
+              '\nocean:', ocean,
+              '\nair:', air, 
+              '\nmwidths:', widths, 
+              '\ncolours_land:', colours_land,
+              '\nlabel_strs:', label_strs,
+              '\nedge_colours:', edge_colours, 
+              '\nlinewidths:', linewidths,
+              '\nplot_style:', plot_style)
         ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         plt.xticks(rotation=90, fontsize='xx-small')
         plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
         draw_hlines = False
         if draw_hlines:
             for exp in exps:
                 ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
                 ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
                 ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
     else:
         ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         if plot_style == 'percentages':
             ax1.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax1.set_ylabel('Total Carbon Allocation, Pg')
 
         label_dict = ['Atmosphere', 'Ocean', 'Land']
         for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
             plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
 
             if ax in [ax0, ax1]:
                 ax.xaxis.set_major_locator(MaxNLocator(integer=True))
                 ax.xaxis.set_ticklabels([])
 
             if ax in [ax2,]:
                 plt.xticks(rotation=90, fontsize='x-small')
 
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
         draw_hlines = False
         if draw_hlines:
             for ax in [ax0, ax1, ax2]:
                 xlims = ax.get_xlim()
                 new_xlims = [xlims[0], xlims[1]+2]
                 ax.set_xlim(new_xlims)
                 
             for exp in exps:
                 ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
                 ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
                 ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3412,522 +3417,526 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
             fig = plt.figure()
 
             gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
             ax0 =  fig.add_subplot(gs[0, 0])
             ax1  =  fig.add_subplot(gs[1, 0])
             ax2  =  fig.add_subplot(gs[2, 0])
             #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
             fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
-        stacked_hists = False
+        stacked_hists = True 
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
-        #'historical':'black',
+        'HISTORICAL':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
+        'HISTORICAL':'darkgrey',
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
+        'HISTORICAL':'lightgrey',
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
+
+        print(threshold, xvalues, land,widths, colours_land, label_strs, edge_colours, linewidths)
         ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         plt.xticks(rotation=90, fontsize='xx-small')
         plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
-
+        draw_hlines = False
         if draw_hlines:
             for exp in exps:
                 ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
                 ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
                 ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
     else:
         ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         if plot_style == 'percentages':
             ax1.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax1.set_ylabel('Total Carbon Allocation, Pg')
 
         label_dict = ['Atmosphere', 'Ocean', 'Land']
         for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
             plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
 
             if ax in [ax0, ax1]:
                 ax.xaxis.set_major_locator(MaxNLocator(integer=True))
                 ax.xaxis.set_ticklabels([])
 
             if ax in [ax2,]:
                 plt.xticks(rotation=90, fontsize='x-small')
 
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
         draw_hlines = False
         if draw_hlines:
             for ax in [ax0, ax1, ax2]:
                 xlims = ax.get_xlim()
                 new_xlims = [xlims[0], xlims[1]+2]
                 ax.set_xlim(new_xlims)
                 
             for exp in exps:
                 ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
                 ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
                 ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit 88250a26063f9f224ff7edac3bf44bd20eeaebcf
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jul 6 11:06:07 2022 +0100

    working here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3408,496 +3412,522 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
-    sorting='alphabetical',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
-            fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            fig = plt.figure()
+
+            gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
+            ax0 =  fig.add_subplot(gs[0, 0])
+            ax1  =  fig.add_subplot(gs[1, 0])
+            ax2  =  fig.add_subplot(gs[2, 0])
+            #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
         stacked_hists = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
-       ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-       ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-       ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
-       plt.xticks(rotation=90, fontsize='xx-small')
-       plt.xlim([-0.1, np.sum(widths)+0.1])
+        ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+        ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+        ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        plt.xticks(rotation=90, fontsize='xx-small')
+        plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
+
+        if draw_hlines:
+            for exp in exps:
+                ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
+                ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
+                ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+
     else:
-       ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-       ax1.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-       ax0.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
-       for ax in [ax0, ax1, ax2]:
+        ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+        ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+        ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        if plot_style == 'percentages':
+            ax1.set_ylabel('Fractional Carbon Allocation, %')
+        else:
+            ax1.set_ylabel('Total Carbon Allocation, Pg')
+
+        label_dict = ['Atmosphere', 'Ocean', 'Land']
+        for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
+            plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
+
+            if ax in [ax0, ax1]:
+                ax.xaxis.set_major_locator(MaxNLocator(integer=True))
+                ax.xaxis.set_ticklabels([])
+
+            if ax in [ax2,]:
+                plt.xticks(rotation=90, fontsize='x-small')
 
-            if plot_style == 'percentages':
-                ax.set_ylim([0., 100.,])
-                ax.set_ylabel('Fractional Carbon Allocation, %')
-            else:
-                ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
-    draw_hlines = False
-    if draw_hlines:
-        for exp in exps:
-            ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
-            ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
-            ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+        draw_hlines = False
+        if draw_hlines:
+            for ax in [ax0, ax1, ax2]:
+                xlims = ax.get_xlim()
+                new_xlims = [xlims[0], xlims[1]+2]
+                ax.set_xlim(new_xlims)
+                
+            for exp in exps:
+                ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
+                ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
+                ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
-
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
-        path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
+        path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit dc70598456f1f16e21d04d82b5ed4a3028d97864
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Thu Jun 30 10:04:45 2022 +0100

    Update diagnostic_gwt_timeseries.py

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3408,541 +3408,496 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     sorting='alphabetical',
+    stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
-        fig, ax = plt.subplots()
-        make_figure_here = True
+        if not stacked_hists:
+            fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            make_figure_here = True
+        else:
+            fig, ax = plt.subplots()
+            make_figure_here = True
     else:
         make_figure_here = False
+        stacked_hists = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
-    if group_by == 'gwlyear':
-
-        gwlyear_data = load_ecs_data()
-        gwlyear_data_ssp = {}
-        for exp in exps:
-            gwlyearS_data_ssp[exp] = {'CMIP6': []}
-
-            for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
-
-            for dat in datasets:
-                if dat=='CMIP6': continue
-                ecs = ECS_data.get(dat, False)
-                if not ecs: continue
-                ECS_data_ssp[exp]['CMIP6'].append(ecs)
-                ECS_data_ssp[exp][dat] = ecs
-            ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
-
-        print('ECS_data_ssp:', ECS_data_ssp)
-        for thr in thresholds:
-            for exp in exps:
-                new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
-                new_dataset_order=[k for v, k in new_dataset_order]
-
-#               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
-                print(thr, exp, 'new_dataset_order:', new_dataset_order)
- #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
-                #print(ECS_data_ssp)
-                #assert 0
-                #dataset_order = sortedECS_data_ssp.items()
-                #or dset,ecs in new_dataset_order.items():
-
-                for dset in new_dataset_order:
-                    print(dset,ecs)
-                    for ens in ensembles:
-                        if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
-                            continue
-                        if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
-                        if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
-                        unique_key = (dset, exp, ens, thr)
-                        if unique_key in unique_key_order: continue
-                        if unique_key not in remnants: continue
-                        print('Key added', unique_key)
-                        unique_key_order.append(unique_key)
-
-
+#     if group_by == 'gwlyear':
+#
+#         gwlyear_data = load_ecs_data()
+#         gwlyear_data_ssp = {}
+#         for exp in exps:
+#             gwlyearS_data_ssp[exp] = {'CMIP6': []}
+#
+#             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
+#         if t_dataset != plot_dataset: continue
+#         if t_short != 'tas': continue
+#         if t_ens != 'ensemble_mean': continue
+#         if t_exp != exp1: continue
+#             for dat in datasets:
+#                 if dat=='CMIP6': continue
+#                 ecs = ECS_data.get(dat, False)
+#                 if not ecs: continue
+#                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
+#                 ECS_data_ssp[exp][dat] = ecs
+#             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
+#
+#         print('ECS_data_ssp:', ECS_data_ssp)
+#         for thr in thresholds:
+#             for exp in exps:
+#                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
+#                 new_dataset_order=[k for v, k in new_dataset_order]
+#
+# #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
+#                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
+#  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
+#                 #print(ECS_data_ssp)
+#                 #assert 0
+#                 #dataset_order = sortedECS_data_ssp.items()
+#                 #or dset,ecs in new_dataset_order.items():
+#
+#                 for dset in new_dataset_order:
+#                     print(dset,ecs)
+#                     for ens in ensembles:
+#                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
+#                             continue
+#                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
+#                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
+#                         unique_key = (dset, exp, ens, thr)
+#                         if unique_key in unique_key_order: continue
+#                         if unique_key not in remnants: continue
+#                         print('Key added', unique_key)
+#                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
-        # Adds a blank line between models.
-        #if t_dataset not in previous_dats:
-        #    land.append(0.)
-        #    ocean.append(0.)
-        #    air.append(0.)
-        #    emissions_bottoms.append(0.)
-        #    experiments.append('')
-        #previous_dats[t_dataset] = True
-
-        #emissions_bottoms[unique_key]
-    #totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
-
-    # if atmos=='atmos_carbon':
-    #     emissions_diff = remnant
-    # else:
-    #     emissions_diff = [e - f - b for e,f,b in zip(emissions, fgco2gts, landcs )]
-    #emissions_diff = remnant
-    # emissions_bottoms = [f + b for f,b in zip(fgco2gts, landcs )]
-    # totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
-    #
-    # for i, exp  in enumerate(experiments):
-    #     print("Final values:",threshold, i, exp, totals[i], '=',emissions_diff[i],('or', remnant[i]), '+', landcs[i], '+', fgco2gts[i], '(a, l, o)')
-    # Add bars:
-    #if quit: assert 0
-    #for x,w,l in zip(xvalues, widths, labels): print(x,w,l)
-
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
-        
+
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
+    if stacked_hists:
+       ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+       ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+       ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+       plt.xticks(rotation=90, fontsize='xx-small')
+       plt.xlim([-0.1, np.sum(widths)+0.1])
+        if float(threshold) > 1850.:
+            ax.set_title(str(threshold))
+        else:
+            ax.set_title(str(threshold)+r'$\degree$'+' warming')
+
+        if plot_style == 'percentages':
+            ax.set_ylim([0., 100.,])
+            ax.set_ylabel('Fractional Carbon Allocation, %')
+        else:
+            ax.set_ylabel('Total Carbon Allocation, Pg')
+
+        if do_legend:
+            ax.legend()
+
+    else:
+       ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+       ax1.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+       ax0.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+       for ax in [ax0, ax1, ax2]:
+            plt.sca(ax)
+            plt.xlim([-0.1, np.sum(widths)+0.1])
+
+            if plot_style == 'percentages':
+                ax.set_ylim([0., 100.,])
+                ax.set_ylabel('Fractional Carbon Allocation, %')
+            else:
+                ax.set_ylabel('Total Carbon Allocation, Pg')
 
-    ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-    ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-    ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        if float(threshold) > 1850.:
+            ax0.set_title(str(threshold))
+        else:
+            ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
     draw_hlines = False
     if draw_hlines:
         for exp in exps:
             ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
             ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
             ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
-    plt.xticks(rotation=90, fontsize='xx-small')
-    plt.xlim([-0.1, np.sum(widths)+0.1])
-
-    # # Add bars:
-    # horizontal = False
-    # if horizontal:
-    #     ax.barh(experiments, land, label='Land', color='mediumseagreen')
-    #     ax.barh(experiments, ocean, left = land,  label='Ocean', color='dodgerblue')
-    #     ax.barh(experiments, air, left = emissions_bottoms,  label='Atmos', color='silver')
-    #     #ax.set_ylabel('Scenarios')
-    #     #lt.xticks(rotation=90)
-    # else:
-    #     ax.bar(experiments, land, width=1.0, label='Land', color='green')
-    #     ax.bar(experiments, ocean, width=1.0, bottom = land,  label='Ocean', color='dodgerblue')
-    #     ax.bar(experiments, air, width=1.0, bottom = emissions_bottoms,  label='Atmos', color='grey')
-    #     #ax.set_xlabel('Scenarios')
-    #     plt.xticks(rotation=90)
-    # Add percentages:
-    # add_pc_text = True
-    # if add_pc_text:
-    #     def pc(a,b): return str("{0:.1f}%".format(100.*a/b))
-    #     for e, exp in enumerate(experiments):
-    #         print(e, exp, landcs[e], fgco2gts[e], emissions_diff[e])
-    #         t = totals[e]
-    #         ax.text(landcs[e]/2, e, pc(landcs[e], t),
-    #                 color='#002200', #'darkgreen',
-    #                 fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-    #
-    #         ax.text(landcs[e]+fgco2gts[e]/2., e, pc(fgco2gts[e], t),
-    #                 color='darkblue', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-    #
-    #         ax.text(emissions_bottoms[e]+emissions_diff[e]/2., e, pc(emissions_diff[e],t ),
-    #                 color='black', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-
-    # Add mean year:
-    # add_mean_year = False
-    # if add_mean_year:
-    #     for e, exp in enumerate(experiments):
-    #         t = totals[e]
-    #         yr = threshold_years[e]
-    #         ax.text(t *1.05, e, str(int(yr)),
-    #                 color='black', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
 
-    if float(threshold) > 1850.:
-        ax.set_title(str(threshold))
-    else:
-        ax.set_title(str(threshold)+r'$\degree$'+' warming')
-
-    if plot_style == 'percentages':
-        ax.set_ylim([0., 100.,])
-        ax.set_ylabel('Fractional Carbon Allocation, %')
-    else:
-        ax.set_ylabel('Total Carbon Allocation, Pg')
-
-
-    if do_legend:
-        ax.legend()
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3365,473 +3408,541 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     sorting='alphabetical',
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         fig, ax = plt.subplots()
         make_figure_here = True
     else:
         make_figure_here = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
+    if group_by == 'gwlyear':
+
+        gwlyear_data = load_ecs_data()
+        gwlyear_data_ssp = {}
+        for exp in exps:
+            gwlyearS_data_ssp[exp] = {'CMIP6': []}
+
+            for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
+
+            for dat in datasets:
+                if dat=='CMIP6': continue
+                ecs = ECS_data.get(dat, False)
+                if not ecs: continue
+                ECS_data_ssp[exp]['CMIP6'].append(ecs)
+                ECS_data_ssp[exp][dat] = ecs
+            ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
+
+        print('ECS_data_ssp:', ECS_data_ssp)
+        for thr in thresholds:
+            for exp in exps:
+                new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
+                new_dataset_order=[k for v, k in new_dataset_order]
+
+#               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
+                print(thr, exp, 'new_dataset_order:', new_dataset_order)
+ #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
+                #print(ECS_data_ssp)
+                #assert 0
+                #dataset_order = sortedECS_data_ssp.items()
+                #or dset,ecs in new_dataset_order.items():
+
+                for dset in new_dataset_order:
+                    print(dset,ecs)
+                    for ens in ensembles:
+                        if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
+                            continue
+                        if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
+                        if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
+                        unique_key = (dset, exp, ens, thr)
+                        if unique_key in unique_key_order: continue
+                        if unique_key not in remnants: continue
+                        print('Key added', unique_key)
+                        unique_key_order.append(unique_key)
+
+
+
+
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
+    hline_land = {exp:[] for exp in exps}
+    hline_air = {exp:[] for exp in exps}
+    hline_ocean = {exp:[] for exp in exps}
+
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
+
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
+
+
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
+        hline_land[t_exp].append(land[-1])
+        hline_ocean[t_exp].append(emissions_bottoms[-1])
+        hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
+
+
         # Adds a blank line between models.
         #if t_dataset not in previous_dats:
         #    land.append(0.)
         #    ocean.append(0.)
         #    air.append(0.)
         #    emissions_bottoms.append(0.)
         #    experiments.append('')
         #previous_dats[t_dataset] = True
 
         #emissions_bottoms[unique_key]
     #totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
 
     # if atmos=='atmos_carbon':
     #     emissions_diff = remnant
     # else:
     #     emissions_diff = [e - f - b for e,f,b in zip(emissions, fgco2gts, landcs )]
     #emissions_diff = remnant
     # emissions_bottoms = [f + b for f,b in zip(fgco2gts, landcs )]
     # totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
     #
     # for i, exp  in enumerate(experiments):
     #     print("Final values:",threshold, i, exp, totals[i], '=',emissions_diff[i],('or', remnant[i]), '+', landcs[i], '+', fgco2gts[i], '(a, l, o)')
     # Add bars:
     #if quit: assert 0
     #for x,w,l in zip(xvalues, widths, labels): print(x,w,l)
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
+
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
-
+        
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
 
     ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
     ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
     ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
 
+    draw_hlines = False
+    if draw_hlines:
+        for exp in exps:
+            ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
+            ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
+            ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+
+
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
     plt.xticks(rotation=90, fontsize='xx-small')
     plt.xlim([-0.1, np.sum(widths)+0.1])
 
     # # Add bars:
     # horizontal = False
     # if horizontal:
     #     ax.barh(experiments, land, label='Land', color='mediumseagreen')
     #     ax.barh(experiments, ocean, left = land,  label='Ocean', color='dodgerblue')
     #     ax.barh(experiments, air, left = emissions_bottoms,  label='Atmos', color='silver')
     #     #ax.set_ylabel('Scenarios')
     #     #lt.xticks(rotation=90)
     # else:
     #     ax.bar(experiments, land, width=1.0, label='Land', color='green')
     #     ax.bar(experiments, ocean, width=1.0, bottom = land,  label='Ocean', color='dodgerblue')
     #     ax.bar(experiments, air, width=1.0, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #     #ax.set_xlabel('Scenarios')
     #     plt.xticks(rotation=90)
     # Add percentages:
     # add_pc_text = True
     # if add_pc_text:
     #     def pc(a,b): return str("{0:.1f}%".format(100.*a/b))
     #     for e, exp in enumerate(experiments):
     #         print(e, exp, landcs[e], fgco2gts[e], emissions_diff[e])
     #         t = totals[e]
     #         ax.text(landcs[e]/2, e, pc(landcs[e], t),
     #                 color='#002200', #'darkgreen',
     #                 fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
     #
     #         ax.text(landcs[e]+fgco2gts[e]/2., e, pc(fgco2gts[e], t),
     #                 color='darkblue', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
     #
     #         ax.text(emissions_bottoms[e]+emissions_diff[e]/2., e, pc(emissions_diff[e],t ),
     #                 color='black', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
 
     # Add mean year:
     # add_mean_year = False
     # if add_mean_year:
     #     for e, exp in enumerate(experiments):
     #         t = totals[e]
     #         yr = threshold_years[e]
     #         ax.text(t *1.05, e, str(int(yr)),
     #                 color='black', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
 
     if float(threshold) > 1850.:
         ax.set_title(str(threshold))
     else:
         ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
     if plot_style == 'percentages':
         ax.set_ylim([0., 100.,])
         ax.set_ylabel('Fractional Carbon Allocation, %')
     else:
         ax.set_ylabel('Total Carbon Allocation, Pg')
 
 
     if do_legend:
         ax.legend()
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 
commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3417,526 +3441,539 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
             fig = plt.figure()
 
             gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
             ax0 =  fig.add_subplot(gs[0, 0])
             ax1  =  fig.add_subplot(gs[1, 0])
             ax2  =  fig.add_subplot(gs[2, 0])
             #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
             fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
         stacked_hists = True 
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
+
+
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
+            if not isinstance(landc, float): assert 0
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         'HISTORICAL':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'HISTORICAL':'darkgrey',
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'HISTORICAL':'lightgrey',
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
 
-        print(threshold, xvalues, land,widths, colours_land, label_strs, edge_colours, linewidths)
+        print('threshold:', threshold, 
+              '\nxvalues:', xvalues, 
+              '\nland:', land,
+              '\nocean:', ocean,
+              '\nair:', air, 
+              '\nmwidths:', widths, 
+              '\ncolours_land:', colours_land,
+              '\nlabel_strs:', label_strs,
+              '\nedge_colours:', edge_colours, 
+              '\nlinewidths:', linewidths,
+              '\nplot_style:', plot_style)
         ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         plt.xticks(rotation=90, fontsize='xx-small')
         plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
         draw_hlines = False
         if draw_hlines:
             for exp in exps:
                 ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
                 ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
                 ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
     else:
         ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         if plot_style == 'percentages':
             ax1.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax1.set_ylabel('Total Carbon Allocation, Pg')
 
         label_dict = ['Atmosphere', 'Ocean', 'Land']
         for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
             plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
 
             if ax in [ax0, ax1]:
                 ax.xaxis.set_major_locator(MaxNLocator(integer=True))
                 ax.xaxis.set_ticklabels([])
 
             if ax in [ax2,]:
                 plt.xticks(rotation=90, fontsize='x-small')
 
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
         draw_hlines = False
         if draw_hlines:
             for ax in [ax0, ax1, ax2]:
                 xlims = ax.get_xlim()
                 new_xlims = [xlims[0], xlims[1]+2]
                 ax.set_xlim(new_xlims)
                 
             for exp in exps:
                 ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
                 ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
                 ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3412,522 +3417,526 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
             fig = plt.figure()
 
             gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
             ax0 =  fig.add_subplot(gs[0, 0])
             ax1  =  fig.add_subplot(gs[1, 0])
             ax2  =  fig.add_subplot(gs[2, 0])
             #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
             fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
-        stacked_hists = False
+        stacked_hists = True 
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
-        #'historical':'black',
+        'HISTORICAL':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
+        'HISTORICAL':'darkgrey',
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
+        'HISTORICAL':'lightgrey',
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
+
+        print(threshold, xvalues, land,widths, colours_land, label_strs, edge_colours, linewidths)
         ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         plt.xticks(rotation=90, fontsize='xx-small')
         plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
-
+        draw_hlines = False
         if draw_hlines:
             for exp in exps:
                 ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
                 ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
                 ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
     else:
         ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
         ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
         ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
         if plot_style == 'percentages':
             ax1.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax1.set_ylabel('Total Carbon Allocation, Pg')
 
         label_dict = ['Atmosphere', 'Ocean', 'Land']
         for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
             plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
 
             if ax in [ax0, ax1]:
                 ax.xaxis.set_major_locator(MaxNLocator(integer=True))
                 ax.xaxis.set_ticklabels([])
 
             if ax in [ax2,]:
                 plt.xticks(rotation=90, fontsize='x-small')
 
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
         draw_hlines = False
         if draw_hlines:
             for ax in [ax0, ax1, ax2]:
                 xlims = ax.get_xlim()
                 new_xlims = [xlims[0], xlims[1]+2]
                 ax.set_xlim(new_xlims)
                 
             for exp in exps:
                 ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
                 ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
                 ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit 88250a26063f9f224ff7edac3bf44bd20eeaebcf
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jul 6 11:06:07 2022 +0100

    working here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3408,496 +3412,522 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
-    sorting='alphabetical',
     stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         if not stacked_hists:
-            fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            fig = plt.figure()
+
+            gs = gridspec.GridSpec(4, 1, figure=fig, hspace=0.1230,height_ratios=[1., 1. ,1., 0.4])
+            ax0 =  fig.add_subplot(gs[0, 0])
+            ax1  =  fig.add_subplot(gs[1, 0])
+            ax2  =  fig.add_subplot(gs[2, 0])
+            #fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            fig.set_size_inches(6, 5)
             make_figure_here = True
         else:
             fig, ax = plt.subplots()
             make_figure_here = True
     else:
         make_figure_here = False
         stacked_hists = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
 #     if group_by == 'gwlyear':
 #
 #         gwlyear_data = load_ecs_data()
 #         gwlyear_data_ssp = {}
 #         for exp in exps:
 #             gwlyearS_data_ssp[exp] = {'CMIP6': []}
 #
 #             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
 #         if t_dataset != plot_dataset: continue
 #         if t_short != 'tas': continue
 #         if t_ens != 'ensemble_mean': continue
 #         if t_exp != exp1: continue
 #             for dat in datasets:
 #                 if dat=='CMIP6': continue
 #                 ecs = ECS_data.get(dat, False)
 #                 if not ecs: continue
 #                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
 #                 ECS_data_ssp[exp][dat] = ecs
 #             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 #
 #         print('ECS_data_ssp:', ECS_data_ssp)
 #         for thr in thresholds:
 #             for exp in exps:
 #                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
 #                 new_dataset_order=[k for v, k in new_dataset_order]
 #
 # #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
 #                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
 #  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
 #                 #print(ECS_data_ssp)
 #                 #assert 0
 #                 #dataset_order = sortedECS_data_ssp.items()
 #                 #or dset,ecs in new_dataset_order.items():
 #
 #                 for dset in new_dataset_order:
 #                     print(dset,ecs)
 #                     for ens in ensembles:
 #                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
 #                             continue
 #                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
 #                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
 #                         unique_key = (dset, exp, ens, thr)
 #                         if unique_key in unique_key_order: continue
 #                         if unique_key not in remnants: continue
 #                         print('Key added', unique_key)
 #                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
 
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
     if stacked_hists:
-       ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-       ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-       ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
-       plt.xticks(rotation=90, fontsize='xx-small')
-       plt.xlim([-0.1, np.sum(widths)+0.1])
+        ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+        ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+        ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        plt.xticks(rotation=90, fontsize='xx-small')
+        plt.xlim([-0.1, np.sum(widths)+0.1])
         if float(threshold) > 1850.:
             ax.set_title(str(threshold))
         else:
             ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
         if plot_style == 'percentages':
             ax.set_ylim([0., 100.,])
             ax.set_ylabel('Fractional Carbon Allocation, %')
         else:
             ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if do_legend:
             ax.legend()
 
+
+        if draw_hlines:
+            for exp in exps:
+                ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
+                ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
+                ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+
     else:
-       ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-       ax1.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-       ax0.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
-       for ax in [ax0, ax1, ax2]:
+        ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+        ax1.bar(xvalues, ocean, width=widths, label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+        ax0.bar(xvalues, air, width=widths, label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        if plot_style == 'percentages':
+            ax1.set_ylabel('Fractional Carbon Allocation, %')
+        else:
+            ax1.set_ylabel('Total Carbon Allocation, Pg')
+
+        label_dict = ['Atmosphere', 'Ocean', 'Land']
+        for ax, label in zip([ax0, ax1, ax2], label_dict):
             plt.sca(ax)
             plt.xlim([-0.1, np.sum(widths)+0.1])
+            plt.text(ax.get_xlim()[1]*0.02, ax.get_ylim()[1]*0.95,  label, ha='left', va='top') #fontsize=8, fontweight='bold',rotation=90)
+
+            if ax in [ax0, ax1]:
+                ax.xaxis.set_major_locator(MaxNLocator(integer=True))
+                ax.xaxis.set_ticklabels([])
+
+            if ax in [ax2,]:
+                plt.xticks(rotation=90, fontsize='x-small')
 
-            if plot_style == 'percentages':
-                ax.set_ylim([0., 100.,])
-                ax.set_ylabel('Fractional Carbon Allocation, %')
-            else:
-                ax.set_ylabel('Total Carbon Allocation, Pg')
 
         if float(threshold) > 1850.:
             ax0.set_title(str(threshold))
         else:
             ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
-    draw_hlines = False
-    if draw_hlines:
-        for exp in exps:
-            ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
-            ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
-            ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+        draw_hlines = False
+        if draw_hlines:
+            for ax in [ax0, ax1, ax2]:
+                xlims = ax.get_xlim()
+                new_xlims = [xlims[0], xlims[1]+2]
+                ax.set_xlim(new_xlims)
+                
+            for exp in exps:
+                ax2.axhline(np.mean(hline_land[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_land[exp])
+                ax1.axhline(np.mean(hline_ocean[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_ocean[exp])
+                ax0.axhline(np.mean(hline_air[exp]), xmin=new_xlims[1]-2., xmax=new_xlims[1], lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
 
-
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
-        path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
+        path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, group_by, ensemble_key, plot_style, ]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit dc70598456f1f16e21d04d82b5ed4a3028d97864
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Thu Jun 30 10:04:45 2022 +0100

    Update diagnostic_gwt_timeseries.py

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3408,541 +3408,496 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     sorting='alphabetical',
+    stacked_hists=False,
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
-        fig, ax = plt.subplots()
-        make_figure_here = True
+        if not stacked_hists:
+            fig, (ax0, ax1, ax2) = plt.subplots(3, 1)
+            make_figure_here = True
+        else:
+            fig, ax = plt.subplots()
+            make_figure_here = True
     else:
         make_figure_here = False
+        stacked_hists = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
-    if group_by == 'gwlyear':
-
-        gwlyear_data = load_ecs_data()
-        gwlyear_data_ssp = {}
-        for exp in exps:
-            gwlyearS_data_ssp[exp] = {'CMIP6': []}
-
-            for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
-
-            for dat in datasets:
-                if dat=='CMIP6': continue
-                ecs = ECS_data.get(dat, False)
-                if not ecs: continue
-                ECS_data_ssp[exp]['CMIP6'].append(ecs)
-                ECS_data_ssp[exp][dat] = ecs
-            ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
-
-        print('ECS_data_ssp:', ECS_data_ssp)
-        for thr in thresholds:
-            for exp in exps:
-                new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
-                new_dataset_order=[k for v, k in new_dataset_order]
-
-#               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
-                print(thr, exp, 'new_dataset_order:', new_dataset_order)
- #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
-                #print(ECS_data_ssp)
-                #assert 0
-                #dataset_order = sortedECS_data_ssp.items()
-                #or dset,ecs in new_dataset_order.items():
-
-                for dset in new_dataset_order:
-                    print(dset,ecs)
-                    for ens in ensembles:
-                        if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
-                            continue
-                        if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
-                        if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
-                        unique_key = (dset, exp, ens, thr)
-                        if unique_key in unique_key_order: continue
-                        if unique_key not in remnants: continue
-                        print('Key added', unique_key)
-                        unique_key_order.append(unique_key)
-
-
+#     if group_by == 'gwlyear':
+#
+#         gwlyear_data = load_ecs_data()
+#         gwlyear_data_ssp = {}
+#         for exp in exps:
+#             gwlyearS_data_ssp[exp] = {'CMIP6': []}
+#
+#             for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
+#         if t_dataset != plot_dataset: continue
+#         if t_short != 'tas': continue
+#         if t_ens != 'ensemble_mean': continue
+#         if t_exp != exp1: continue
+#             for dat in datasets:
+#                 if dat=='CMIP6': continue
+#                 ecs = ECS_data.get(dat, False)
+#                 if not ecs: continue
+#                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
+#                 ECS_data_ssp[exp][dat] = ecs
+#             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
+#
+#         print('ECS_data_ssp:', ECS_data_ssp)
+#         for thr in thresholds:
+#             for exp in exps:
+#                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
+#                 new_dataset_order=[k for v, k in new_dataset_order]
+#
+# #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
+#                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
+#  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
+#                 #print(ECS_data_ssp)
+#                 #assert 0
+#                 #dataset_order = sortedECS_data_ssp.items()
+#                 #or dset,ecs in new_dataset_order.items():
+#
+#                 for dset in new_dataset_order:
+#                     print(dset,ecs)
+#                     for ens in ensembles:
+#                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
+#                             continue
+#                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
+#                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
+#                         unique_key = (dset, exp, ens, thr)
+#                         if unique_key in unique_key_order: continue
+#                         if unique_key not in remnants: continue
+#                         print('Key added', unique_key)
+#                         unique_key_order.append(unique_key)
 
 
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
     hline_land = {exp:[] for exp in exps}
     hline_air = {exp:[] for exp in exps}
     hline_ocean = {exp:[] for exp in exps}
 
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
 
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
 
 
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
         hline_land[t_exp].append(land[-1])
         hline_ocean[t_exp].append(emissions_bottoms[-1])
         hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
 
 
-        # Adds a blank line between models.
-        #if t_dataset not in previous_dats:
-        #    land.append(0.)
-        #    ocean.append(0.)
-        #    air.append(0.)
-        #    emissions_bottoms.append(0.)
-        #    experiments.append('')
-        #previous_dats[t_dataset] = True
-
-        #emissions_bottoms[unique_key]
-    #totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
-
-    # if atmos=='atmos_carbon':
-    #     emissions_diff = remnant
-    # else:
-    #     emissions_diff = [e - f - b for e,f,b in zip(emissions, fgco2gts, landcs )]
-    #emissions_diff = remnant
-    # emissions_bottoms = [f + b for f,b in zip(fgco2gts, landcs )]
-    # totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
-    #
-    # for i, exp  in enumerate(experiments):
-    #     print("Final values:",threshold, i, exp, totals[i], '=',emissions_diff[i],('or', remnant[i]), '+', landcs[i], '+', fgco2gts[i], '(a, l, o)')
-    # Add bars:
-    #if quit: assert 0
-    #for x,w,l in zip(xvalues, widths, labels): print(x,w,l)
-
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
 
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
-        
+
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
+    if stacked_hists:
+       ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+       ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+       ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+       plt.xticks(rotation=90, fontsize='xx-small')
+       plt.xlim([-0.1, np.sum(widths)+0.1])
+        if float(threshold) > 1850.:
+            ax.set_title(str(threshold))
+        else:
+            ax.set_title(str(threshold)+r'$\degree$'+' warming')
+
+        if plot_style == 'percentages':
+            ax.set_ylim([0., 100.,])
+            ax.set_ylabel('Fractional Carbon Allocation, %')
+        else:
+            ax.set_ylabel('Total Carbon Allocation, Pg')
+
+        if do_legend:
+            ax.legend()
+
+    else:
+       ax2.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
+       ax1.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
+       ax0.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+       for ax in [ax0, ax1, ax2]:
+            plt.sca(ax)
+            plt.xlim([-0.1, np.sum(widths)+0.1])
+
+            if plot_style == 'percentages':
+                ax.set_ylim([0., 100.,])
+                ax.set_ylabel('Fractional Carbon Allocation, %')
+            else:
+                ax.set_ylabel('Total Carbon Allocation, Pg')
 
-    ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
-    ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
-    ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
+        if float(threshold) > 1850.:
+            ax0.set_title(str(threshold))
+        else:
+            ax0.set_title(str(threshold)+r'$\degree$'+' warming')
 
     draw_hlines = False
     if draw_hlines:
         for exp in exps:
             ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
             ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
             ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
 
 
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
-    plt.xticks(rotation=90, fontsize='xx-small')
-    plt.xlim([-0.1, np.sum(widths)+0.1])
-
-    # # Add bars:
-    # horizontal = False
-    # if horizontal:
-    #     ax.barh(experiments, land, label='Land', color='mediumseagreen')
-    #     ax.barh(experiments, ocean, left = land,  label='Ocean', color='dodgerblue')
-    #     ax.barh(experiments, air, left = emissions_bottoms,  label='Atmos', color='silver')
-    #     #ax.set_ylabel('Scenarios')
-    #     #lt.xticks(rotation=90)
-    # else:
-    #     ax.bar(experiments, land, width=1.0, label='Land', color='green')
-    #     ax.bar(experiments, ocean, width=1.0, bottom = land,  label='Ocean', color='dodgerblue')
-    #     ax.bar(experiments, air, width=1.0, bottom = emissions_bottoms,  label='Atmos', color='grey')
-    #     #ax.set_xlabel('Scenarios')
-    #     plt.xticks(rotation=90)
-    # Add percentages:
-    # add_pc_text = True
-    # if add_pc_text:
-    #     def pc(a,b): return str("{0:.1f}%".format(100.*a/b))
-    #     for e, exp in enumerate(experiments):
-    #         print(e, exp, landcs[e], fgco2gts[e], emissions_diff[e])
-    #         t = totals[e]
-    #         ax.text(landcs[e]/2, e, pc(landcs[e], t),
-    #                 color='#002200', #'darkgreen',
-    #                 fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-    #
-    #         ax.text(landcs[e]+fgco2gts[e]/2., e, pc(fgco2gts[e], t),
-    #                 color='darkblue', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-    #
-    #         ax.text(emissions_bottoms[e]+emissions_diff[e]/2., e, pc(emissions_diff[e],t ),
-    #                 color='black', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
-
-    # Add mean year:
-    # add_mean_year = False
-    # if add_mean_year:
-    #     for e, exp in enumerate(experiments):
-    #         t = totals[e]
-    #         yr = threshold_years[e]
-    #         ax.text(t *1.05, e, str(int(yr)),
-    #                 color='black', fontsize=8 , # fontweight='bold',
-    #                 verticalalignment='center',horizontalalignment='center')
 
-    if float(threshold) > 1850.:
-        ax.set_title(str(threshold))
-    else:
-        ax.set_title(str(threshold)+r'$\degree$'+' warming')
-
-    if plot_style == 'percentages':
-        ax.set_ylim([0., 100.,])
-        ax.set_ylabel('Fractional Carbon Allocation, %')
-    else:
-        ax.set_ylabel('Total Carbon Allocation, Pg')
-
-
-    if do_legend:
-        ax.legend()
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3365,473 +3408,541 @@
 def make_ensemble_barchart_pane(
     cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     year0 = None,
     do_legend=True,
     land_carbon = 'nbpgt',
     #atmos='atmos_carbon',
     ensemble_key = 'ensemble_mean',
     plot_style = 'percentages',
     group_by = 'group_by_model',
     sorting='alphabetical',
     fig=None,
     ax=None):
     """
     Make a bar chart (of my favourite pies)
 
     Ensemble plot
     """
     if fig == None:
         fig, ax = plt.subplots()
         make_figure_here = True
     else:
         make_figure_here = False
         plt.sca(ax)
 
     # single pane, single threshold
     remnants, landcs, fgco2gts = prepare_percentages_data(cfg,
         data_dict,
         thresholds_dict,
         threshold = threshold,
         land_carbon = 'tls')
 
     datasets, exps, ensembles, thresholds = {}, {}, {}, {}
     # only_one_ensemble = {}
     ecs_keys = {}
     for unique_key, remnant in remnants.items():
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
         datasets[t_dataset] = True
         exps[t_exp] = True
         ensembles[t_ens] = True
         thresholds[t_threshold] = True
         ecs_keys[(t_dataset, t_exp)] = True
 
     exps = sorted(list(exps.keys()))
     thresholds = sorted(list(thresholds.keys()))
 
     ensembles = sorted(list(ensembles.keys()))
     ensembles.insert(0,  ensembles.pop(ensembles.index('ensemble_mean')))
 
     datasets = sorted(list(datasets.keys()))
     datasets.insert(0,  datasets.pop(datasets.index('CMIP6')))
 
     # Build a list of keys.
     unique_key_order = []
     # order is dataset [CMIP then others], ssps, ensemble means, then ensemble members
     # Order by model:
     if group_by == 'ecs':
 
         ECS_data = load_ecs_data()
         ECS_data_ssp = {}
         for exp in exps:
             ECS_data_ssp[exp] = {'CMIP6': []}
             for dat in datasets:
                 if dat=='CMIP6': continue
                 ecs = ECS_data.get(dat, False)
                 if not ecs: continue
                 ECS_data_ssp[exp]['CMIP6'].append(ecs)
                 ECS_data_ssp[exp][dat] = ecs
             ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
 
         print('ECS_data_ssp:', ECS_data_ssp)
         for thr in thresholds:
             for exp in exps:
                 new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
                 new_dataset_order=[k for v, k in new_dataset_order]
 
 #               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
                 print(thr, exp, 'new_dataset_order:', new_dataset_order)
  #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
                 #print(ECS_data_ssp)
                 #assert 0
                 #dataset_order = sortedECS_data_ssp.items()
                 #or dset,ecs in new_dataset_order.items():
 
                 for dset in new_dataset_order:
                     print(dset,ecs)
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
+    if group_by == 'gwlyear':
+
+        gwlyear_data = load_ecs_data()
+        gwlyear_data_ssp = {}
+        for exp in exps:
+            gwlyearS_data_ssp[exp] = {'CMIP6': []}
+
+            for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
+
+            for dat in datasets:
+                if dat=='CMIP6': continue
+                ecs = ECS_data.get(dat, False)
+                if not ecs: continue
+                ECS_data_ssp[exp]['CMIP6'].append(ecs)
+                ECS_data_ssp[exp][dat] = ecs
+            ECS_data_ssp[exp]['CMIP6'] = np.mean(ECS_data_ssp[exp]['CMIP6'])
+
+        print('ECS_data_ssp:', ECS_data_ssp)
+        for thr in thresholds:
+            for exp in exps:
+                new_dataset_order = sorted((value, key) for (key,value) in ECS_data_ssp[exp].items())
+                new_dataset_order=[k for v, k in new_dataset_order]
+
+#               new_dataset_order = {d:ecs for (d, e), ecs in ECS_data_ssp.items() if e == exp}
+                print(thr, exp, 'new_dataset_order:', new_dataset_order)
+ #              new_dataset_order = sorted(new_dataset_order.items(), key=lambda x:x[1])
+                #print(ECS_data_ssp)
+                #assert 0
+                #dataset_order = sortedECS_data_ssp.items()
+                #or dset,ecs in new_dataset_order.items():
+
+                for dset in new_dataset_order:
+                    print(dset,ecs)
+                    for ens in ensembles:
+                        if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
+                            continue
+                        if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
+                        if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
+                        unique_key = (dset, exp, ens, thr)
+                        if unique_key in unique_key_order: continue
+                        if unique_key not in remnants: continue
+                        print('Key added', unique_key)
+                        unique_key_order.append(unique_key)
+
+
+
+
     if group_by == 'group_by_model':
         for thr in thresholds:
             for dset in datasets:
                for exp in exps:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     if group_by == 'group_by_ssp':
         for thr in thresholds:
             for exp in exps:
                 for dset in datasets:
                     for ens in ensembles:
                         if ensemble_key == 'ensemble_mean' and ens != 'ensemble_mean':
                             continue
                         if ensemble_key != 'ensemble_mean' and ens == 'ensemble_mean' and dset!= 'CMIP6': continue
                         if dset.find('UKESM')>-1: print(dset, exp, ens, thr)
                         unique_key = (dset, exp, ens, thr)
                         if unique_key in unique_key_order: continue
                         if unique_key not in remnants: continue
                         print('Key added', unique_key)
                         unique_key_order.append(unique_key)
 
     #totals={}
     labels, land, air, ocean = [], [], [], []
     xvalues = []
     widths = []
     emissions_bottoms = []
 
     previous_datasets = {}
 #    if ensemble_key == 'ensemble_mean':
 #        gap = 0.3
 #    else: gap = 0.6
     quit = False
 
     if ensemble_key == 'ensemble_mean':
         print(group_by, unique_key_order)
         #assert 0
 
     make_table_here = True
     if make_table_here:
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_barcharts_csv' ])
         csvpath += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = 'Count, model, exp, ensemble, threshold, atmos, land, ocean, total, \n'
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             remnant = remnants[unique_key]
             landc = landcs[unique_key]
             oceanc = fgco2gts[unique_key]
             total = remnant + landc + oceanc
 
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             line1 = ', '.join([str(i), t_dataset, t_exp, t_ens, t_threshold])
             line2 = ', '.join([str(v) for v in [remnant, landc, oceanc, total, '\n']])
             out_txt  += line1 +', '+line2
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
         csvpath = diagtools.folder([cfg['plot_dir'], 'ensemble_counts_csv' ])
         csvpath += '_'.join(['ensemble_barchart_count'+str(threshold), land_carbon, ensemble_key]) + '.txt'
         out_txt = '# Count for thrshold: '+str(threshold)+'\n'
         out_txt += '# land_carbon:' + land_carbon+'\n'
         out_txt += '# ensemble_key:' + ensemble_key+'\n'
         #out_txt += 'Model, scenario, count,\n'
         counts = {}
         models = {}
         ssps = {}
         for i, unique_key in enumerate(unique_key_order):
 
             if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
             if t_threshold != threshold: continue
             (t_dataset, t_exp, t_ens, t_threshold) = unique_key
             models[t_dataset] = True
             ssps[t_exp] = True
             count_key = (t_dataset, t_exp)
             if counts.get(count_key, False):
                 counts[count_key]+=1
             else:
                 counts[count_key] = 1
         out_txt  = 'Model, ' + ', '.join(sorted(ssps.keys()))+'\n'
         for moded_csv in sorted(models.keys()):
            line1 = moded_csv+', '
            for exp_csv in sorted(ssps.keys()):
                if (moded_csv, exp_csv) in counts:
 
                    line1 += str(counts[(moded_csv, exp_csv)])+', '
                else:
                    line1 += '0, '
            out_txt += line1 +'\n'
        #for (t_dataset, t_exp) in sorted(counts.keys()):
        #     line1 = ','.join([t_dataset, t_exp, str(counts[(t_dataset, t_exp)])])
        #     out_txt  += line1 +',\n'
 
         csv_file = open(csvpath,'w')
         csv_file.write(out_txt)
         csv_file.close()
 
+    hline_land = {exp:[] for exp in exps}
+    hline_air = {exp:[] for exp in exps}
+    hline_ocean = {exp:[] for exp in exps}
+
 
     for i, unique_key in enumerate(unique_key_order):
     #for unique_key, remnant in sorted(remnants.items()):
         (t_dataset, t_exp, t_ens, t_threshold) = unique_key
 
         if ensemble_key == 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         #if 'CMIP6' in unique_key: continue
 
         if t_threshold != threshold: continue
         #if unique_key not in remnants: continue
 
         remnant = remnants[unique_key]
         landc = landcs[unique_key]
         oceanc = fgco2gts[unique_key]
         total = remnant + landc + oceanc
 
         adding_gaps = False
         dataset_blank = (i>0 and group_by == 'group_by_model' and t_dataset not in labels[-1])
         exp_blank =  (i>0 and group_by == 'group_by_ssp' and t_exp not in labels[-1])
 
         if adding_gaps and (dataset_blank or exp_blank):
             xvalues.append((xvalues[-1]+0.4))
             widths.append(1.)
             land.append(0.)
             ocean.append(0.)
             air.append(0.)
             emissions_bottoms.append(0.)
             labels.append([''.join(['.' for k in range(i)]), ])
 
 
 #        if i == 0:
 #            print(i, unique_key)
 #            assert 0
         # create bar label.
         #if ensemble_key == 'ensemble_mean':
         #    label_keys = [t_dataset, t_exp]
         #else:
         label_keys = [t_dataset, t_exp, t_ens]
  #       if 'CMIP6' in label_keys and 'SSP119' in t_exp and
 
         labels.append(label_keys)
 
         xvalues.append(i+0.5)
         widths.append(1.)
 
 #        if i == 0:
 #            xvalues.append(0.)
 #            widths.append(1.)
 #        else:
 #            xvalues.append(xvalues[-1]+1.)
 #            widths.append(1.)
 
         if plot_style == 'percentages':
             land.append(100. * landc/total)
             ocean.append(100. * oceanc/total)
             air.append(100. * remnant/total)
             emissions_bottoms.append(100* (landc +oceanc)/total)
+
         else:
             land.append(landc)
             ocean.append(oceanc)
             air.append(remnant)
             emissions_bottoms.append(landc+oceanc)
+
+
             if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
                 if landc+oceanc + remnant<600.:
                     print('ERROR:', label_keys, landc, oceanc, remnant, landc+oceanc + remnant )
                     quit = True
                     assert 0
 
+        hline_land[t_exp].append(land[-1])
+        hline_ocean[t_exp].append(emissions_bottoms[-1])
+        hline_air[t_exp].append(emissions_bottoms[-1]+air[-1])
+
+
         # Adds a blank line between models.
         #if t_dataset not in previous_dats:
         #    land.append(0.)
         #    ocean.append(0.)
         #    air.append(0.)
         #    emissions_bottoms.append(0.)
         #    experiments.append('')
         #previous_dats[t_dataset] = True
 
         #emissions_bottoms[unique_key]
     #totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
 
     # if atmos=='atmos_carbon':
     #     emissions_diff = remnant
     # else:
     #     emissions_diff = [e - f - b for e,f,b in zip(emissions, fgco2gts, landcs )]
     #emissions_diff = remnant
     # emissions_bottoms = [f + b for f,b in zip(fgco2gts, landcs )]
     # totals = [a + f + b for a,f,b in zip(remnant, fgco2gts, landcs)]
     #
     # for i, exp  in enumerate(experiments):
     #     print("Final values:",threshold, i, exp, totals[i], '=',emissions_diff[i],('or', remnant[i]), '+', landcs[i], '+', fgco2gts[i], '(a, l, o)')
     # Add bars:
     #if quit: assert 0
     #for x,w,l in zip(xvalues, widths, labels): print(x,w,l)
 
     label_strs = []
     linewidths = []
     edge_colours = []
     colours_land, colours_ocean, colours_air = [],[],[]
 
     ssp_land = {
         #'historical':'black',
         'SSP119': 'darkgreen',
         'SSP126': 'blue',
         'SSP245': 'saddlebrown',
         'SSP370': 'indigo',
         'SSP585': 'darkred',
         }
     ssp_ocean = {
         'SSP119': 'green',
         'SSP126': 'royalblue',
         'SSP245': 'darkorange',
         'SSP370': 'purple',
         'SSP585': 'red',
     }
     ssp_air = {
         'SSP119': 'lightgreen',
         'SSP126': 'dodgerblue',
         'SSP245': 'sandybrown',
         'SSP370': 'orchid',
         'SSP585': 'lightcoral',
     }
     full_alpha = (0.,0.,0.,0.)
+
     for i, lablist in enumerate(labels):
 
         if lablist[0][0] == '.':
             # empty bar
             label_strs.append(' ')
             linewidths.append(0.)
             edge_colours.append(full_alpha)
             colours_land.append('white')
             colours_ocean.append('white')
             colours_air.append('white')
             continue
 
         (t_dataset, t_exp, t_ens) = lablist
 
         colours_land.append(ssp_land[t_exp])
         colours_ocean.append(ssp_ocean[t_exp])
         colours_air.append(ssp_air[t_exp])
-
+        
         if t_dataset == 'CMIP6':
             edge_colours.append('k')
             linewidths.append(0.)
         else:
             edge_colours.append(full_alpha)
             linewidths.append(0.)
 
         if ensemble_key == 'ensemble_mean':
             if group_by == 'group_by_model':
                 label_strs.append(' '.join([t_dataset, t_exp]))
 
             if group_by == 'group_by_ssp':
                  if t_dataset == 'CMIP6':
                      label_strs.append('Multi-model mean')
                  else:
                      label_strs.append(' '.join([t_dataset, ]))
             if group_by == 'ecs':
                  ecs= str(round(ECS_data_ssp[t_exp][t_dataset],2))
                  if t_dataset == 'CMIP6':
                      label_strs.append(' '.join(['Multi-model mean', ])) # ecs
                  else:
                      label_strs.append(' '.join([t_dataset, ])) # ecs
 
         else:
             if group_by == 'group_by_model':
                if t_dataset  not in labels[i-1]:
                    label_strs.append(t_dataset)
                else: label_strs.append(' ')
             if group_by == 'group_by_ssp':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
             if group_by == 'ecs':
                if t_exp not in labels[i-1]:
                    label_strs.append(t_exp)
                else: label_strs.append(' ')
 
     #labels = [' '.join(label) for label in labels]
     if len(label_strs)== len(land) == len(widths) == len(xvalues) == len(colours_land): pass
     else:
         print('ERROR:',  len(labels),len(land),len(widths), len(xvalues), len(label_strs), len(colours_land))
         assert 0
 
 
     ax.bar(xvalues, land, width=widths, label='Land', color=colours_land, tick_label = label_strs, edgecolor=edge_colours, linewidth=linewidths)
     ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color=colours_ocean, edgecolor=edge_colours, linewidth=linewidths)
     ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color=colours_air, edgecolor=edge_colours, linewidth=linewidths)
 
+    draw_hlines = False
+    if draw_hlines:
+        for exp in exps:
+            ax.axhline(np.mean(hline_land[exp]), lw=1.2, color=ssp_land[exp])
+            ax.axhline(np.mean(hline_ocean[exp]), lw=1.2, color=ssp_ocean[exp])
+            ax.axhline(np.mean(hline_air[exp]), lw=1.2, color=ssp_air[exp])
+
+
     # ax.bar(xvalues, land, width=widths, label='Land', color='green', tick_label = label_strs)
     # ax.bar(xvalues, ocean, width=widths, bottom = land,  label='Ocean', color='dodgerblue')
     # ax.bar(xvalues, air, width=widths, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #ax.set_xlabel('Scenarios')
     plt.xticks(rotation=90, fontsize='xx-small')
     plt.xlim([-0.1, np.sum(widths)+0.1])
 
     # # Add bars:
     # horizontal = False
     # if horizontal:
     #     ax.barh(experiments, land, label='Land', color='mediumseagreen')
     #     ax.barh(experiments, ocean, left = land,  label='Ocean', color='dodgerblue')
     #     ax.barh(experiments, air, left = emissions_bottoms,  label='Atmos', color='silver')
     #     #ax.set_ylabel('Scenarios')
     #     #lt.xticks(rotation=90)
     # else:
     #     ax.bar(experiments, land, width=1.0, label='Land', color='green')
     #     ax.bar(experiments, ocean, width=1.0, bottom = land,  label='Ocean', color='dodgerblue')
     #     ax.bar(experiments, air, width=1.0, bottom = emissions_bottoms,  label='Atmos', color='grey')
     #     #ax.set_xlabel('Scenarios')
     #     plt.xticks(rotation=90)
     # Add percentages:
     # add_pc_text = True
     # if add_pc_text:
     #     def pc(a,b): return str("{0:.1f}%".format(100.*a/b))
     #     for e, exp in enumerate(experiments):
     #         print(e, exp, landcs[e], fgco2gts[e], emissions_diff[e])
     #         t = totals[e]
     #         ax.text(landcs[e]/2, e, pc(landcs[e], t),
     #                 color='#002200', #'darkgreen',
     #                 fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
     #
     #         ax.text(landcs[e]+fgco2gts[e]/2., e, pc(fgco2gts[e], t),
     #                 color='darkblue', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
     #
     #         ax.text(emissions_bottoms[e]+emissions_diff[e]/2., e, pc(emissions_diff[e],t ),
     #                 color='black', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
 
     # Add mean year:
     # add_mean_year = False
     # if add_mean_year:
     #     for e, exp in enumerate(experiments):
     #         t = totals[e]
     #         yr = threshold_years[e]
     #         ax.text(t *1.05, e, str(int(yr)),
     #                 color='black', fontsize=8 , # fontweight='bold',
     #                 verticalalignment='center',horizontalalignment='center')
 
     if float(threshold) > 1850.:
         ax.set_title(str(threshold))
     else:
         ax.set_title(str(threshold)+r'$\degree$'+' warming')
 
     if plot_style == 'percentages':
         ax.set_ylim([0., 100.,])
         ax.set_ylabel('Fractional Carbon Allocation, %')
     else:
         ax.set_ylabel('Total Carbon Allocation, Pg')
 
 
     if do_legend:
         ax.legend()
 
     if make_figure_here:
         image_extention = diagtools.get_image_format(cfg)
         path = diagtools.folder([cfg['plot_dir'], 'single_barcharts' ])
         path += '_'.join(['ensemble_barchart'+str(threshold), land_carbon, atmos, group_by]) + image_extention
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 
commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -2670,439 +2675,439 @@
 def make_ts_figure(cfg, data_dict, thresholds_dict, x='time', y='npp',
     markers='thresholds',
     draw_line=True,
     do_moving_average=False,
     plot_dataset='all_models',
     ensemble_mean = False, # does nothing now.
     plot_styles = ['ensemble_mean', ], #['CMIP6_range', 'CMIP6_mean'],
     fig=None,
     ax=None,
     do_legend=True,
-    plot_thresholds = [1.5, 2., 3., 4., 5.,],
+    plot_thresholds = [1., 1.5, 2., 3., 4., 5.,],
     skip_historical_ssp=False,
     experiments = ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
     #short_time_range = False,
     ):
     """
     make a 2D figure.
     x axis and y axis are determined by the short_names provuided in x and y
     vars.
     Markers are placed at certain points when the tas goes above thresholds.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
     plot_dataset:
         either 'all_models'
         or an individual model name.
     plot_styles: ambition:
         ['ensemble_mean', ] default behaviour before
         CMIP6_mean: Only CMIP6 multi model mean
         CMIP6_range: range bewteen each model mean shown
         CMIP6_full_range: full range between individual model ensemble menmbers
         all_models_means: Each individual models mean is plotted.
         all_models_range: Each individual models range is plotted
     """
     exps = {}
     ensembles = {}
     datasets = {}
     for (dataset, short_name, exp, ensemble)  in data_dict.keys():
          if not exp in experiments: continue
          exps[exp] = True
          ensembles[ensemble] = True
          datasets[dataset] = True
          print(dataset, short_name, exp, ensemble)
 
     if plot_dataset != 'all_models':
         if isinstance(plot_dataset, str):
             datasets = {plot_dataset:True}
         else:
             datasets = {pd:True for pd in plot_dataset}
             plot_dataset = '_'.join(plot_dataset)
 
     # set path:
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'ts_figure',plot_dataset])
     print(path, plot_styles)
     ensemble_mean_txt = '_'.join(plot_styles)
     path += '_'.join([x, y, markers, ensemble_mean_txt, plot_dataset]) + image_extention
 
     if do_moving_average:
         path = path.replace(image_extention, '_21ma'+image_extention)
     #if os.path.exists(path): return
 
 #    exp_colours = {'historical':'black',
 #                   'ssp119':'green',
 #                   'ssp126':'dodgerblue',
 #                   'ssp245':'blue',
 #                   'ssp370':'purple',
 #                   'ssp434':'magenta',
 #                   'ssp585': 'red',
 #                   'ssp534-over':'orange',
 #                   'historical-ssp119':'green',
 #                   'historical-ssp126':'dodgerblue',
 #                   'historical-ssp245':'blue',
 #                   'historical-ssp370':'purple',
 #                   'historical-ssp434':'magenta',
 #                   'historical-ssp585': 'red',
 #                   'historical-ssp585-ssp534-over':'orange'}
 
-    marker_styles = {1.5: '*', 2.:'o', 3.:'D', 4.:'s', 5.:'X'}
+    #threshold_marker_styles = {1.5: '*', 2.:'o', 3.:'D', 4.:'s', 5.:'X'}
 
     if plot_styles == ['ensemble_mean', ]:
         ensembles = ['ensemble_mean', ]
 
     exps = sorted(exps.keys())
     exps.reverse()
     print(exps, ensembles)
     print(data_dict.keys())
 
     if fig == None:
         fig = plt.figure()
         ax = fig.add_subplot(111)
         make_figure_here = True
     else:
         make_figure_here = False
         plt.sca(ax)
 
     x_label,y_label = [], []
     print('\n\n\n\n\nStaring plot:',
         'x:', x,
         'y:', y,
         'markers:', markers,
         'draw_line:', draw_line,
         'do_moving_average:', do_moving_average,
         'plot_styles:', plot_styles)
 
     number_of_lines=0
 
     label_dicts = {
 #        'tas': ' '.join(['Temperature, K',]), # ''.join([r'$\degree$', 'C'])]),
 #        'tas_norm': ' '.join(['Normalised Temperature,', ''.join([r'$\degree$', 'C'])]),
         'co2': ' '.join(['Atmospheric co2, ppm']),
         # 'emissions': ' '.join(['Anthropogenic emissions, Pg/yr']),
         # 'cumul_emissions': ' '.join(['Cumulative Anthropogenic emissions, Pg']),
         'luegt': ' '.join(['Land use emissions, Pg']),
         'tls': 'S'+r'$_{Land}$',
         'atmos_carbon': 'Anthropogenic CO'+r'$_{2}$'+', Pg',
     }
 
     for exp_1, ensemble_1,dataset_1, plot_style in product(exps, ensembles, datasets, plot_styles):
         x_data, y_data = [], []
         x_times, y_times = [], []
 
             #plot_styles: ambition:
             #    ['ensemble_mean', ] default behaviour before
             #    CMIP6_mean: Only CMIP6 multi model mean
             #    CMIP6_range: range bewteen each model mean shown
             #    CMIP6_full_range: full range between individual model ensemble menmbers
             #    all_models_means: Each individual models mean is plotted.
             #    all_models_range: Each individual models range is plotted
             #    all_ensembles: Every single ensemble member is shown.
 
         if plot_style == 'all_ensembles':
             if ensemble_1 in ['ensemble_mean', 'ensemble_min', 'ensemble_max']: continue
             if dataset_1 == 'CMIP6': continue
             #print(plot_style, exp_1, ensemble_1,dataset_1, plot_style)
             #assert 0
 
         if plot_style == 'all_models_means':
             if ensemble_1 != 'ensemble_mean': continue
             if dataset_1 == 'CMIP6': continue
 
         if plot_style == 'CMIP6_mean':
             if ensemble_1 != 'ensemble_mean': continue
             if dataset_1 != 'CMIP6': continue
 
         if skip_historical_ssp:
             if exp_1.find('historical-')>-1: continue
             if exp_1.find('historical_')>-1: continue
 
         if plot_style in ['CMIP6_range', 'all_models_range', ]:
             if plot_style in ['CMIP6_range', ] and dataset_1 != 'CMIP6': continue
             if plot_style in ['all_models_range', ] and dataset_1 == 'CMIP6': continue
             # just so it only gets plotted once.
             if ensemble_1 != 'ensemble_min': continue
 
             if x != 'time':
                print('plotting a range with time on the x axes is not possible.')
                assert 0
 
             if (dataset_1, y, exp_1, 'ensemble_min') not in data_dict.keys(): continue
             mins_data = data_dict[(dataset_1, y, exp_1, 'ensemble_min')]
             maxs_data = data_dict[(dataset_1, y, exp_1, 'ensemble_max')]
             x_label = 'Year'
             if isinstance(mins_data, iris.cube.Cube):
                 x_times = diagtools.cube_time_to_float(mins_data)
                 y_data_mins = np.array(mins_data.data.copy())
                 y_data_maxs = np.array(maxs_data.data.copy())
             else:
                 x_times = mins_data['time']
                 y_data_mins = mins_data[y].copy()
                 y_data_maxs = maxs_data[y].copy()
 
             x_times = np.array(x_times)
             if exp_1 in ['historical', ]:
                 x_times = np.ma.masked_where(x_times>2015., x_times)
             else:
                 x_times = np.ma.masked_where(x_times<2015., x_times)
 
             y_data_mins = np.ma.masked_where(x_times.mask, y_data_mins)
             y_data_maxs = np.ma.masked_where(x_times.mask, y_data_maxs)
 
 
 
             if y in label_dicts.keys():
                 y_label = label_dicts[y]
             else:
                 y_label = ' '.join([get_long_name(y) ])#, get_long_name(str(mins_data.units))])
 
             if np.array_equal(y_data_mins, y_data_maxs) or np.abs(np.mean(y_data_mins - y_data_maxs)/np.mean(y_data_maxs)) < 1e-6:
                 plt.plot(x_times, y_data_mins, c=exp_colours[exp_1], alpha=0.4, lw=2.5)
             else:
                 plt.fill_between(x_times, y_data_mins, y_data_maxs, fc = exp_colours_fill[exp_1], alpha=exp_colours_alpha[exp_1])
                 plt.plot(x_times, y_data_mins, c=exp_colours[exp_1], lw=0.4)
                 plt.plot(x_times, y_data_maxs, c=exp_colours[exp_1], lw=0.4)
             continue
 
         for (dataset, short_name, exp, ensemble), cube in data_dict.items():
             if short_name not in [x,y]: continue
             if exp != exp_1: continue
             if ensemble != ensemble_1: continue
             if dataset != dataset_1: continue
 
             print('Everything matches', plot_style, (dataset, short_name, exp, ensemble),'vs', [x,y], (exp_1, ensemble_1))
             print('make_ts_figure: found', plot_style, dataset, short_name, exp, ensemble, x,y)
             if x == 'time' and short_name == y:
                 x_label = 'Year'
                 if isinstance(cube, iris.cube.Cube):
                     x_data = diagtools.cube_time_to_float(cube)
                     x_times = x_data.copy()
                     print('setting x time to ',short_name, exp, ensemble)
                 else:
                     x_data = cube['time']
                     x_times = x_data.copy()
                     print('setting x time to ',short_name, exp, ensemble)
             elif x == short_name and x in label_dicts.keys():
                 x_data = cube[x].copy()
                 x_times = cube['time'].copy()
                 print('setting x time to ',short_name, exp, ensemble)
                 x_label = label_dicts[x]
 
             elif short_name == x:
                 x_data = np.array(cube.data.copy())
                 x_times = diagtools.cube_time_to_float(cube)
                 print('setting x axis to ',short_name, exp, ensemble, np.min(x_data), np.max(x_data))
                 x_label = ' '.join([get_long_name(x), ] ) # get_long_name(str(cube.units))])
 
             if y == 'time':
                 print('what kind of crazy person plots time on y axis?')
                 assert 0
             elif y == short_name and y in label_dicts.keys():
                 #['co2', 'emissions', 'cumul_emissions', 'luegt']:
                 y_data = cube[y].copy()
                 y_times = cube['time'].copy()
                 y_label = label_dicts[y]
                 print('setting y time to ',short_name, exp, ensemble)
             elif short_name == y:
                 print(short_name, 'is a cube for y ts plot..')
                 y_data = cube.data.copy()
                 y_times = diagtools.cube_time_to_float(cube)
                 print('setting y time to ',short_name, exp, ensemble, y_data)
                 y_label = ' '.join([get_long_name(y), ] ) # get_long_name(str(cube.units))])
 
             print('make_ts_figure: loaded x data', short_name, exp, ensemble, x, np.mean(x_data))
             print('make_ts_figure: loaded y data', short_name, exp, ensemble, y, np.mean(y_data))
 
         if 0 in [len(x_data), len(y_data), len(x_times), len(y_times)]:
             print('no data found',(exp_1, ensemble_1,dataset_1),  x,'vs',y, 'x:', len(x_data), 'y:',len(y_data))
             continue
 
         if len(x_data) != len(x_times) or len(y_data) != len(y_times):
             print('x:', len(x_data), len(x_times), 'y:', len(y_data), len(y_times))
             assert 0
 
         label = ' '.join([exp_1, ]) #ensemble_1])
         # masks fromn the year 2005 of hist data, so that they can line up properly.
 
         hist_ssp_sync = False #
         if draw_line:
             x_times = np.ma.array(x_times)
             y_times = np.ma.array(y_times)
             number_of_lines+=1
 
             #plot_styles: ambition:
             #    ['ensemble_mean', ] default behaviour before
             #    CMIP6_mean: Only CMIP6 multi model mean
             #    CMIP6_range: range bewteen each model mean shown
             #    CMIP6_full_range: full range between individual model ensemble menmbers
             #    all_models_means: Each individual models mean is plotted.
             #    all_models_range: Each individual models range is plotted
             #    all_ensembles: Every single ensemble member is shown.
 
             if plot_styles == ['ensemble_mean', ]:
                 lw = 1.3
             elif plot_style=='CMIP6_mean':
                 lw = 1.7
             elif plot_style=='all_models_means':
                 lw = 1.0
             else:
                 lw = 0.5
 
 
             if exp_1 in ['historical', ]:
                 x_times = np.ma.masked_where(x_times>2015., x_times)
                 y_times = np.ma.masked_where(y_times>2015., y_times)
             else:
                 x_times = np.ma.masked_where(x_times<2015., x_times)
                 y_times = np.ma.masked_where(y_times<2015., y_times)
 
             x_data = np.ma.masked_where(x_times.mask, x_data)
             y_data = np.ma.masked_where(y_times.mask, y_data)
             plt.plot(x_data, y_data,
                      lw=lw,
                      color=exp_colours[exp_1])
 
 
 #                if hist_ssp_sync:
 #                    histx_t = np.ma.masked_where(x_times > 2005., x_times)
 #                    histy_t = np.ma.masked_where(y_times > 2005., y_times)
 #                    histx_d = np.ma.masked_where(histx_t.mask, x_data).compressed()
 #                    histy_d = np.ma.masked_where(histy_t.mask, y_data).compressed()
 #             plt.plot(histx_d, histy_d,
 #                      lw=lw,
 #                     color=exp_colours[exp_1])
 #
 #                else:
 #             plt.plot(x_data, y_data,
 #                        lw=lw,
 #                        color=exp_colours[exp_1])
 #
 #            else:
 #                if hist_ssp_sync:
 #                    tdatcx = np.ma.masked_where((2004. > x_times) + (x_times > 2015.), x_times).compressed()
 #                    tdatcy = np.ma.masked_where((2004. > y_times) + (y_times > 2015.), y_times).compressed()
 #                    datcx = np.ma.masked_where((2004. > x_times) + (x_times > 2015.), x_data).compressed()
 #                    datcy = np.ma.masked_where((2004. > y_times) + (y_times > 2015.), y_data).compressed()
 #                    if len(tdatcx) == len(tdatcy):
 #                        plt.plot(
 #                            datcx, # np.ma.masked_where((2004 > x_times) + (x_times > 2015), x_data).compressed(),
 #                            datcy, # np.ma.masked_where((2004 > y_times) + (y_times > 2015), y_data).compressed(),
 #                            lw=lw,
 #                            color=exp_colours['historical'])
 #
 #                    xdatc = np.ma.masked_where((x_times < 2015.) + (x_times > 2100.), x_data).compressed()
 #                    ydatc = np.ma.masked_where((y_times < 2015.) + (y_times > 2100. ), y_data).compressed()
 #                    xtdatc = np.ma.masked_where((x_times < 2015.) + (x_times > 2100.), x_times).compressed()
 #                    ytdatc = np.ma.masked_where((y_times < 2015.) + (y_times > 2100. ), y_times).compressed()
 #
 #                    if len(xtdatc) == len(ytdatc):
 #                        plt.plot(xdatc, # np.ma.masked_where(x_times < 2015., x_data).compressed(),
 #                             ydatc, # np.ma.masked_where(y_times < 2015., y_data).compressed(),
 #                             lw=lw,
 #                             color=exp_colours[exp_1])
 #                else:
 #                    if len(x_data) != len(y_data):
 #                        print('WARNING: x!=y:', len(x_data), '!=', len(y_data), 'x:', x, 'y:',y)
 #                        print(x, 'x_times:', x_times)
 #                        print(y, 'y_times:', y_times)
 #
 #                    plt.plot(x_data,
 #                         y_data,
 #                         lw=lw,
 #                         color=exp_colours[exp_1])
 
         # plot_style == ''
 
         if markers == 'thresholds':
             try: threshold_times = thresholds_dict[(dataset_1, 'tas', exp_1, ensemble_1)]
             except:
                threshold_times = {}
             ms = 6
             for threshold, time in threshold_times.items():
                 if not time:
                     continue
                 if threshold not in plot_thresholds:
                     continue
                 x_point = get_threshold_point({'time':x_times}, time.year)
                 #_point = get_threshold_point(cube, time.year)
                 y_point = get_threshold_point({'time':y_times}, time.year)
 
                 print('thresholds:', dataset_1, exp_1, ensemble_1,x,y, threshold, time, x_point, y_point, len(x_data),len(y_data))
                 #assert 0
                 plt.plot(x_data[x_point],
                          y_data[y_point],
-                         marker_styles[threshold],
+                         threshold_marker_styles[threshold],
                          markersize = ms,
                          fillstyle='full',
                          zorder=10,
                          color=to_rgba(exp_colours[exp_1], alpha=0.5),
                          markeredgecolor=exp_colours_dark[exp_1]
                           )
                 #plt.plot(x_data[x_point],
                 #         y_data[y_point],
                 #         'o',
                 #         markersize = 2,
                 #         #fillstyle='none',
                 #         color=exp_colours[exp_1])
 
 #      if plot_style == '' ## fills:
 
 
 
     if not number_of_lines:
         print('No lines plotted')
         plt.close()
         return fig, ax
         #assert 0
 
     if do_legend:
         exp_colours_leg = {'historical':'black',
                        'ssp119':'green',
                        'ssp126':'dodgerblue',
                        'ssp245':'blue',
                        'ssp370':'purple',
                        'ssp434':'magenta',
                        'ssp585': 'red',
                        'ssp534-over':'orange'}
         plot_details = {}
         for exp,color in sorted(exp_colours_leg.items()):
             plot_details[exp] = {
                         'c': color,
                         'ls': '-',
                         'lw': 2.,
                         'label': exp
                     }
-        for thres,ms in sorted(marker_styles.items()):
+        for thres,ms in sorted(threshold_marker_styles.items()):
             plot_details[str(thres)] = {
                         'c': 'black',
                         'marker': ms,
                         'fillstyle':'none',
                         'label': '>' + str(thres)+u'\u00B0C'
                     }
         diagtools.add_legend_outside_right(
                 plot_details, plt.gca(), column_width=0.175)
 
     # set labels:
     plt.xlabel(x_label)
     plt.ylabel(y_label)
 
     # set title:
     if x == 'time':
         title = '' #get_long_name(y)
     else:
         title = ' '.join([get_long_name(x), 'by', get_long_name(y)])
 
     if make_figure_here and plot_dataset != 'all_models':
         title += ' '+plot_dataset
 
     plt.title(title)
 
     if make_figure_here:
         print('saving figure:', path)
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -2623,439 +2666,439 @@
 def make_ts_figure(cfg, data_dict, thresholds_dict, x='time', y='npp',
     markers='thresholds',
     draw_line=True,
     do_moving_average=False,
     plot_dataset='all_models',
     ensemble_mean = False, # does nothing now.
     plot_styles = ['ensemble_mean', ], #['CMIP6_range', 'CMIP6_mean'],
     fig=None,
     ax=None,
     do_legend=True,
     plot_thresholds = [1.5, 2., 3., 4., 5.,],
     skip_historical_ssp=False,
     experiments = ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
     #short_time_range = False,
     ):
     """
     make a 2D figure.
     x axis and y axis are determined by the short_names provuided in x and y
     vars.
     Markers are placed at certain points when the tas goes above thresholds.
 
     Parameters
     ----------
     cfg: dict
         the opened global config dictionairy, passed by ESMValTool.
     plot_dataset:
         either 'all_models'
         or an individual model name.
     plot_styles: ambition:
         ['ensemble_mean', ] default behaviour before
         CMIP6_mean: Only CMIP6 multi model mean
         CMIP6_range: range bewteen each model mean shown
         CMIP6_full_range: full range between individual model ensemble menmbers
         all_models_means: Each individual models mean is plotted.
         all_models_range: Each individual models range is plotted
     """
     exps = {}
     ensembles = {}
     datasets = {}
     for (dataset, short_name, exp, ensemble)  in data_dict.keys():
          if not exp in experiments: continue
          exps[exp] = True
          ensembles[ensemble] = True
          datasets[dataset] = True
          print(dataset, short_name, exp, ensemble)
 
     if plot_dataset != 'all_models':
         if isinstance(plot_dataset, str):
             datasets = {plot_dataset:True}
         else:
             datasets = {pd:True for pd in plot_dataset}
             plot_dataset = '_'.join(plot_dataset)
 
     # set path:
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'ts_figure',plot_dataset])
     print(path, plot_styles)
     ensemble_mean_txt = '_'.join(plot_styles)
     path += '_'.join([x, y, markers, ensemble_mean_txt, plot_dataset]) + image_extention
 
     if do_moving_average:
         path = path.replace(image_extention, '_21ma'+image_extention)
     #if os.path.exists(path): return
 
 #    exp_colours = {'historical':'black',
 #                   'ssp119':'green',
 #                   'ssp126':'dodgerblue',
 #                   'ssp245':'blue',
 #                   'ssp370':'purple',
 #                   'ssp434':'magenta',
 #                   'ssp585': 'red',
 #                   'ssp534-over':'orange',
 #                   'historical-ssp119':'green',
 #                   'historical-ssp126':'dodgerblue',
 #                   'historical-ssp245':'blue',
 #                   'historical-ssp370':'purple',
 #                   'historical-ssp434':'magenta',
 #                   'historical-ssp585': 'red',
 #                   'historical-ssp585-ssp534-over':'orange'}
 
     marker_styles = {1.5: '*', 2.:'o', 3.:'D', 4.:'s', 5.:'X'}
 
     if plot_styles == ['ensemble_mean', ]:
         ensembles = ['ensemble_mean', ]
 
     exps = sorted(exps.keys())
     exps.reverse()
     print(exps, ensembles)
     print(data_dict.keys())
 
     if fig == None:
         fig = plt.figure()
         ax = fig.add_subplot(111)
         make_figure_here = True
     else:
         make_figure_here = False
         plt.sca(ax)
 
     x_label,y_label = [], []
     print('\n\n\n\n\nStaring plot:',
         'x:', x,
         'y:', y,
         'markers:', markers,
         'draw_line:', draw_line,
         'do_moving_average:', do_moving_average,
         'plot_styles:', plot_styles)
 
     number_of_lines=0
 
     label_dicts = {
 #        'tas': ' '.join(['Temperature, K',]), # ''.join([r'$\degree$', 'C'])]),
 #        'tas_norm': ' '.join(['Normalised Temperature,', ''.join([r'$\degree$', 'C'])]),
         'co2': ' '.join(['Atmospheric co2, ppm']),
         # 'emissions': ' '.join(['Anthropogenic emissions, Pg/yr']),
         # 'cumul_emissions': ' '.join(['Cumulative Anthropogenic emissions, Pg']),
         'luegt': ' '.join(['Land use emissions, Pg']),
-        'tls': ' '.join(['True Land Sink, Pg']),
-        'atmos_carbon': 'Remnant Anthropogenic CO2, Pg',
+        'tls': 'S'+r'$_{Land}$',
+        'atmos_carbon': 'Anthropogenic CO'+r'$_{2}$'+', Pg',
     }
 
     for exp_1, ensemble_1,dataset_1, plot_style in product(exps, ensembles, datasets, plot_styles):
         x_data, y_data = [], []
         x_times, y_times = [], []
 
             #plot_styles: ambition:
             #    ['ensemble_mean', ] default behaviour before
             #    CMIP6_mean: Only CMIP6 multi model mean
             #    CMIP6_range: range bewteen each model mean shown
             #    CMIP6_full_range: full range between individual model ensemble menmbers
             #    all_models_means: Each individual models mean is plotted.
             #    all_models_range: Each individual models range is plotted
             #    all_ensembles: Every single ensemble member is shown.
 
         if plot_style == 'all_ensembles':
             if ensemble_1 in ['ensemble_mean', 'ensemble_min', 'ensemble_max']: continue
             if dataset_1 == 'CMIP6': continue
             #print(plot_style, exp_1, ensemble_1,dataset_1, plot_style)
             #assert 0
 
         if plot_style == 'all_models_means':
             if ensemble_1 != 'ensemble_mean': continue
             if dataset_1 == 'CMIP6': continue
 
         if plot_style == 'CMIP6_mean':
             if ensemble_1 != 'ensemble_mean': continue
             if dataset_1 != 'CMIP6': continue
 
         if skip_historical_ssp:
             if exp_1.find('historical-')>-1: continue
             if exp_1.find('historical_')>-1: continue
 
         if plot_style in ['CMIP6_range', 'all_models_range', ]:
             if plot_style in ['CMIP6_range', ] and dataset_1 != 'CMIP6': continue
             if plot_style in ['all_models_range', ] and dataset_1 == 'CMIP6': continue
             # just so it only gets plotted once.
             if ensemble_1 != 'ensemble_min': continue
 
             if x != 'time':
                print('plotting a range with time on the x axes is not possible.')
                assert 0
 
             if (dataset_1, y, exp_1, 'ensemble_min') not in data_dict.keys(): continue
             mins_data = data_dict[(dataset_1, y, exp_1, 'ensemble_min')]
             maxs_data = data_dict[(dataset_1, y, exp_1, 'ensemble_max')]
             x_label = 'Year'
             if isinstance(mins_data, iris.cube.Cube):
                 x_times = diagtools.cube_time_to_float(mins_data)
                 y_data_mins = np.array(mins_data.data.copy())
                 y_data_maxs = np.array(maxs_data.data.copy())
             else:
                 x_times = mins_data['time']
                 y_data_mins = mins_data[y].copy()
                 y_data_maxs = maxs_data[y].copy()
 
             x_times = np.array(x_times)
             if exp_1 in ['historical', ]:
                 x_times = np.ma.masked_where(x_times>2015., x_times)
             else:
                 x_times = np.ma.masked_where(x_times<2015., x_times)
 
             y_data_mins = np.ma.masked_where(x_times.mask, y_data_mins)
             y_data_maxs = np.ma.masked_where(x_times.mask, y_data_maxs)
 
 
 
             if y in label_dicts.keys():
                 y_label = label_dicts[y]
             else:
                 y_label = ' '.join([get_long_name(y) ])#, get_long_name(str(mins_data.units))])
 
             if np.array_equal(y_data_mins, y_data_maxs) or np.abs(np.mean(y_data_mins - y_data_maxs)/np.mean(y_data_maxs)) < 1e-6:
                 plt.plot(x_times, y_data_mins, c=exp_colours[exp_1], alpha=0.4, lw=2.5)
             else:
                 plt.fill_between(x_times, y_data_mins, y_data_maxs, fc = exp_colours_fill[exp_1], alpha=exp_colours_alpha[exp_1])
                 plt.plot(x_times, y_data_mins, c=exp_colours[exp_1], lw=0.4)
                 plt.plot(x_times, y_data_maxs, c=exp_colours[exp_1], lw=0.4)
             continue
 
         for (dataset, short_name, exp, ensemble), cube in data_dict.items():
             if short_name not in [x,y]: continue
             if exp != exp_1: continue
             if ensemble != ensemble_1: continue
             if dataset != dataset_1: continue
 
             print('Everything matches', plot_style, (dataset, short_name, exp, ensemble),'vs', [x,y], (exp_1, ensemble_1))
             print('make_ts_figure: found', plot_style, dataset, short_name, exp, ensemble, x,y)
             if x == 'time' and short_name == y:
                 x_label = 'Year'
                 if isinstance(cube, iris.cube.Cube):
                     x_data = diagtools.cube_time_to_float(cube)
                     x_times = x_data.copy()
                     print('setting x time to ',short_name, exp, ensemble)
                 else:
                     x_data = cube['time']
                     x_times = x_data.copy()
                     print('setting x time to ',short_name, exp, ensemble)
             elif x == short_name and x in label_dicts.keys():
                 x_data = cube[x].copy()
                 x_times = cube['time'].copy()
                 print('setting x time to ',short_name, exp, ensemble)
                 x_label = label_dicts[x]
 
             elif short_name == x:
                 x_data = np.array(cube.data.copy())
                 x_times = diagtools.cube_time_to_float(cube)
                 print('setting x axis to ',short_name, exp, ensemble, np.min(x_data), np.max(x_data))
                 x_label = ' '.join([get_long_name(x), ] ) # get_long_name(str(cube.units))])
 
             if y == 'time':
                 print('what kind of crazy person plots time on y axis?')
                 assert 0
             elif y == short_name and y in label_dicts.keys():
                 #['co2', 'emissions', 'cumul_emissions', 'luegt']:
                 y_data = cube[y].copy()
                 y_times = cube['time'].copy()
                 y_label = label_dicts[y]
                 print('setting y time to ',short_name, exp, ensemble)
             elif short_name == y:
                 print(short_name, 'is a cube for y ts plot..')
                 y_data = cube.data.copy()
                 y_times = diagtools.cube_time_to_float(cube)
                 print('setting y time to ',short_name, exp, ensemble, y_data)
                 y_label = ' '.join([get_long_name(y), ] ) # get_long_name(str(cube.units))])
 
             print('make_ts_figure: loaded x data', short_name, exp, ensemble, x, np.mean(x_data))
             print('make_ts_figure: loaded y data', short_name, exp, ensemble, y, np.mean(y_data))
 
         if 0 in [len(x_data), len(y_data), len(x_times), len(y_times)]:
             print('no data found',(exp_1, ensemble_1,dataset_1),  x,'vs',y, 'x:', len(x_data), 'y:',len(y_data))
             continue
 
         if len(x_data) != len(x_times) or len(y_data) != len(y_times):
             print('x:', len(x_data), len(x_times), 'y:', len(y_data), len(y_times))
             assert 0
 
         label = ' '.join([exp_1, ]) #ensemble_1])
         # masks fromn the year 2005 of hist data, so that they can line up properly.
 
         hist_ssp_sync = False #
         if draw_line:
             x_times = np.ma.array(x_times)
             y_times = np.ma.array(y_times)
             number_of_lines+=1
 
             #plot_styles: ambition:
             #    ['ensemble_mean', ] default behaviour before
             #    CMIP6_mean: Only CMIP6 multi model mean
             #    CMIP6_range: range bewteen each model mean shown
             #    CMIP6_full_range: full range between individual model ensemble menmbers
             #    all_models_means: Each individual models mean is plotted.
             #    all_models_range: Each individual models range is plotted
             #    all_ensembles: Every single ensemble member is shown.
 
             if plot_styles == ['ensemble_mean', ]:
                 lw = 1.3
             elif plot_style=='CMIP6_mean':
                 lw = 1.7
             elif plot_style=='all_models_means':
                 lw = 1.0
             else:
                 lw = 0.5
 
 
             if exp_1 in ['historical', ]:
                 x_times = np.ma.masked_where(x_times>2015., x_times)
                 y_times = np.ma.masked_where(y_times>2015., y_times)
             else:
                 x_times = np.ma.masked_where(x_times<2015., x_times)
                 y_times = np.ma.masked_where(y_times<2015., y_times)
 
             x_data = np.ma.masked_where(x_times.mask, x_data)
             y_data = np.ma.masked_where(y_times.mask, y_data)
             plt.plot(x_data, y_data,
                      lw=lw,
                      color=exp_colours[exp_1])
 
 
 #                if hist_ssp_sync:
 #                    histx_t = np.ma.masked_where(x_times > 2005., x_times)
 #                    histy_t = np.ma.masked_where(y_times > 2005., y_times)
 #                    histx_d = np.ma.masked_where(histx_t.mask, x_data).compressed()
 #                    histy_d = np.ma.masked_where(histy_t.mask, y_data).compressed()
 #             plt.plot(histx_d, histy_d,
 #                      lw=lw,
 #                     color=exp_colours[exp_1])
 #
 #                else:
 #             plt.plot(x_data, y_data,
 #                        lw=lw,
 #                        color=exp_colours[exp_1])
 #
 #            else:
 #                if hist_ssp_sync:
 #                    tdatcx = np.ma.masked_where((2004. > x_times) + (x_times > 2015.), x_times).compressed()
 #                    tdatcy = np.ma.masked_where((2004. > y_times) + (y_times > 2015.), y_times).compressed()
 #                    datcx = np.ma.masked_where((2004. > x_times) + (x_times > 2015.), x_data).compressed()
 #                    datcy = np.ma.masked_where((2004. > y_times) + (y_times > 2015.), y_data).compressed()
 #                    if len(tdatcx) == len(tdatcy):
 #                        plt.plot(
 #                            datcx, # np.ma.masked_where((2004 > x_times) + (x_times > 2015), x_data).compressed(),
 #                            datcy, # np.ma.masked_where((2004 > y_times) + (y_times > 2015), y_data).compressed(),
 #                            lw=lw,
 #                            color=exp_colours['historical'])
 #
 #                    xdatc = np.ma.masked_where((x_times < 2015.) + (x_times > 2100.), x_data).compressed()
 #                    ydatc = np.ma.masked_where((y_times < 2015.) + (y_times > 2100. ), y_data).compressed()
 #                    xtdatc = np.ma.masked_where((x_times < 2015.) + (x_times > 2100.), x_times).compressed()
 #                    ytdatc = np.ma.masked_where((y_times < 2015.) + (y_times > 2100. ), y_times).compressed()
 #
 #                    if len(xtdatc) == len(ytdatc):
 #                        plt.plot(xdatc, # np.ma.masked_where(x_times < 2015., x_data).compressed(),
 #                             ydatc, # np.ma.masked_where(y_times < 2015., y_data).compressed(),
 #                             lw=lw,
 #                             color=exp_colours[exp_1])
 #                else:
 #                    if len(x_data) != len(y_data):
 #                        print('WARNING: x!=y:', len(x_data), '!=', len(y_data), 'x:', x, 'y:',y)
 #                        print(x, 'x_times:', x_times)
 #                        print(y, 'y_times:', y_times)
 #
 #                    plt.plot(x_data,
 #                         y_data,
 #                         lw=lw,
 #                         color=exp_colours[exp_1])
 
         # plot_style == ''
 
         if markers == 'thresholds':
             try: threshold_times = thresholds_dict[(dataset_1, 'tas', exp_1, ensemble_1)]
             except:
                threshold_times = {}
             ms = 6
             for threshold, time in threshold_times.items():
                 if not time:
                     continue
                 if threshold not in plot_thresholds:
                     continue
                 x_point = get_threshold_point({'time':x_times}, time.year)
                 #_point = get_threshold_point(cube, time.year)
                 y_point = get_threshold_point({'time':y_times}, time.year)
 
                 print('thresholds:', dataset_1, exp_1, ensemble_1,x,y, threshold, time, x_point, y_point, len(x_data),len(y_data))
                 #assert 0
                 plt.plot(x_data[x_point],
                          y_data[y_point],
                          marker_styles[threshold],
                          markersize = ms,
                          fillstyle='full',
                          zorder=10,
                          color=to_rgba(exp_colours[exp_1], alpha=0.5),
                          markeredgecolor=exp_colours_dark[exp_1]
                           )
                 #plt.plot(x_data[x_point],
                 #         y_data[y_point],
                 #         'o',
                 #         markersize = 2,
                 #         #fillstyle='none',
                 #         color=exp_colours[exp_1])
 
 #      if plot_style == '' ## fills:
 
 
 
     if not number_of_lines:
         print('No lines plotted')
         plt.close()
         return fig, ax
         #assert 0
 
     if do_legend:
         exp_colours_leg = {'historical':'black',
                        'ssp119':'green',
                        'ssp126':'dodgerblue',
                        'ssp245':'blue',
                        'ssp370':'purple',
                        'ssp434':'magenta',
                        'ssp585': 'red',
                        'ssp534-over':'orange'}
         plot_details = {}
         for exp,color in sorted(exp_colours_leg.items()):
             plot_details[exp] = {
                         'c': color,
                         'ls': '-',
                         'lw': 2.,
                         'label': exp
                     }
         for thres,ms in sorted(marker_styles.items()):
             plot_details[str(thres)] = {
                         'c': 'black',
                         'marker': ms,
                         'fillstyle':'none',
                         'label': '>' + str(thres)+u'\u00B0C'
                     }
         diagtools.add_legend_outside_right(
                 plot_details, plt.gca(), column_width=0.175)
 
     # set labels:
     plt.xlabel(x_label)
     plt.ylabel(y_label)
 
     # set title:
     if x == 'time':
         title = '' #get_long_name(y)
     else:
         title = ' '.join([get_long_name(x), 'by', get_long_name(y)])
 
     if make_figure_here and plot_dataset != 'all_models':
         title += ' '+plot_dataset
 
     plt.title(title)
 
     if make_figure_here:
         print('saving figure:', path)
         plt.savefig(path)
         plt.close()
     else:
         return fig, ax
 
 
commit ad22a8ec32adaf8adac284f6ecc17e5f178f65d5
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 25 09:18:08 2022 +0100

    working here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3126,164 +3124,166 @@
 def prepare_percentages_data( cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     land_carbon = 'tls',
     #ensemble_key = 'all',
     ):
     #print("I think the problem is somewhere in here.")
     #assert 0
 
 
     #print(thresholds_dict)
     #print(119, thresholds_dict.get(('CMIP6', 'tas', 'ssp119', 'ensemble_mean'), None))
     #print(126, thresholds_dict[('CMIP6', 'tas', 'ssp126', 'ensemble_mean')])
     #print(245, thresholds_dict[('CMIP6', 'tas', 'ssp245', 'ensemble_mean')])
     #print(370, thresholds_dict[('CMIP6', 'tas', 'ssp370', 'ensemble_mean')])
     #print(585, thresholds_dict[('CMIP6', 'tas', 'ssp585', 'ensemble_mean')])
 
     data_dict_shelve = diagtools.folder([cfg['work_dir'], 'percentages_dicts'])
     data_dict_shelve+='_'.join(['allocations', threshold])+'.shelve'
     overwrite_shelve=True
 
     if not overwrite_shelve and glob.glob(data_dict_shelve+'*'):
         print('loading:', data_dict_shelve)
         sh = shelve.open(data_dict_shelve)
         remnants = sh['remnants']
         landcs = sh['landcs']
         fgco2gts = sh['fgco2gts']
         sh.close()
 
         # (t_dataset, t_exp, t_ens, threshold)
         print(remnants.keys())
         for k in sorted(remnants.keys()):
           if 'CMIP6' in k and 'ensemble_mean' in k:
               print(k, remnants[k])
 
         if threshold == '2.0':
            print(585, remnants[('CMIP6', 'SSP585', 'ensemble_mean', '2.0')])
            print(126, remnants[('CMIP6', 'SSP126', 'ensemble_mean', '2.0')])
 
         return remnants, landcs, fgco2gts
 
     #emissions = {}
     #threshold_years = {}
     remnants = {}
     landcs = {}
     fgco2gts = {}
 
     for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
         if t_short != 'tas': continue
         t_exp = standardized_exps(t_exp)
         t_ens = standardized_ens(t_ens)
         if t_exp == 'ssp534-over': continue
         print((t_dataset, t_short, t_exp, t_ens), threshold_times)
         #if t_dataset != 'CMIP6': continue
         #if t_ens != 'ensemble_mean': continue
         #if ensemble_key == 'all': pass
         #if ensemble_key = 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         print("prepare_percentages_data", t_short, t_exp, t_ens)
 #         cumul_emissions = data_dict.get((t_dataset, 'cumul_emissions', t_exp, t_ens), None) #dict
 #         if cumul_emissions is None:  # Because not all sceanrios have emissions data.
 #            print('couldnt find cumul_emissions:', (t_dataset, 'cumul_emissions', t_exp, t_ens))
 #            for (t_dataset1, t_short1, t_exp1, t_ens1), datad in data_dict.items():
 #                 if t_dataset1 != t_dataset: continue
 #                 if t_short1 != 'cumul_emissions': continue
 #                 print('candidate:', (t_dataset1, t_short1, t_exp1, t_ens1))
 # #           for (t_dataset1, t_short1, t_exp1, t_ens1), datad in data_dict.items():
 # #                if t_dataset1 != t_dataset: continue
 # #                #if t_short1 != 'cumul_emissions': continue
 # #                print('candidate 1:', (t_dataset1, t_short1, t_exp1, t_ens1))
 #
 #            assert 0
 
         atmos_carbon = data_dict.get((t_dataset, 'atmos_carbon',  t_exp, t_ens), None) #dict
         if atmos_carbon is None:  # Because not all sceanrios have emissions data.
            print('couldnt find atmos carbon:', t_dataset, 'atmos_carbon',  t_exp, t_ens)
            for (t_dataset1, t_short1, t_exp1, t_ens1), threshold_times in thresholds_dict.items():
                 if t_dataset1 != t_dataset: continue
                 if t_short1 != 'atmos_carbon': continue
                 print('candidate:', (t_dataset, 'atmos_carbon',  t_exp, t_ens))
            assert 0
 
         # if land_carbon == 'nbpgt':
         #     landc_cumul = data_dict[(t_dataset, 'nbpgt_cumul', t_exp, t_ens)] # cube
         if land_carbon == 'tls':
             landc_cumul = data_dict.get((t_dataset, 'tls', t_exp, t_ens), None)# dict
         if landc_cumul is None:
            print('couldnt find land carbon:', t_dataset, 'tls:',  t_exp, t_ens)
            for (t_dataset1, t_short1, t_exp1, t_ens1), threshold_times in data_dict.items():
                 if t_dataset1 != t_dataset: continue
                 if t_short1 != 'tls': continue
                 print('candidate:', (t_dataset, 'tls',  t_exp, t_ens))
            assert 0
 
 
         fgco2gt_cumul = data_dict[(t_dataset, 'fgco2gt_cumul', t_exp, t_ens)] # cube
         print('prepare_percentages_data: vworking here right now', threshold_times)
         for thresh, time in threshold_times.items():
             # print("prepare_percentages_data", t_short, t_exp, t_ens, thresh, threshold, time)
             if float(threshold) != float(thresh):
                 #print(threshold, '!=', thresh)
                 continue
             if not time:
                 print('time', 'isn t there' , time)
                 continue
             print("prepare_percentages_data", t_short, t_exp, t_ens, thresh, threshold, 'time:',time)
 
             fl_threshold = float(threshold)
             if fl_threshold > 1850.: # Threshold is a specific point in time.
                 # e_xpoint = get_threshold_point(cumul_emissions, fl_threshold)
                 a_xpoint = get_threshold_point(atmos_carbon, fl_threshold)
                 n_xpoint = get_threshold_point(landc_cumul, fl_threshold)
                 f_xpoint = get_threshold_point(fgco2gt_cumul, fl_threshold)
                 if None in [a_xpoint, n_xpoint, f_xpoint]: continue
 
             print("prepare_percentages_data",threshold, time)
             # e_xpoint = get_threshold_point(cumul_emissions, time.year)
             a_xpoint = get_threshold_point(atmos_carbon, time.year)
             n_xpoint = get_threshold_point(landc_cumul, time.year)
             f_xpoint = get_threshold_point(fgco2gt_cumul, time.year)
 
+            if None in [a_xpoint,n_xpoint,f_xpoint]: assert 0
+
             # emission = cumul_emissions['cumul_emissions'][e_xpoint]
             remnant = atmos_carbon['atmos_carbon'][a_xpoint]
             fgco2gt = fgco2gt_cumul.data[f_xpoint]
 
             if isinstance(landc_cumul, dict):
                 landc = landc_cumul[land_carbon][n_xpoint]
             else:
                 landc = landc_cumul.data[n_xpoint]
             t_exp = t_exp.replace('historical-', '').upper()
 
 #            if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
 #                if landc+fgco2gt+ remnant<600.:
 #                    print('ERROR:', t_short, t_exp, t_ens, thresh, threshold, time, (landc,fgco2gt, remnant))
 #                    assert 0
             #if t_ens
             if isinstance(remnant, np.ndarray):
                  print('ERROR: This should be a single value but it is an array:', remnant)
                  print(threshold, time, t_dataset, t_short, t_exp, t_ens)
                  print('a_xpoint:', a_xpoint)
                  print('atmos_carbon:', atmos_carbon)
 
                  assert 0
             if isinstance(fgco2gt, np.ndarray):
                  assert 0
             if isinstance(landc, np.ndarray):
                  assert 0
 
             unique_key = (t_dataset, t_exp, t_ens, threshold)
             # emissions[unique_key] = emission
             remnants[unique_key] = remnant
             fgco2gts[unique_key] = fgco2gt
             landcs[unique_key] = landc
 
     print('prepare_percentages_data: saving:', data_dict_shelve)
     sh = shelve.open(data_dict_shelve)
     sh['remnants'] = remnants
     sh['landcs'] = landcs
     sh['fgco2gts'] = fgco2gts
     sh.close()
 
     return remnants, landcs, fgco2gts
 

commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -3114,152 +3126,164 @@
 def prepare_percentages_data( cfg,
     data_dict,
     thresholds_dict,
     threshold = '2.0',
     land_carbon = 'tls',
     #ensemble_key = 'all',
     ):
     #print("I think the problem is somewhere in here.")
     #assert 0
 
 
     #print(thresholds_dict)
     #print(119, thresholds_dict.get(('CMIP6', 'tas', 'ssp119', 'ensemble_mean'), None))
     #print(126, thresholds_dict[('CMIP6', 'tas', 'ssp126', 'ensemble_mean')])
     #print(245, thresholds_dict[('CMIP6', 'tas', 'ssp245', 'ensemble_mean')])
     #print(370, thresholds_dict[('CMIP6', 'tas', 'ssp370', 'ensemble_mean')])
     #print(585, thresholds_dict[('CMIP6', 'tas', 'ssp585', 'ensemble_mean')])
 
     data_dict_shelve = diagtools.folder([cfg['work_dir'], 'percentages_dicts'])
     data_dict_shelve+='_'.join(['allocations', threshold])+'.shelve'
     overwrite_shelve=True
 
     if not overwrite_shelve and glob.glob(data_dict_shelve+'*'):
         print('loading:', data_dict_shelve)
         sh = shelve.open(data_dict_shelve)
         remnants = sh['remnants']
         landcs = sh['landcs']
         fgco2gts = sh['fgco2gts']
         sh.close()
 
         # (t_dataset, t_exp, t_ens, threshold)
         print(remnants.keys())
         for k in sorted(remnants.keys()):
           if 'CMIP6' in k and 'ensemble_mean' in k:
               print(k, remnants[k])
 
         if threshold == '2.0':
            print(585, remnants[('CMIP6', 'SSP585', 'ensemble_mean', '2.0')])
            print(126, remnants[('CMIP6', 'SSP126', 'ensemble_mean', '2.0')])
 
         return remnants, landcs, fgco2gts
 
     #emissions = {}
     #threshold_years = {}
     remnants = {}
     landcs = {}
     fgco2gts = {}
 
     for (t_dataset, t_short, t_exp, t_ens), threshold_times in thresholds_dict.items():
         if t_short != 'tas': continue
         t_exp = standardized_exps(t_exp)
         t_ens = standardized_ens(t_ens)
         if t_exp == 'ssp534-over': continue
         print((t_dataset, t_short, t_exp, t_ens), threshold_times)
         #if t_dataset != 'CMIP6': continue
         #if t_ens != 'ensemble_mean': continue
         #if ensemble_key == 'all': pass
         #if ensemble_key = 'ensemble_mean' and t_ens != 'ensemble_mean': continue
 
         print("prepare_percentages_data", t_short, t_exp, t_ens)
 #         cumul_emissions = data_dict.get((t_dataset, 'cumul_emissions', t_exp, t_ens), None) #dict
 #         if cumul_emissions is None:  # Because not all sceanrios have emissions data.
 #            print('couldnt find cumul_emissions:', (t_dataset, 'cumul_emissions', t_exp, t_ens))
 #            for (t_dataset1, t_short1, t_exp1, t_ens1), datad in data_dict.items():
 #                 if t_dataset1 != t_dataset: continue
 #                 if t_short1 != 'cumul_emissions': continue
 #                 print('candidate:', (t_dataset1, t_short1, t_exp1, t_ens1))
 # #           for (t_dataset1, t_short1, t_exp1, t_ens1), datad in data_dict.items():
 # #                if t_dataset1 != t_dataset: continue
 # #                #if t_short1 != 'cumul_emissions': continue
 # #                print('candidate 1:', (t_dataset1, t_short1, t_exp1, t_ens1))
 #
 #            assert 0
 
         atmos_carbon = data_dict.get((t_dataset, 'atmos_carbon',  t_exp, t_ens), None) #dict
         if atmos_carbon is None:  # Because not all sceanrios have emissions data.
            print('couldnt find atmos carbon:', t_dataset, 'atmos_carbon',  t_exp, t_ens)
            for (t_dataset1, t_short1, t_exp1, t_ens1), threshold_times in thresholds_dict.items():
                 if t_dataset1 != t_dataset: continue
                 if t_short1 != 'atmos_carbon': continue
                 print('candidate:', (t_dataset, 'atmos_carbon',  t_exp, t_ens))
            assert 0
 
         # if land_carbon == 'nbpgt':
         #     landc_cumul = data_dict[(t_dataset, 'nbpgt_cumul', t_exp, t_ens)] # cube
         if land_carbon == 'tls':
             landc_cumul = data_dict.get((t_dataset, 'tls', t_exp, t_ens), None)# dict
         if landc_cumul is None:
            print('couldnt find land carbon:', t_dataset, 'tls:',  t_exp, t_ens)
            for (t_dataset1, t_short1, t_exp1, t_ens1), threshold_times in data_dict.items():
                 if t_dataset1 != t_dataset: continue
                 if t_short1 != 'tls': continue
                 print('candidate:', (t_dataset, 'tls',  t_exp, t_ens))
            assert 0
 
 
         fgco2gt_cumul = data_dict[(t_dataset, 'fgco2gt_cumul', t_exp, t_ens)] # cube
         print('prepare_percentages_data: vworking here right now', threshold_times)
         for thresh, time in threshold_times.items():
             # print("prepare_percentages_data", t_short, t_exp, t_ens, thresh, threshold, time)
             if float(threshold) != float(thresh):
                 #print(threshold, '!=', thresh)
                 continue
             if not time:
                 print('time', 'isn t there' , time)
                 continue
             print("prepare_percentages_data", t_short, t_exp, t_ens, thresh, threshold, 'time:',time)
 
             fl_threshold = float(threshold)
             if fl_threshold > 1850.: # Threshold is a specific point in time.
                 # e_xpoint = get_threshold_point(cumul_emissions, fl_threshold)
                 a_xpoint = get_threshold_point(atmos_carbon, fl_threshold)
                 n_xpoint = get_threshold_point(landc_cumul, fl_threshold)
                 f_xpoint = get_threshold_point(fgco2gt_cumul, fl_threshold)
                 if None in [a_xpoint, n_xpoint, f_xpoint]: continue
 
             print("prepare_percentages_data",threshold, time)
             # e_xpoint = get_threshold_point(cumul_emissions, time.year)
             a_xpoint = get_threshold_point(atmos_carbon, time.year)
             n_xpoint = get_threshold_point(landc_cumul, time.year)
             f_xpoint = get_threshold_point(fgco2gt_cumul, time.year)
 
             # emission = cumul_emissions['cumul_emissions'][e_xpoint]
             remnant = atmos_carbon['atmos_carbon'][a_xpoint]
             fgco2gt = fgco2gt_cumul.data[f_xpoint]
 
             if isinstance(landc_cumul, dict):
                 landc = landc_cumul[land_carbon][n_xpoint]
             else:
                 landc = landc_cumul.data[n_xpoint]
             t_exp = t_exp.replace('historical-', '').upper()
 
 #            if t_dataset.find('UKESM')>-1 and  threshold == '4.0':
 #                if landc+fgco2gt+ remnant<600.:
 #                    print('ERROR:', t_short, t_exp, t_ens, thresh, threshold, time, (landc,fgco2gt, remnant))
 #                    assert 0
             #if t_ens
+            if isinstance(remnant, np.ndarray):
+                 print('ERROR: This should be a single value but it is an array:', remnant)
+                 print(threshold, time, t_dataset, t_short, t_exp, t_ens)
+                 print('a_xpoint:', a_xpoint)
+                 print('atmos_carbon:', atmos_carbon)
+
+                 assert 0
+            if isinstance(fgco2gt, np.ndarray):
+                 assert 0
+            if isinstance(landc, np.ndarray):
+                 assert 0
+
             unique_key = (t_dataset, t_exp, t_ens, threshold)
             # emissions[unique_key] = emission
             remnants[unique_key] = remnant
             fgco2gts[unique_key] = fgco2gt
             landcs[unique_key] = landc
 
     print('prepare_percentages_data: saving:', data_dict_shelve)
     sh = shelve.open(data_dict_shelve)
     sh['remnants'] = remnants
     sh['landcs'] = landcs
     sh['fgco2gts'] = fgco2gts
     sh.close()
 
     return remnants, landcs, fgco2gts
 
commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5420,43 +5457,43 @@
 def timeseries_megapane(cfg, data_dict, thresholds_dict, key,
     plot_styles = ['CMIP6_range', 'CMIP6_mean'],
     experiments = ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
     #experiments = ['historical', 'historical-ssp119', 'historical-ssp126', 'historical-ssp245', 'historical-ssp370', 'ssp585'],
     plot_dataset='all_models',
     fig = None,
     ax = None,
     axhline=None,
     ):
     """
     Single time series pane for the megaplot.
     """
     make_ts_figure(cfg, data_dict, thresholds_dict, x='time', y=key,
         markers='thresholds',
         draw_line=True,
         do_moving_average=False,
         plot_dataset=plot_dataset,
         ensemble_mean = True,
         fig=fig,
         ax=ax,
         do_legend = False,
-        plot_thresholds = [1., 2., 3., 4.,],
+        plot_thresholds = [2., 3., 4.,],
         plot_styles=plot_styles,
         skip_historical_ssp = True,
         experiments = experiments,
         #short_time_range = False,
         )
     text = ''
     if key in ['tas_norm', 'atmos_carbon', ]: text = 'Atmosphere'
     if key in ['fgco2gt_cumul',]: text = 'Ocean'
     if key in ['tls', 'luegt', 'nbpgt_cumul', ]: text = 'Land'
     ax.text(0.1, 0.9, text,
      horizontalalignment='left',
      verticalalignment='center',
      transform = ax.transAxes)
 
 
     ax.set_xlim([1850., 2100.])
     if axhline == None: pass
     else: ax.axhline(axhline,c='k', ls=':')
     return fig, ax
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5301,43 +5420,43 @@
 def timeseries_megapane(cfg, data_dict, thresholds_dict, key,
     plot_styles = ['CMIP6_range', 'CMIP6_mean'],
     experiments = ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
     #experiments = ['historical', 'historical-ssp119', 'historical-ssp126', 'historical-ssp245', 'historical-ssp370', 'ssp585'],
     plot_dataset='all_models',
     fig = None,
     ax = None,
     axhline=None,
     ):
     """
     Single time series pane for the megaplot.
     """
     make_ts_figure(cfg, data_dict, thresholds_dict, x='time', y=key,
         markers='thresholds',
         draw_line=True,
         do_moving_average=False,
         plot_dataset=plot_dataset,
         ensemble_mean = True,
         fig=fig,
         ax=ax,
         do_legend = False,
-        plot_thresholds = [2., 3., 4.,],
+        plot_thresholds = [1., 2., 3., 4.,],
         plot_styles=plot_styles,
         skip_historical_ssp = True,
         experiments = experiments,
         #short_time_range = False,
         )
     text = ''
     if key in ['tas_norm', 'atmos_carbon', ]: text = 'Atmosphere'
     if key in ['fgco2gt_cumul',]: text = 'Ocean'
     if key in ['tls', 'luegt', 'nbpgt_cumul', ]: text = 'Land'
     ax.text(0.1, 0.9, text,
      horizontalalignment='left',
      verticalalignment='center',
      transform = ax.transAxes)
 
 
     ax.set_xlim([1850., 2100.])
     if axhline == None: pass
     else: ax.axhline(axhline,c='k', ls=':')
     return fig, ax
 
 

commit 967a91364972727f25376e6bf1a8e8766e54072f
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Wed Jun 29 17:13:41 2022 +0100

    sending it back

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -5207,30 +5318,43 @@
 def timeseries_megapane(cfg, data_dict, thresholds_dict, key,
     plot_styles = ['CMIP6_range', 'CMIP6_mean'],
     experiments = ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
     #experiments = ['historical', 'historical-ssp119', 'historical-ssp126', 'historical-ssp245', 'historical-ssp370', 'ssp585'],
-
+    plot_dataset='all_models',
     fig = None,
     ax = None,
+    axhline=None,
     ):
     """
     Single time series pane for the megaplot.
     """
     make_ts_figure(cfg, data_dict, thresholds_dict, x='time', y=key,
         markers='thresholds',
         draw_line=True,
         do_moving_average=False,
-        plot_dataset='all_models',
+        plot_dataset=plot_dataset,
         ensemble_mean = True,
         fig=fig,
         ax=ax,
         do_legend = False,
         plot_thresholds = [2., 3., 4.,],
         plot_styles=plot_styles,
         skip_historical_ssp = True,
         experiments = experiments,
         #short_time_range = False,
         )
+    text = ''
+    if key in ['tas_norm', 'atmos_carbon', ]: text = 'Atmosphere'
+    if key in ['fgco2gt_cumul',]: text = 'Ocean'
+    if key in ['tls', 'luegt', 'nbpgt_cumul', ]: text = 'Land'
+    ax.text(0.1, 0.9, text,
+     horizontalalignment='left',
+     verticalalignment='center',
+     transform = ax.transAxes)
+
+
     ax.set_xlim([1850., 2100.])
+    if axhline == None: pass
+    else: ax.axhline(axhline,c='k', ls=':')
     return fig, ax
 
 
commit 48994f11e432a92d7b27b4506a0f9e6d755bbdfd
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Fri Jul 22 13:27:53 2022 +0100

    removing 1 degree gwt

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4702,131 +4739,131 @@
 def make_cumulative_timeseries_megaplot(cfg, data_dict,
        thresholds_dict,
        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
        plot_types = ['pair', 'area_over_zero'],
        ensemble = 'ensemble_mean',
        dataset='CMIP6',):
     """
     Single plot massive thing.
     """
     fig = plt.figure()
     fig.set_size_inches(12, 8)
     gs = gridspec.GridSpec(5, 4, figure=fig,
           height_ratios=[1,1,0.25,1,1], hspace=0.1,
           width_ratios=[1,1,1,0.4], wspace=0.130 )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
 
     ssp_points = {
         'historical':[0, 0], # row, column
         'ssp119':[0, 1],
         'ssp126':[0, 2],
         'ssp245':[3, 0],
         'ssp370':[3, 1],
         'ssp585':[3, 2],
     }
     ax_leg = fig.add_subplot(gs[:, -1])
 
     for ssp in ssps:
         ax1 =  fig.add_subplot(gs[ssp_points[ssp][0], ssp_points[ssp][1]])
         ax2 =  fig.add_subplot(gs[ssp_points[ssp][0]+1,ssp_points[ssp][1]])
 
         fig, ax1 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'area_over_zero',
-            plot_thresholds = [1., 2., 3., 4.],
+            plot_thresholds = [2., 3., 4.],
             fig = fig,
             ax= ax1,
             do_leg=False,
         )
         ax1.set_ylim([0., 2000.])
         ax1.set_xticks([])
         ax1.set_title('')
         ax1.text(0.01, 1.01, sspify(ssp) , horizontalalignment='left',
             verticalalignment='bottom', transform=ax1.transAxes)
 
         fig, ax2 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'pc',
-            plot_thresholds = [1., 2., 3., 4.],
+            plot_thresholds = [2., 3., 4.], #1.
             fig = fig,
             ax= ax2,
             do_leg=False,
         )
         ax2.set_title('')
         #ax1.grid(axis='y')
         #ax2.grid(axis='y')
 
         if ssp_points[ssp][1]>0:
             ax1.set_ylabel('')
             ax2.set_ylabel('')
             ax1.set_yticks([])
             ax2.set_yticks([])
 
 #       if ssp_points[ssp][0]>0:
 #           ax1.set_xlabel('')
 #           ax2.set_xlabel('')
 
         if ssp == 'historical':
             ax1.set_xlim([1860., 2015.])
             ax2.set_xlim([1860., 2015.])
         else:
             ax1.set_xlim([2001., 2100.])
             ax2.set_xlim([2001., 2100.])
 
     plt.sca(ax_leg)
     colours = { #'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     plt.plot([],[], c='silver', lw=8, ls='-', label = 'Atmosphere')
     plt.plot([],[], c='mediumseagreen', lw=8, ls='-', label = 'Land')
     plt.plot([],[], c='dodgerblue', lw=8, ls='-', label = 'Ocean')
 
     #threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
     #threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
     #plt.plot([],[], c=threshold_colours[2.0], ls='-', lw=1.7, label='2'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[3.0], ls='-', lw=1.7, label='3'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[4.0], ls='-', lw=1.7, label='4'+r'$\degree$'+ ' GWT', alpha=0.7,)
 
     #plt.plot([],[], 'k-', lw=1.3,label='Emissions+LUE')
     #plt.plot([],[], 'k--', lw=1.3, label='LUE')
     plt.plot([], [], c='k', ls=':', label = 'Raupach (2014)' )
     plt.plot([], [], c='navy', ls='-.', label = 'Watson (2020)'  )
     add_ipcc = True
     if add_ipcc:
         plt.plot([], [], c='k', ls='-', lw=2.8,  label = 'SPM.7')
 
 
     legd = ax_leg.legend( #keys, labels,
         bbox_to_anchor=(1.7, 0.5),
         numpoints=1, labelspacing=1.2,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
     if dataset == 'CMIP6':
         plt.suptitle('Anthropogenic Carbon Allocation Timeseries')
     else:
         plt.suptitle(dataset+' Anthropogenic Carbon Allocation Timeseries')
 
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries_megaplot'])
     path += '_'.join(['allocation_timeseries', 'megaplot', dataset]) + image_extention
     print('saving figure:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 

commit a36b8282d4eb6af5f08b736db38e3e3c8b7c6309
Author: Lee de Mora <ledm@pml.ac.uk>
Date:   Mon Jul 18 14:19:51 2022 +0100

    workinug here

diff --git a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
--- a/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
+++ b/esmvaltool/diag_scripts/ocean/diagnostic_gwt_timeseries.py
@@ -4673,127 +4702,131 @@
 def make_cumulative_timeseries_megaplot(cfg, data_dict,
        thresholds_dict,
        ssps= ['historical', 'ssp119', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
        plot_types = ['pair', 'area_over_zero'],
        ensemble = 'ensemble_mean',
        dataset='CMIP6',):
     """
     Single plot massive thing.
     """
     fig = plt.figure()
     fig.set_size_inches(12, 8)
     gs = gridspec.GridSpec(5, 4, figure=fig,
           height_ratios=[1,1,0.25,1,1], hspace=0.1,
           width_ratios=[1,1,1,0.4], wspace=0.130 )# width_ratios=[1,1], wspace=0.5, hspace=0.5)
 
     ssp_points = {
         'historical':[0, 0], # row, column
         'ssp119':[0, 1],
         'ssp126':[0, 2],
         'ssp245':[3, 0],
         'ssp370':[3, 1],
         'ssp585':[3, 2],
     }
     ax_leg = fig.add_subplot(gs[:, -1])
 
     for ssp in ssps:
         ax1 =  fig.add_subplot(gs[ssp_points[ssp][0], ssp_points[ssp][1]])
         ax2 =  fig.add_subplot(gs[ssp_points[ssp][0]+1,ssp_points[ssp][1]])
 
         fig, ax1 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'area_over_zero',
-            plot_thresholds = [2., 3., 4.],
+            plot_thresholds = [1., 2., 3., 4.],
             fig = fig,
             ax= ax1,
             do_leg=False,
         )
         ax1.set_ylim([0., 2000.])
         ax1.set_xticks([])
         ax1.set_title('')
         ax1.text(0.01, 1.01, sspify(ssp) , horizontalalignment='left',
             verticalalignment='bottom', transform=ax1.transAxes)
 
         fig, ax2 = make_cumulative_timeseries(cfg, data_dict,
             thresholds_dict,
             ssp=ssp,
             ensemble = ensemble,
             dataset = dataset,
             plot_type = 'pc',
-            plot_thresholds = [2., 3., 4.],
+            plot_thresholds = [1., 2., 3., 4.],
             fig = fig,
             ax= ax2,
             do_leg=False,
         )
         ax2.set_title('')
         #ax1.grid(axis='y')
         #ax2.grid(axis='y')
 
         if ssp_points[ssp][1]>0:
             ax1.set_ylabel('')
             ax2.set_ylabel('')
             ax1.set_yticks([])
             ax2.set_yticks([])
 
 #       if ssp_points[ssp][0]>0:
 #           ax1.set_xlabel('')
 #           ax2.set_xlabel('')
 
         if ssp == 'historical':
             ax1.set_xlim([1860., 2015.])
             ax2.set_xlim([1860., 2015.])
         else:
-            ax1.set_xlim([2015., 2100.])
-            ax2.set_xlim([2015., 2100.])
+            ax1.set_xlim([2001., 2100.])
+            ax2.set_xlim([2001., 2100.])
 
     plt.sca(ax_leg)
     colours = { #'cumul_emissions': 'silver',
         'atmos_carbon': 'silver',
         'fgco2gt_cumul':'dodgerblue',
         'nbpgt_cumul':'orange',
         'tls':'mediumseagreen',
         'luegt': 'purple'}
 
     plt.plot([],[], c='silver', lw=8, ls='-', label = 'Atmosphere')
     plt.plot([],[], c='mediumseagreen', lw=8, ls='-', label = 'Land')
     plt.plot([],[], c='dodgerblue', lw=8, ls='-', label = 'Ocean')
 
     #threshold_colours = {2.0: 'darkorange', 3.0:'red', 4.0:'purple',}
-    threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
+    #threshold_colours = {2.0: 'darkblue', 3.0:'darkred', 4.0:'purple',}
     #plt.plot([],[], c=threshold_colours[2.0], ls='-', lw=1.7, label='2'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[3.0], ls='-', lw=1.7, label='3'+r'$\degree$'+ ' GWT', alpha=0.7,)
     #plt.plot([],[], c=threshold_colours[4.0], ls='-', lw=1.7, label='4'+r'$\degree$'+ ' GWT', alpha=0.7,)
 
     #plt.plot([],[], 'k-', lw=1.3,label='Emissions+LUE')
     #plt.plot([],[], 'k--', lw=1.3, label='LUE')
     plt.plot([], [], c='k', ls=':', label = 'Raupach (2014)' )
     plt.plot([], [], c='navy', ls='-.', label = 'Watson (2020)'  )
+    add_ipcc = True
+    if add_ipcc:
+        plt.plot([], [], c='k', ls='-', lw=2.8,  label = 'SPM.7')
+
 
     legd = ax_leg.legend( #keys, labels,
         bbox_to_anchor=(1.7, 0.5),
         numpoints=1, labelspacing=1.2,
         loc='center right', ) #tsize=16)
 
     legd.draw_frame(False)
     legd.get_frame().set_alpha(0.)
     ax_leg.get_xaxis().set_visible(False)
     ax_leg.get_yaxis().set_visible(False)
     plt.axis('off')
 
     if dataset == 'CMIP6':
         plt.suptitle('Anthropogenic Carbon Allocation Timeseries')
     else:
         plt.suptitle(dataset+' Anthropogenic Carbon Allocation Timeseries')
 
     image_extention = diagtools.get_image_format(cfg)
     path = diagtools.folder([cfg['plot_dir'], 'allocation_timeseries_megaplot'])
     path += '_'.join(['allocation_timeseries', 'megaplot', dataset]) + image_extention
     print('saving figure:', path)
     plt.savefig(path)
     plt.close()
 
 
 
 
