From 4f00d0d0d3577264a7b01088b52e7be422e35a96 Mon Sep 17 00:00:00 2001 From: Trevor Ray Hillebrand Date: Wed, 18 May 2022 13:08:27 -0600 Subject: [PATCH 1/3] Update plot_mass_balance.py to use new globalStats budget components Update plot_mass_balance.py to use new globalStats budgets and plot total, grounded, and floating components, as well as fractional error between total volume change and sum of budget components. --- .../output_processing_li/plot_mass_balance.py | 172 ++++++++++++++---- 1 file changed, 136 insertions(+), 36 deletions(-) diff --git a/landice/output_processing_li/plot_mass_balance.py b/landice/output_processing_li/plot_mass_balance.py index c7ee81773..43d10bc94 100755 --- a/landice/output_processing_li/plot_mass_balance.py +++ b/landice/output_processing_li/plot_mass_balance.py @@ -30,61 +30,161 @@ dyr[1:] = yr[1:]-yr[:-1] # ---- Figure: mass change rate --- -fig = plt.figure(1, figsize=(6, 10), facecolor='w') +fig, ax = plt.subplots(3,3) -ax = fig.add_subplot(2, 1, 1) -plt.xlabel('Year') -plt.ylabel('Grounded mass change (Gt/yr)') -plt.grid() +#===================== +# 1. Total mass budget +#===================== +# get fields and plot stuff +vol = f.variables['totalIceVolume'][:] +vol = vol * rhoi / 1.0e12 +dvol = np.zeros(yr.shape) +dvol[1:] = (vol[1:]-vol[:-1]) / dyr[1:] + +# --- time-step-wise mass change --- +ax[0,0].plot(yr, dvol, 'k', linewidth=3, label="mass change") + +SMB = f.variables['totalSfcMassBal'][:] / 1.0e12 +ax[0,0].plot(yr, SMB, label="SMB") + +BMB = f.variables['totalBasalMassBal'][:] / 1.0e12 +ax[0,0].plot(yr, BMB, label="BMB") + +calv = -f.variables['totalCalvingFlux'][:] / 1.0e12 +ax[0,0].plot(yr, calv, label='calv') + +FMF = -f.variables['totalFaceMeltingFlux'][:] / 1.0e12 +ax[0,0].plot(yr, FMF, label='facemelt') + +# Grounding line flux and grounding line migration flux +# do not come into the global mass budget +ax[0,0].plot(yr, SMB+BMB+calv+FMF, "--", label="total") + +ax[0,0].legend(loc='best', prop={'size': 6}) +ax[0,0].set_ylabel('Mass change (Gt)') +# --- cumulative mass change --- + +ax[1,0].plot(yr, vol - vol[0], 'k', linewidth=3, label='total mass change') +ax[1,0].plot(yr, (SMB*dyr).cumsum(), label="SMB") +ax[1,0].plot(yr, (BMB*dyr).cumsum(), label="BMB") +ax[1,0].plot(yr, (calv*dyr).cumsum(), label='calving') +ax[1,0].plot(yr, (FMF*dyr).cumsum(), label='facemelt') +ax[1,0].plot(yr, ( (SMB+BMB+calv+FMF) * dyr).cumsum(), "--", label='total budget') +ax[1,0].legend(loc='best', prop={'size': 6}) +ax[1,0].set_ylabel('Cumulative mass change (Gt)') + +ax[2,0].semilogy(yr, np.abs( ( (dvol) - (SMB+BMB+calv+FMF) ) / dvol ) ) +ax[2,0].set_ylabel('fractional error') + +#======================== +# 2. Grounded mass budget +#======================== # get fields and plot stuff volGround = f.variables['groundedIceVolume'][:] volGround = volGround * rhoi / 1.0e12 dvolGround = np.zeros(yr.shape) dvolGround[1:] = (volGround[1:]-volGround[:-1]) / dyr[1:] -ax.plot(yr, dvolGround, 'k', linewidth=3, label="grounded mass change") +ax[0,1].plot(yr, dvolGround, 'k', linewidth=3, label="mass change") +# --- time-step-wise mass change --- SMBg = f.variables['totalGroundedSfcMassBal'][:] / 1.0e12 -ax.plot(yr, SMBg, label="grounded SMB") +ax[0,1].plot(yr, SMBg, label="SMB") BMBg = f.variables['totalGroundedBasalMassBal'][:] / 1.0e12 -ax.plot(yr, BMBg, label="grounded BMB") +ax[0,1].plot(yr, BMBg, label="BMB") + +calvg = -f.variables['totalGroundedCalvingFlux'][:] / 1.0e12 +ax[0,1].plot(yr, calvg, label='calv') + +FMFg = -f.variables['totalGroundedFaceMeltingFlux'][:] / 1.0e12 +ax[0,1].plot(yr, FMFg, label='facemelt') + +GLflux = -f.variables['groundingLineFlux'][:]/1.0e12 +ax[0,1].plot(yr, GLflux, label="GL flux") + +GLMigrationflux = -f.variables['groundingLineMigrationFlux'][:]/1.0e12 +ax[0,1].plot(yr, GLMigrationflux, label="GL migration flux") + +ax[0,1].plot(yr, SMBg+BMBg+calv+FMF+GLflux+GLMigrationflux, "--", label="total") + +ax[0,1].legend(loc='best', prop={'size': 6}) + +# --- Figure: cumulative mass change --- +ax[1,1].set_xlabel('Year') +ax[1,1].set_ylabel('Cumulative mass change (Gt)') + +ax[1,1].plot(yr, volGround - volGround[0], 'k', linewidth=3, label='total mass change') +ax[1,1].plot(yr, (SMBg*dyr).cumsum(), label="SMB") +ax[1,1].plot(yr, (BMBg*dyr).cumsum(), label="BMB") + +ax[1,1].plot(yr, (calv*dyr).cumsum(), label='calving') +ax[1,1].plot(yr, (FMF*dyr).cumsum(), label='facemelt') +ax[1,1].plot(yr, (GLflux*dyr).cumsum(), label="GL flux") +ax[1,1].plot(yr, (GLMigrationflux*dyr).cumsum(), label="GL Migration flux") +ax[1,1].plot(yr, ( (SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux) * dyr).cumsum(), "--", label='total budget') + +ax[1,1].legend(loc='best', prop={'size': 6}) + +ax[2,1].semilogy(yr, np.abs( ( (dvolGround) - (SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux) ) / dvolGround ) ) + + +#======================== +# 3. Floating mass budget +#======================== + +# get fields and plot stuff +volFloat = f.variables['floatingIceVolume'][:] +volFloat = volFloat * rhoi / 1.0e12 +dvolFloat = np.zeros(yr.shape) +dvolFloat[1:] = (volFloat[1:]-volFloat[:-1]) / dyr[1:] +ax[0,2].plot(yr, dvolFloat, 'k', linewidth=3, label="mass change") + +SMBf = f.variables['totalFloatingSfcMassBal'][:] / 1.0e12 +ax[0,2].plot(yr, SMBf, label="SMB") + +BMBf = f.variables['totalFloatingBasalMassBal'][:] / 1.0e12 +ax[0,2].plot(yr, BMBf, label="BMB") + +calvf = -f.variables['totalFloatingCalvingFlux'][:] / 1.0e12 +ax[0,2].plot(yr, calvf, label='calv') + +FMFf = -f.variables['totalFloatingFaceMeltingFlux'][:] / 1.0e12 +ax[0,2].plot(yr, FMFf, label='facemelt') GLflux = f.variables['groundingLineFlux'][:]/1.0e12 -ax.plot(yr, -GLflux, label="GL flux") +ax[0,2].plot(yr, GLflux, label="GL flux") GLMigrationflux = f.variables['groundingLineMigrationFlux'][:]/1.0e12 -ax.plot(yr, -GLMigrationflux, label="GL migration flux") +ax[0,2].plot(yr, GLMigrationflux, label="GL migration flux") +ax[0,2].plot(yr, SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux, "--", label="total") -ax.plot(yr, SMBg+BMBg, "--", label="SMB+BMB") -ax.plot(yr, SMBg+BMBg-GLflux, "--", label="SMB+BMB+GLf") -ax.plot(yr, SMBg+BMBg-GLflux-GLMigrationflux, "--", label="SMB+BMB+GLf+GLMf") +ax[0,2].legend(loc='best', prop={'size': 6}) -plt.legend(loc='best', prop={'size': 6}) -plt.tight_layout() +# --- cumulative mass change --- +ax[1,2].plot(yr, volFloat - volFloat[0], 'k', linewidth=3, label='total mass change') +ax[1,2].plot(yr, (SMBf*dyr).cumsum(), label="SMB") +ax[1,2].plot(yr, (BMBf*dyr).cumsum(), label="BMB") -# --- Figure: cumulative mass change --- -#fig2 = plt.figure(2, figsize=(6,5), facecolor='w') -ax = fig.add_subplot(2, 1, 2) -plt.xlabel('Year') -plt.ylabel('Cumulative grounded mass change (Gt)') -plt.grid() - -plt.plot(yr, volGround - volGround[0], 'k', linewidth=3, label='grounded mass') -plt.plot(yr, (SMBg*dyr).cumsum(), label="grounded SMB") -plt.plot(yr, (BMBg*dyr).cumsum(), label="grounded BMB") -plt.plot(yr, -1.0*(GLflux*dyr).cumsum(), label="GL flux") -plt.plot(yr, -1.0*(GLMigrationflux*dyr).cumsum(), label="GL Migration flux") -plt.plot(yr, ( (SMBg+BMBg) * dyr).cumsum(), "--", label='SMB+BMB') -plt.plot(yr, ( (SMBg+BMBg-GLflux) * dyr).cumsum(), "--", label='SMB+BMB+GLflux') -plt.plot(yr, ( (SMBg+BMBg-GLflux-GLMigrationflux) * dyr).cumsum(), "--", label='SMB+BMB+GLf+GLMf') -#plt.plot(yr, dareag.cumsum(), 'k', label="mass change due to change in grounded area") - -plt.legend(loc='best', prop={'size': 6}) -plt.tight_layout() - -print("Plotting complete.") +ax[1,2].plot(yr, (calvf*dyr).cumsum(), label='calving') +ax[1,2].plot(yr, (FMFf*dyr).cumsum(), label='facemelt') +ax[1,2].plot(yr, (GLflux*dyr).cumsum(), label="GL flux") +ax[1,2].plot(yr, (GLMigrationflux*dyr).cumsum(), label="GL Migration flux") +ax[1,2].plot(yr, ( (SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux) * dyr).cumsum(), "--", label='total budget') + +ax[1,2].legend(loc='best', prop={'size': 6}) + +ax[2,2].semilogy(yr, np.abs( ( (dvolFloat) - (SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux) ) / dvolFloat ) ) + +for plotAx in ax.ravel(): + plotAx.grid('on') +ax[2,0].set_xlabel('yr') +ax[2,1].set_xlabel('yr') +ax[2,2].set_xlabel('yr') +ax[0,0].set_title('Total budget') +ax[0,1].set_title('Grounded budget') +ax[0,2].set_title('Floating budget') plt.show() f.close() From 3c716e96995435894d1ad6f61594fde5e5d768bd Mon Sep 17 00:00:00 2001 From: Trevor Ray Hillebrand Date: Wed, 18 May 2022 17:37:04 -0600 Subject: [PATCH 2/3] Correct grounded budgets Previous commit used total calving and facemelting on plot instead of just grounded components. --- landice/output_processing_li/plot_mass_balance.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/landice/output_processing_li/plot_mass_balance.py b/landice/output_processing_li/plot_mass_balance.py index 43d10bc94..92b400737 100755 --- a/landice/output_processing_li/plot_mass_balance.py +++ b/landice/output_processing_li/plot_mass_balance.py @@ -107,20 +107,17 @@ GLMigrationflux = -f.variables['groundingLineMigrationFlux'][:]/1.0e12 ax[0,1].plot(yr, GLMigrationflux, label="GL migration flux") -ax[0,1].plot(yr, SMBg+BMBg+calv+FMF+GLflux+GLMigrationflux, "--", label="total") +ax[0,1].plot(yr, SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux, "--", label="total") ax[0,1].legend(loc='best', prop={'size': 6}) # --- Figure: cumulative mass change --- -ax[1,1].set_xlabel('Year') -ax[1,1].set_ylabel('Cumulative mass change (Gt)') - ax[1,1].plot(yr, volGround - volGround[0], 'k', linewidth=3, label='total mass change') ax[1,1].plot(yr, (SMBg*dyr).cumsum(), label="SMB") ax[1,1].plot(yr, (BMBg*dyr).cumsum(), label="BMB") -ax[1,1].plot(yr, (calv*dyr).cumsum(), label='calving') -ax[1,1].plot(yr, (FMF*dyr).cumsum(), label='facemelt') +ax[1,1].plot(yr, (calvg*dyr).cumsum(), label='calving') +ax[1,1].plot(yr, (FMFg*dyr).cumsum(), label='facemelt') ax[1,1].plot(yr, (GLflux*dyr).cumsum(), label="GL flux") ax[1,1].plot(yr, (GLMigrationflux*dyr).cumsum(), label="GL Migration flux") ax[1,1].plot(yr, ( (SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux) * dyr).cumsum(), "--", label='total budget') From 383ed644aa4aba305b59744aba1cc7c0be02324a Mon Sep 17 00:00:00 2001 From: Trevor Ray Hillebrand Date: Thu, 19 May 2022 14:27:00 -0600 Subject: [PATCH 3/3] Add absolute errors Plot absolute errors on another vertical axis on same panel as fractional errors. --- .../output_processing_li/plot_mass_balance.py | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/landice/output_processing_li/plot_mass_balance.py b/landice/output_processing_li/plot_mass_balance.py index 92b400737..7e6dcc582 100755 --- a/landice/output_processing_li/plot_mass_balance.py +++ b/landice/output_processing_li/plot_mass_balance.py @@ -30,8 +30,7 @@ dyr[1:] = yr[1:]-yr[:-1] # ---- Figure: mass change rate --- -fig, ax = plt.subplots(3,3) - +fig, ax = plt.subplots(3,3, figsize=(15,12)) #===================== # 1. Total mass budget #===================== @@ -58,7 +57,8 @@ # Grounding line flux and grounding line migration flux # do not come into the global mass budget -ax[0,0].plot(yr, SMB+BMB+calv+FMF, "--", label="total") +tot = SMB+BMB+calv+FMF +ax[0,0].plot(yr, tot, "--", label="total") ax[0,0].legend(loc='best', prop={'size': 6}) ax[0,0].set_ylabel('Mass change (Gt)') @@ -70,14 +70,15 @@ ax[1,0].plot(yr, (calv*dyr).cumsum(), label='calving') ax[1,0].plot(yr, (FMF*dyr).cumsum(), label='facemelt') -ax[1,0].plot(yr, ( (SMB+BMB+calv+FMF) * dyr).cumsum(), "--", label='total budget') +ax[1,0].plot(yr, (tot * dyr).cumsum(), "--", label='total budget') ax[1,0].legend(loc='best', prop={'size': 6}) ax[1,0].set_ylabel('Cumulative mass change (Gt)') -ax[2,0].semilogy(yr, np.abs( ( (dvol) - (SMB+BMB+calv+FMF) ) / dvol ) ) -ax[2,0].set_ylabel('fractional error') - +ax[2,0].semilogy(yr, np.abs( (tot - dvol ) / dvol ) ) +ax[2,0].set_ylabel('fractional error', color='tab:blue') +absErrAxTot = ax[2,0].twinx() +absErrAxTot.plot(yr, tot - dvol, color='tab:orange') #======================== # 2. Grounded mass budget #======================== @@ -107,11 +108,13 @@ GLMigrationflux = -f.variables['groundingLineMigrationFlux'][:]/1.0e12 ax[0,1].plot(yr, GLMigrationflux, label="GL migration flux") -ax[0,1].plot(yr, SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux, "--", label="total") +grndTot = SMBg+calvg+BMBg+FMFg+GLflux+GLMigrationflux +ax[0,1].plot(yr, grndTot, "--", label="total") ax[0,1].legend(loc='best', prop={'size': 6}) # --- Figure: cumulative mass change --- + ax[1,1].plot(yr, volGround - volGround[0], 'k', linewidth=3, label='total mass change') ax[1,1].plot(yr, (SMBg*dyr).cumsum(), label="SMB") ax[1,1].plot(yr, (BMBg*dyr).cumsum(), label="BMB") @@ -120,13 +123,13 @@ ax[1,1].plot(yr, (FMFg*dyr).cumsum(), label='facemelt') ax[1,1].plot(yr, (GLflux*dyr).cumsum(), label="GL flux") ax[1,1].plot(yr, (GLMigrationflux*dyr).cumsum(), label="GL Migration flux") -ax[1,1].plot(yr, ( (SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux) * dyr).cumsum(), "--", label='total budget') +ax[1,1].plot(yr, ( (grndTot) * dyr).cumsum(), "--", label='total budget') ax[1,1].legend(loc='best', prop={'size': 6}) +ax[2,1].semilogy(yr, np.abs( (grndTot - dvolGround) / dvolGround ) ) -ax[2,1].semilogy(yr, np.abs( ( (dvolGround) - (SMBg+BMBg+calvg+FMFg+GLflux+GLMigrationflux) ) / dvolGround ) ) - - +absErrAxGrnd = ax[2,1].twinx() +absErrAxGrnd.plot(yr, grndTot - dvolGround, color='tab:orange') #======================== # 3. Floating mass budget #======================== @@ -150,12 +153,12 @@ FMFf = -f.variables['totalFloatingFaceMeltingFlux'][:] / 1.0e12 ax[0,2].plot(yr, FMFf, label='facemelt') -GLflux = f.variables['groundingLineFlux'][:]/1.0e12 -ax[0,2].plot(yr, GLflux, label="GL flux") +ax[0,2].plot(yr, -GLflux, label="GL flux") + +ax[0,2].plot(yr, -GLMigrationflux, label="GL migration flux") -GLMigrationflux = f.variables['groundingLineMigrationFlux'][:]/1.0e12 -ax[0,2].plot(yr, GLMigrationflux, label="GL migration flux") -ax[0,2].plot(yr, SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux, "--", label="total") +fltTot = SMBf+BMBf+FMFf+calvf-GLflux-GLMigrationflux +ax[0,2].plot(yr, fltTot, "--", label="total") ax[0,2].legend(loc='best', prop={'size': 6}) @@ -166,13 +169,17 @@ ax[1,2].plot(yr, (calvf*dyr).cumsum(), label='calving') ax[1,2].plot(yr, (FMFf*dyr).cumsum(), label='facemelt') -ax[1,2].plot(yr, (GLflux*dyr).cumsum(), label="GL flux") -ax[1,2].plot(yr, (GLMigrationflux*dyr).cumsum(), label="GL Migration flux") -ax[1,2].plot(yr, ( (SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux) * dyr).cumsum(), "--", label='total budget') +ax[1,2].plot(yr, (-GLflux*dyr).cumsum(), label="GL flux") +ax[1,2].plot(yr, (-GLMigrationflux*dyr).cumsum(), label="GL Migration flux") +ax[1,2].plot(yr, (fltTot * dyr).cumsum(), "--", label='total budget') ax[1,2].legend(loc='best', prop={'size': 6}) -ax[2,2].semilogy(yr, np.abs( ( (dvolFloat) - (SMBf+BMBf+calvf+FMFf+GLflux+GLMigrationflux) ) / dvolFloat ) ) +ax[2,2].semilogy(yr, np.abs( (fltTot - dvolFloat) / dvolFloat ) ) + +absErrAxFlt = ax[2,2].twinx() +absErrAxFlt.plot(yr, fltTot - dvolFloat, color='tab:orange') +absErrAxFlt.set_ylabel('Absolute error (Gt; budget - true)', color='tab:orange') for plotAx in ax.ravel(): plotAx.grid('on') @@ -183,5 +190,7 @@ ax[0,0].set_title('Total budget') ax[0,1].set_title('Grounded budget') ax[0,2].set_title('Floating budget') + +fig.subplots_adjust(wspace=0.5) plt.show() f.close()