<jupyter_start><jupyter_text>What is the global glacier ice volume outside the ice sheets? Code & data attached to the manuscript. If using the data for something else, please refer to the original sources.<jupyter_code>import pandas as pd
import numpy as np<jupyter_output><empty_output><jupyter_text>Read in the various estimates<jupyter_code># Match regional agg choices Millan 2022
def reformat_df(df):
    df.loc['01, 02'] = df.loc[['01', '02']].sum()
    df.loc['13, 14, 15'] = df.loc[['13', '14', '15']].sum()
    return df.drop(['01', '02'] + ['13', '14', '15']).sort_index()
# Output
gdf = pd.DataFrame()

s = 'mb96'
gdf.loc['Global', f'{s}_V'] = 180000
gdf.loc['Global', f'{s}_V_err'] = 40000
gdf.loc['Global', f'{s}_SLE'] = 0.5
gdf.loc['Global', f'{s}_SLE_err'] = 0.1

s = 'o04'
gdf.loc['excl. A. & G.', f'{s}_V'] = 56000
gdf.loc['excl. A. & G.', f'{s}_V_err'] = np.NaN
gdf.loc['excl. A. & G.', f'{s}_SLE'] = 0.15
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = np.NaN

s = 'dm05'
gdf.loc['Global', f'{s}_V'] = 260000
gdf.loc['Global', f'{s}_V_err'] = 65000
gdf.loc['Global', f'{s}_SLE'] = 0.65
gdf.loc['Global', f'{s}_SLE_err'] = 0.16
gdf.loc['excl. A. & G.', f'{s}_V'] = 133000
gdf.loc['excl. A. & G.', f'{s}_V_err'] = 20000
gdf.loc['excl. A. & G.', f'{s}_SLE'] = 133000 * 0.9 / 326 * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = 20000 * 0.9 / 326 * 1e-3

s = 'rb05'
gdf.loc['excl. A. & G.', f'{s}_V'] = 87000
gdf.loc['excl. A. & G.', f'{s}_V_err'] = 10000
gdf.loc['excl. A. & G.', f'{s}_SLE'] = 0.241
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = 0.026<jupyter_output><empty_output><jupyter_text>The following estimates have regional tables.  Radic & Hock 2010 This is pre-RGI and slightly different:<jupyter_code>rh10 = pd.read_csv('data/rh10.csv', index_col=0, header=1)
rh10
rh10_total = rh10.iloc[-1:].copy()
rh10_total
rh10 = rh10.iloc[:-1].copy().drop('WGI_XF', axis=1)
rh10.index = [f'{int(c):02d}' for c in rh10.index]
rh10.sum().to_frame().T
((rh10**2).sum()**0.5).loc[['A_err.1', 'V_err.1', 'SLE_err']].to_frame().T<jupyter_output><empty_output><jupyter_text>Table is consistent. **Volume without 05 and 19**:<jupyter_code>rh10_no = rh10.drop(['17', '18', '19'])
rh10_no_s = rh10_no.sum().to_frame().T
rh10_no_s
err = ((rh10_no**2).sum()**0.5).loc[['A_err.1', 'V_err.1', 'SLE_err']].to_frame().T
err
rh10_no['V.1'].values
s = 'rh10'
gdf.loc['Global', f'{s}_V'] = rh10_total['V.1'].values
gdf.loc['Global', f'{s}_V_err'] = rh10_total['V_err.1'].values
gdf.loc['Global', f'{s}_SLE'] = rh10_total['SLE'].values * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = rh10_total['SLE_err'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = rh10_no_s['V.1'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = err['V_err.1'].values
gdf.loc['excl. A. & G.', f'{s}_SLE'] = rh10_no_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = err['SLE_err'].values * 1e-3<jupyter_output><empty_output><jupyter_text>Marzeion et al, 2012<jupyter_code>m12 = pd.read_csv('data/m12.csv', index_col=0)
m12[['A', 'A_err']] = m12[['A', 'A_err']] * 1e3<jupyter_output><empty_output><jupyter_text>Let's compute the volumes from SLE:<jupyter_code>m12['V'] = m12['SLE'] * 362 / 0.9
m12['V_err'] = m12['SLE_err'] * 362 / 0.9
m12_total = m12.iloc[-1:].copy()
m12_total
m12 = m12.iloc[:-1].copy()
m12.index = [f'{int(c):02d}' for c in m12.index]
m12.sum().to_frame().T
((m12**2).sum()**0.5).loc[['A_err', 'V_err', 'SLE_err']].to_frame().T<jupyter_output><empty_output><jupyter_text>OK Table is more or less consistent, **uncertainty estimates computed as uncorrelated.** **Volume without 05 and 19**:<jupyter_code>m12_no5 = m12.drop('05')
m12_no5_s = m12_no5.sum().to_frame().T
m12_no5_s
err = ((m12_no5**2).sum()**0.5).loc[['A_err', 'V_err', 'SLE_err']].to_frame().T
err
s = 'm12'
gdf.loc['excl. A. & G.', f'{s}_V'] = m12_no5_s['V'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = err['V_err'].values
gdf.loc['excl. A. & G.', f'{s}_SLE'] = m12_no5_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = err['SLE_err'].values * 1e-3<jupyter_output><empty_output><jupyter_text>Huss & Farinotti 2012<jupyter_code>hf12 = pd.read_csv('data/hf12.csv', index_col=0).drop('Name', axis=1)
hf12
hf12_total = hf12.iloc[[-1]].copy()
hf12_total
hf12 = hf12.iloc[:-1].copy()
hf12.index = [f'{int(c):02d}' for c in hf12.index]
hf12.sum().to_frame().T<jupyter_output><empty_output><jupyter_text>OK Table is more or less consistent. The volume is off by 11 and the error estimates aren't exact (using uncorrelated is much worse) **Volume without 05 and 19**:<jupyter_code>hf12_no = hf12.drop(['05', '19'])
hf12_no_s = hf12_no.sum().to_frame().T
hf12_no_s
s = 'hf12'
gdf.loc['Global', f'{s}_V'] = hf12_total['V'].values
gdf.loc['Global', f'{s}_V_err'] = hf12_total['V_err'].values
gdf.loc['Global', f'{s}_SLE'] = hf12_total['SLE'].values * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = hf12_total['SLE_err'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = hf12_no_s['V'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = hf12_no_s['V_err'].values
gdf.loc['excl. A. & G.', f'{s}_SLE'] = hf12_no_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = hf12_no_s['SLE_err'].values * 1e-3<jupyter_output><empty_output><jupyter_text>Grinsted, 2013<jupyter_code>g13 = pd.read_csv('data/g13.csv', index_col=0)<jupyter_output><empty_output><jupyter_text>Let's compute the volumes from SLE:<jupyter_code>g13['V'] = g13['SLE'] * 362 / 0.9
g13['V_err'] = g13['SLE_err'] * 362 / 0.9
g13_total = g13.iloc[-2:].copy()
g13_total
g13 = g13.iloc[:-2].copy()
g13.index = [f'{int(c):02d}' for c in g13.index]
g13.sum().to_frame().T<jupyter_output><empty_output><jupyter_text>OK Table is more or less consistent. **Volume without 05 and 19**:<jupyter_code>g13_no = g13.drop(['05', '19'])
g13_no_s = g13_no.sum().to_frame().T
g13_no_s
s = 'g13'
gdf.loc['Global', f'{s}_V'] = g13_total.loc['Total', 'V']
gdf.loc['Global', f'{s}_V_err'] = g13_total.loc['Total', 'V_err']
gdf.loc['Global', f'{s}_SLE'] = g13_total.loc['Total', 'SLE'] * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = g13_total.loc['Total', 'SLE_err'] * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = g13_total.loc['Withouth 5+19', 'V']
gdf.loc['excl. A. & G.', f'{s}_V_err'] = g13_total.loc['Withouth 5+19', 'V_err']
gdf.loc['excl. A. & G.', f'{s}_SLE'] = g13_total.loc['Withouth 5+19', 'SLE'] * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = g13_total.loc['Withouth 5+19', 'SLE_err'] * 1e-3<jupyter_output><empty_output><jupyter_text>Radic et al., 2014<jupyter_code>r14 = pd.read_csv('data/r14.csv', index_col=0)
r14_total = r14.iloc[[-1]].copy()
r14_total
r14 = r14.iloc[:-1].copy()
r14.index = [f'{int(c):02d}' for c in r14.index]
r14_s = r14.sum().to_frame().T
r14_s<jupyter_output><empty_output><jupyter_text>OK Table is consistent. **Volume without 05 and 19**:<jupyter_code>r14_no = r14.drop(['05', '19'])
r14_no_s = r14_no.sum().to_frame().T
r14_no_s
s = 'r14'
gdf.loc['Global', f'{s}_V'] = r14_total['V'].values
gdf.loc['Global', f'{s}_V_err'] = r14_total['V_err'].values
gdf.loc['Global', f'{s}_SLE'] = r14_total['SLE'].values * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = r14_total['SLE_err'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = r14_no_s['V'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = np.NaN
gdf.loc['excl. A. & G.', f'{s}_SLE'] = r14_no_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = np.NaN<jupyter_output><empty_output><jupyter_text>Farinotti et al., 2019<jupyter_code>f19 = pd.read_csv('data/f19.csv', index_col=0)
f19[['V', 'V_err']] = f19[['V', 'V_err']] * 1e3
f19_total = f19.iloc[[-1]].copy()
f19_total
f19 = f19.iloc[:-1].copy()
f19.sum().to_frame().T<jupyter_output><empty_output><jupyter_text>OK Table is consistent. **Volume without 05 and 19**:<jupyter_code>f19_no = f19.drop(['05', '19'])
f19_no_s = f19_no.sum().to_frame().T
f19_no_s
s = 'f19'
gdf.loc['Global', f'{s}_V'] = f19_total['V'].values
gdf.loc['Global', f'{s}_V_err'] = f19_total['V_err'].values
gdf.loc['Global', f'{s}_SLE'] = f19_total['SLE'].values * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = f19_total['SLE_err'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = f19_no_s['V'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = f19_no_s['V_err'].values
gdf.loc['excl. A. & G.', f'{s}_SLE'] = f19_no_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = f19_no_s['SLE_err'].values * 1e-3<jupyter_output><empty_output><jupyter_text>Millan et al., 2022<jupyter_code>m22 = pd.read_csv('data/m22.csv', index_col=0)
m22[['A', 'V', 'V_err']] *= 1e3;
m22_total = m22.iloc[[-1]].copy()
m22_total
# Also add a dataset with AA "cropped" only
m22_a = m22.iloc[[-2]].copy()
m22_a
m22 = m22.iloc[:-2].copy()
m22_s = m22.sum().to_frame().T
m22_s
# Total with other region
m22_ss = (m22.iloc[:-1].sum().to_frame()).T + m22_a.values
m22_ss
# Verification
# diff = 35.1 - 3.2
# print(diff * 1e3, 140900 - 109000)<jupyter_output><empty_output><jupyter_text>OK Table is more or less consistent, with the **problem of global SLE of course**. **Volume without 05 and 19**:<jupyter_code>m22_no = m22.drop(['05', '19'])
m22_no_s = m22_no.sum().to_frame().T
m22_no_s
s = 'm22'
gdf.loc['Global', f'{s}_V'] = m22_total['V'].values
gdf.loc['Global', f'{s}_V_err'] = m22_s['V_err'].values
gdf.loc['Global', f'{s}_SLE'] = m22_s['SLE'].values * 1e-3
gdf.loc['Global', f'{s}_SLE_err'] = m22_s['SLE_err'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_V'] = m22_no_s['V'].values
gdf.loc['excl. A. & G.', f'{s}_V_err'] = m22_no_s['V_err'].values
gdf.loc['excl. A. & G.', f'{s}_SLE'] = m22_no_s['SLE'].values * 1e-3
gdf.loc['excl. A. & G.', f'{s}_SLE_err'] = m22_no_s['SLE_err'].values * 1e-3<jupyter_output><empty_output><jupyter_text>Final check and area vs volume plot<jupyter_code># We copy the values from the table to have the authors values 
d = {
    'mb96': [180000, 40000, 680000, 0.5],
    # 'o04': [, ,],
    'dm05': [260000, 65000, 785000, 0.65],
    # 'rb05': [, ,],
    'rh10': [241430, 29229, 741448, 0.6],
    # 'm12': [, ,],
    'hf12': [170214, 20688, 734856, 0.43],
    'g13': [140778, 28155, 734933, 0.35],
    'r14': [209973, 0, 736989, 0.522],
    'f19': [158170, 41030, 705253, 0.324],
    'm22': [140800, 40400, 705253, 0.311],
    'm22*': [109000, 32130, 705253-106701, 0.257],
}
df_v = pd.DataFrame(d, index=['V', 'V_err', 'A', 'SLE']).T
df_v
for k in df_v.index:
    if k == 'm22*':
        continue
    p = df_v.loc[k, 'V']
    m = gdf.loc['Global', k +'_V']
    if not np.allclose(p, m):
        print(k, 'V', p, m)
    p = df_v.loc[k, 'V_err']
    m = gdf.loc['Global', k +'_V_err']
    if not np.allclose(p, m):
        print(k, 'V_err', p, m)<jupyter_output>g13 V_err 28155.0 28155.555555555555
r14 V_err 0.0 nan<jupyter_text>Plot<jupyter_code>import seaborn as sns
import random

import matplotlib.pyplot as plt
from matplotlib.offsetbox import TextArea, VPacker, AnnotationBbox  # for the text box
from matplotlib.gridspec import GridSpec  # for plot layout
# Separate vol and SLE
x = np.array([1, 2])
gdf.index = x
gdf_vol = gdf[[c for c in gdf if 'V' in c]].copy()
gdf_sle = gdf[[c for c in gdf if 'SLE' in c]].copy()
dataframes = {
    'm12': reformat_df(m12),
    'hf12': reformat_df(hf12),
    'g13': reformat_df(g13),
    'r14': reformat_df(r14),
    'f19': reformat_df(f19),
    'm22': m22,
}
legend = {
    'mb96': '<NAME>, 1996',
    'o04': 'Ohmura, 2004',
    'dm05': 'Dyurgerov and Meier, 2005',
    'rb05': 'Raper and Braithwaite 2005',
    'rh10': '<NAME>, 2010',
    'm12': 'Marzeion and others, 2012',
    'hf12': '<NAME>, 2012',
    'g13': 'Grinsted, 2013',
    'r14': 'Radić and others, 2014',
    'f19': 'Farinotti and others, 2019',
    'm22': 'Millan and others, 2022',
}
# Axis labels for region plot, in order by RGI area
rgi_ids = reformat_df(f19).sort_values('A').index[::-1]

names = [
    'Antarctic\nPeriphery',
    'Arctic Canada\nNorth',
    'Alaska, Western\nCanada & USA',
    'High Mountain\nAsia',
    'Greenland\nperiphery',
    'Russian\nArctic',
    'Arctic Canada\nSouth',
    'Svalbard &\nJan Mayen',
    'Southern\nAndes',
    'Iceland',
    'Scandinavia',
    'Asia North',
    'Low Latitudes',
    'Central Europe',
    'Caucasus &\nMiddle East',
    'New Zealand'
]

strs = []
for i, n in zip(rgi_ids, names):
    # strs.append(n + f' ({i})')
    strs.append(n)
# Whixh data are available for the global plot
estimates = [c.split('_')[0] for c in gdf_vol if 'err' not in c]
sle_valid_keys_global = gdf_sle[[f'{e}_SLE' for e in estimates]].iloc[[0]].dropna(axis=1).columns
sle_valid_keys_no = gdf_sle[[f'{e}_SLE' for e in estimates]].iloc[[1]].dropna(axis=1).columns
v_valid_keys_global = gdf_vol[[f'{e}_V' for e in estimates]].iloc[[0]].dropna(axis=1).columns
v_valid_keys_no = gdf_vol[[f'{e}_V' for e in estimates]].iloc[[1]].dropna(axis=1).columns
# Make plot pretty
sns.set_context('talk')
sns.set_style('whitegrid')
# Figure size
scale_factor = 0.85  # to control font size in PNG
f = plt.figure(figsize=(22 * scale_factor, 18 * scale_factor))

# Axis layout
gs = GridSpec(3, 2, wspace=0.03)
ax1 = f.add_subplot(gs[0, 1])
ax2 = f.add_subplot(gs[1, 1])
ax3 = f.add_subplot(gs[2, 1])
ax4 = f.add_subplot(gs[:, 0])
ax1.sharex(ax2)

# Prepare the rhs plot for y distance between estimates - we want the same for b and c
nm = len(sle_valid_keys_global) / 40  # +1 for additional millan
offset_global = np.linspace(-nm, nm, len(sle_valid_keys_global) + 1)
nm = (len(sle_valid_keys_no) - 1) / 40
offset_no = np.linspace(-nm, nm, len(sle_valid_keys_no))
xtext = 0.85  # where to put the rhs text

# Colors - we shuffle for prettier colors in the "important" estimates
p = sns.color_palette("dark", len(estimates))
random.Random(2).shuffle(p)
cmillan = '#7f8dbe'
mimarker = 'D'

# Parameters
y_range_rhs = 0.27  # Make sure both plots have same size despite different # of estimates
fs_rhs = 18
fs_lhs = 16

# Shift axis up right
yshift = 0.03

# ------------- Plot top right (b) -------------
ax = ax1

toplot = gdf_sle.iloc[[0]]
for i, e in enumerate(sle_valid_keys_global):

    estimate = e.split('_')[0]
    color = p[estimates.index(estimate)]

    err = toplot[f'{e}_err']
    if not np.isfinite(err.values[0]):
        err = None

    ax.errorbar(toplot[f'{e}'], offset_global[i], xerr=err, fmt='o', c=color);
    ax.text(xtext, offset_global[i], legend[estimate], c=color, va='center', fontsize=fs_rhs)

# Millan weird
ax.errorbar(257.2 * 1e-3, offset_global[i + 1], xerr=85 * 1e-3, fmt=mimarker, c=color, alpha=0.5);
ax.text(xtext, offset_global[i + 1], 'Millan and others, 2022*', c=cmillan, va='center', fontsize=fs_rhs)

# Axis cosmetics stuffs
ax.grid(axis='y')
ax.set_yticks([])
ax.set_ylim((-y_range_rhs, y_range_rhs))
sns.despine(ax=ax, bottom=False)
ax.set_title(r'$\bf{b}$ SLE global', loc='left')
plt.setp(ax1.get_xticklabels(), visible=False)


# Pos shenanigans
pos = ax.get_position()
pos.y0 += yshift;
ax.set_position(pos)


# ------------- Plot middle right (c) -------------
ax = ax2

toplot = gdf_sle.iloc[[1]]
for i, e in enumerate(sle_valid_keys_no):

    estimate = e.split('_')[0]
    color = p[estimates.index(estimate)]

    err = toplot[f'{e}_err']
    if not np.isfinite(err.values[0]):
        err = None

    ax.errorbar(toplot[f'{e}'], offset_no[i], xerr=err, fmt='o', c=color);
    ax.text(xtext, offset_no[i], legend[estimate], c=color, va='center', fontsize=fs_rhs)

# Axis cosmetics stuffs
ax.grid(axis='y')
ax.set_yticks([])
ax.set_xlim([0, 0.85]);
ax.set_ylim((-y_range_rhs, y_range_rhs))

# Pos shenanigans
pos = ax.get_position()
pos.y0 += yshift * 2; pos.y1 += yshift;
ax.set_position(pos)

ax.set_xlabel('Sea-level equivalent (m)')
ax.set_title(r'$\bf{c}$ SLE excluding Antarctic periphery & Greenland periphery', loc='left');
sns.despine(ax=ax)

# ------------- Plot bottom right (d) -------------
ax = ax3

for estimate in df_v.index:
    if estimate == 'm22*':
        c = cmillan
        fmt = mimarker
    else:
        c = p[estimates.index(estimate)]
        fmt = 'o'

    toplot = df_v.loc[[estimate]]
    ax.errorbar(toplot.A * 1e-3, toplot.V * 1e-3, yerr=toplot.V_err * 1e-3, fmt=fmt, color=c, capsize=6)

    # Text
    e = estimate.upper()
    if len(e) == 4 and '*' not in e:
        text = f'{e[0]}{e[2:]}'
    else:
        text = f'{e[0]}{e[1:]}'

    px, py = toplot.A * 1e-3 + 1.5, toplot.V * 1e-3 + 1.5
    ha = 'left'
    va = 'bottom'
    if e in ['R14', 'DM05']:
        px -= 3
        ha = 'right'
    if e in ['M22', 'G13']:
        py -= 3
        va = 'top'

    ax.text(px, py, text, color=c, ha=ha, va=va, fontsize=14);
ax.set_title(r'$\bf{d}$ Global volume $\it{vs}$ area', loc='left')
ax.set_xlabel('Area (10$^3$ km$^2$)'); ax.set_ylabel('Volume (10$^3$ km$^3$)');

ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
ax.tick_params(axis='both', which='both', length=0)

# Pos shenanigans
pos = ax.get_position()
pos.y1 -= yshift / 2;
ax.set_position(pos)


# ------------- Plot left (a) -------------
ax = ax4

# Index on the y-axis
rx = np.arange(len(m22))
# Space between estimates
offset = np.linspace(-0.25, 0.25, 6)

# Parameters
s = 6  # markersize
a = 0.4  # alpha for "less important" estimates

texts_for_legend = []

# Go over all esimates
for i, estimate in enumerate(['m22', 'f19', 'r14', 'g13', 'hf12', 'm12']):
    df = dataframes[estimate]
    if estimate == 'm12':
        # One reg less
        df = df.loc[rgi_ids[1:]]
        x = rx[1:] + offset[i]
    else:
        df = df.loc[rgi_ids]
        x = rx + offset[i]

    alpha = 1 if i < 2 else a

    c = p[estimates.index(estimate)]
    ax.errorbar(df['V'], x, xerr=df['V_err'], fmt='o', c=c, markersize=s, alpha=alpha);
    texts_for_legend.append(TextArea(legend[estimate], textprops=dict(color=c, fontsize=fs_lhs, alpha=alpha)))

# Add Millan other
ax.errorbar(m22_a['V'], rx[0] - 0.35, xerr=m22_a['V_err'], fmt=mimarker, c=cmillan, markersize=s);
texts_for_legend.insert(0, TextArea('Millan and others, 2022*', textprops=dict(color=cmillan, fontsize=fs_lhs)))

# Legend box
texts_vbox = VPacker(children=texts_for_legend, pad=0, sep=0)
ann = AnnotationBbox(texts_vbox, (.223, .92), xycoords=ax.transAxes,
                     bboxprops=dict(color='none', facecolor='white'))
ann.set_figure(f)
f.artists.append(ann)

# Titles
ax.set_title(r'$\bf{a}$ Volume per region', loc='left');
ax.set_xlabel('Ice volume (km$^3$) - log scale');

# Axis cosmetics
ax.invert_yaxis()
ax.set_yticks(rx);
ax.set_yticklabels(strs);
sns.despine(ax=ax, right=True)
ax.grid(axis='y', which='both')
# All gridlines for log
ax.set_xscale('log')
xlocs = np.concatenate([np.arange(1, 11)[2:] * 1e1,
                        np.arange(1, 11) * 1e2,
                        np.arange(1, 11) * 1e3,
                        np.arange(1, 11)[:6] * 1e4])
ax.set_xticks(xlocs)
ax.set_xlim([30, 65000])

locs, labels = plt.yticks()

# Shading
for i, loc in enumerate(locs):
    alpha = 0.05 if i % 2 == 1 else 0.1
    ax.axhspan(loc - 0.5, loc + 0.5, facecolor='grey', alpha=alpha)
ax.set_ylim(15.5, -0.5)

# plt.tight_layout()
plt.savefig('plot_global_and_reg_log_alpha.png', dpi=150, bbox_inches='tight');<jupyter_output><empty_output><jupyter_text>Additional analyses   Other models in Farinotti 2019<jupyter_code>df_rgi = pd.read_hdf('data/rgi6_stats.h5')
df_all = pd.read_hdf('data/f19_icevol_pergla.hdf')

df_all['area'] = df_rgi['Area']
df_all['REG'] = [s[6:8] for s in df_all.index]
df_ref = df_rgi.groupby('O1Region').sum()[['Area']]
models = ['composite_vol_m3',
          'model_1_vol_m3',
          'model_2_vol_m3',
          'model_3_vol_m3',
          'model_4_vol_m3']

df_all_s = df_ref.copy()

for mo in models:

    dd_ = df_all[['REG', 'area', mo]].dropna()
    dd = dd_.groupby('REG').sum().replace(0, np.NaN) * 1e-9
    dd['area'] =  dd_.groupby('REG').sum().replace(0, np.NaN)['area']

    ratio = dd['area'].divide(df_ref['Area'])
    dd.loc[ratio < 0.98] = np.NaN

    df_all_s[mo] = dd[mo]
df_all_s.loc['01, 02'] = df_all_s.loc[['01', '02']].sum()
df_all_s.loc['13, 14, 15'] = df_all_s.loc[['13', '14', '15']].sum()
df_all_s = df_all_s.drop(['01', '02'] + ['13', '14', '15']).sort_index()
df_all_s.loc['13, 14, 15', 'model_4_vol_m3'] = np.NaN
df_all_s.loc['01, 02', 'model_2_vol_m3'] = np.NaN
df_all_s.loc['01, 02', 'model_4_vol_m3'] = np.NaN
f, ax = plt.subplots(figsize=(14, 7))

reformat_df(f19).plot(ax=ax, y='V', yerr='V_err', marker='o', linestyle='none', alpha=0.8, c='C0');
m22.plot(ax=ax, y='V', yerr='V_err', marker='o', linestyle='none', alpha=0.8, c='C3');

plt.plot(df_all_s.model_1_vol_m3, '.', c='black', zorder=99)

ax.set_yscale('log')
plt.xticks(np.arange(len(m22.index)));
ax.set_xticklabels(m22.index, rotation=45);
plt.legend(['Individual models in F 19', 'Farinotti 19', 'Millan 22'], loc='lower left'); plt.xlabel('Region'); plt.ylabel('Volume [km$^3$]');

plt.plot(df_all_s.model_1_vol_m3, '.', c='black', zorder=99)
plt.plot(df_all_s.model_2_vol_m3, '.', c='black', zorder=99)
plt.plot(df_all_s.model_3_vol_m3, '.', c='black', zorder=99)
plt.plot(df_all_s.model_4_vol_m3, '.', c='black', zorder=99)

plt.title('Volume, log scale');<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2185389517739941, 'fraction_numerical': 0.06934271853895177, 'mean_word_length': 4.40123298227588, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '229853', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 10390, 'n_tokens_neox': 9456, 'n_words': 1793, 'path': 'analysis.ipynb', 'repo_name': 'fmaussion/global_glacier_volume_paper', 'size': '21054'}