Great Britain emissions

Here we will explore Great Britain’s emissions and ask whether or not they are on track to meeting their emissions pledges. “On track” will be defined as their current emissions being less than that of a scenario with uniform decrease in emissions.

[1]:
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator
import numpy as np
import pandas as pd
from openclimate import Client
[2]:
# create an openclimate Client object
client = Client()
client.jupyter

Get data

We will the emissions data from UNFCCC to perform this analysis.

[3]:
actor_id = 'GB'
client.emissions_datasets(actor_id)
[3]:
actor_id datasource_id name publisher published URL
0 GB BP:statistical_review_june2022 Statistical Review of World Energy all data, 1... BP 2022-06-01T00:00:00.000Z https://www.bp.com/en/global/corporate/energy-...
1 GB EDGARv7.0:ghg Emissions Database for Global Atmospheric Rese... JRC 2022-01-01T00:00:00.000Z https://edgar.jrc.ec.europa.eu/dataset_ghg70
2 GB GCB2022:national_fossil_emissions:v1.0 Data supplement to the Global Carbon Budget 20... GCP 2022-11-04T00:00:00.000Z https://www.icos-cp.eu/science-and-impact/glob...
3 GB PRIMAP:10.5281/zenodo.7179775:v2.4 PRIMAP-hist_v2.4_no_extrap (scenario=HISTCR) PRIMAP 2022-10-17T00:00:00.000Z https://zenodo.org/record/7179775
4 GB UNFCCC:GHG_ANNEX1:2019-11-08 UNFCCC GHG total without LULUCF, ANNEX I count... UNFCCC 2019-11-08T00:00:00.000Z https://di.unfccc.int/time_series
5 GB carbon_monitor:2022_12_14 Carbon Monitor country CO2 emissions by sector Carbon Monitor 2022-12-14T00:00:00.000Z https://carbonmonitor.org/
6 GB climateTRACE:country_inventory climate TRACE: country inventory climate TRACE 2022-12-02T00:00:00.000Z https://climatetrace.org/inventory
7 GB WRI:climate_watch_historical_ghg:2022 Climate Watch Historical GHG Emissions WRI 2022-01-01T00:00:00.000Z https://www.climatewatchdata.org/ghg-emissions
8 GB openGHGmap:R2021A European OpenGHGMap NTNU 2021-01-01T00:00:00.000Z https://openghgmap.net/data/
9 GB BEIS:UK_regional_GHG:2022-06-30 UK local authority and regional greenhouse gas... BEIS 2022-06-30T00:00:00.000Z https://www.gov.uk/government/statistics/uk-lo...
10 GB IEA:GHG_energy_highlights:2022 Greenhouse Gas Emissions from Energy Highlights IEA 2022-09-01T00:00:00.000Z https://www.iea.org/data-and-statistics/data-p...
[4]:
emissions_datasource = 'UNFCCC:GHG_ANNEX1:2019-11-08'
df_gb = client.emissions(actor_id=actor_id, datasource_id=emissions_datasource)
df_ndc = client.targets(actor_id=actor_id)

# convert tonnes to megatonnes
df_gb['total_emissions'] = df_gb['total_emissions'] / 10**6

# filter ndc by target
filt = df_ndc['datasource_id']=='IGES:NDC_db:10.57405/iges-5005'
df_ndc = df_ndc.loc[filt]

The UK has pledged to reduce their emissions by 68% from 1990 levels by 2030.

[5]:
df_ndc
[5]:
actor_id target_type baseline_year baseline_value target_year target_value target_unit datasource_id
0 GB Absolute emission reduction 1990.0 None 2030 68 percent IGES:NDC_db:10.57405/iges-5005

A quick look at their emissions we see that Great Britain’s emissions have been decreasing for the last thirty years. But this brings up a a couple questions: - Is GB “on-track” to meeting this goal? - Will GB meet their goal if this long-term trend continues?

[6]:
plt.plot(np.array(df_gb['year'], dtype='float64'), np.array(df_gb['total_emissions']))
plt.xlabel('Year')
plt.ylabel('GB Annual Emissions [MtCO$_2$-eq]')
[6]:
Text(0, 0.5, 'GB Annual Emissions [MtCO$_2$-eq]')
../_images/notebooks_great_britain_emissions_9_1.png

Is Great Britain on track?

To answer this question, we will simply ask if the current emissions are less than if the emissions decreased uniformly from baseline to their goal. We will also ask whether GB will meet their goal if the long-term trend contintues. Keep in mind that both of these are crude and imperfect metrics. More sophistiated approaches including using integrated assessment models (IAMs) that incorporate proposed actions.

[7]:
# implementation normal equations for ordinary least squares regression
def linear_eq(df, start_year=None, year_var='year', emissions_var='total_emissions'):
    '''simple linear regression'''
    filt = df[year_var]>=start_year
    x = df.loc[filt, year_var].values
    y = df.loc[filt, emissions_var].values

    # least-squares linear regression
    n = len(x)
    sum_x = np.sum(x)
    sum_y = np.sum(y)
    sum_xy = np.sum(x * y)
    sum_xx = np.sum(x * x)
    mean_x = np.mean(x)
    mean_y = np.mean(y)

    # calculate coefficients
    b = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x**2)
    a = mean_y - b * mean_x

    # Make predictions using the regression line
    pred = lambda x: a + b * x
    return {'equation':pred, 'slope':b, 'intercept':a}
[8]:
baseline_year = df_ndc['baseline_year'].values[0]
current_year = df_gb['year'].max()
net_zero_year = 2050
target_year = df_ndc['target_year'].values[0]
target_value = int(df_ndc['target_value'])
target_percent = float(df_ndc['target_value'].squeeze())/100

pred = linear_eq(df_gb, start_year=baseline_year)
X_pred = np.arange(baseline_year, target_year + 1)
Y_pred = pred['equation'](X_pred)

# get baseline and target emissions
filt = df_gb['year'] == baseline_year
baseline_emissions = df_gb.loc[filt,'total_emissions']
target_emissions = df_gb.loc[filt,'total_emissions'] * (100 - target_value)/100
net_zero_emissions = 0

# current emissions
filt = df_gb['year'] == current_year
current_emissions = df_gb.loc[filt,'total_emissions']

# average annual reduction needed to achieve goal:
avg_rate = round(((baseline_emissions - target_emissions) / (target_year - baseline_year + 1)).values[0])
nz_rate = round(((baseline_emissions - net_zero_emissions) / (net_zero_year - baseline_year + 1)).values[0])

year_target_achieved = round((target_emissions - pred['intercept']) / pred['slope'])
print(f"To acheive goal, average rate of reduction needs to be {abs(avg_rate):.0f} MT/yr")
print(f"To acheive net-zero goal, average rate of reduction needs to be {abs(nz_rate):.0f} MT/yr")
print(f"GB reducing emissions by about {abs(pred['slope']):.0f} MT/yr")
print(f'Target emissions of {int(target_emissions.values)} MT/yr will be acheived around {int(year_target_achieved.values)}')
To acheive goal, average rate of reduction needs to be 13 MT/yr
To acheive net-zero goal, average rate of reduction needs to be 13 MT/yr
GB reducing emissions by about 12 MT/yr
Target emissions of 255 MT/yr will be acheived around 2037
/tmp/ipykernel_1447/3089394390.py:5: FutureWarning: Calling int on a single element Series is deprecated and will raise a TypeError in the future. Use int(ser.iloc[0]) instead
  target_value = int(df_ndc['target_value'])

From this quick analysis, we can see that GB maybe be slightly off track to meeting their goals

Plot of emissions and pledges

[9]:
fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111)

ax.plot(np.array(df_gb['year']), np.array(df_gb['total_emissions']),
        linewidth=4,
        label='Great Britian annual emissions',
       color=[0.0,0.0,0.0])

ax.plot(X_pred, Y_pred, '--',
        linewidth=2,
        color=[0.6,0.6,0.6],
       label='Linear trend')

ax.plot(np.array([baseline_year, float(target_year)]), np.array([float(baseline_emissions), float(target_emissions)]),
        '-',
        linewidth=2,
        color=[0.6,0.6,0.6],
       label='linear decrease')


ax.plot([df_ndc['baseline_year'], df_ndc['target_year']],
        [target_emissions, target_emissions],
        '-.',
        linewidth=1,
        color=[0.5,0.5,0.5],
       label='target emissions')

ylim = [200, 850]
ax.set_ylim(ylim)
ax.set_xlim([1990, 2035])

# Turn off the display of all ticks.
ax.tick_params(which='both',     # Options for both major and minor ticks
               top='off',        # turn off top ticks
               left='off',       # turn off left ticks
               right='off',      # turn off right ticks
               bottom='off')     # turn off bottom ticks

# Remove x tick marks
plt.setp(ax.get_xticklabels(), rotation=0)

# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)

# Only show ticks on the left and bottom spines
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')

# major/minor tick lines
ax.xaxis.set_minor_locator(AutoMinorLocator(5))
ax.grid(axis='y',
        which='major',
        color=[0.8, 0.8, 0.8], linestyle='-')

bline_emissions = baseline_emissions.values[0]
ylim_achieved = [(bline_emissions - ylim[0])/ (bline_emissions*target_percent)*100,
                 (bline_emissions - ylim[1])/ (bline_emissions*target_percent)*100]
ax2 = ax.twinx()
ax2.set_ylim(ylim_achieved)

# Hide the right and top spines
ax2.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.spines['bottom'].set_visible(False)

# Only show ticks on the left and bottom spines
ax2.yaxis.set_ticks_position('right')
ax2.xaxis.set_ticks_position('bottom')
ax2.yaxis.set_tick_params(size=0)

# Set the y-axis tick labels using a FixedFormatter
vals = ax2.get_yticks()
ax2.yaxis.set_major_locator(plt.FixedLocator(vals))
ax2.set_yticklabels([f"{int(x)}%" for x in vals])

ax2.set_ylabel("Percent achieved", fontsize=12)
ax.set_ylabel("Emissions (MtCO$_2$-eq)", fontsize=12)
ax.legend(loc='upper right', frameon=False)
/tmp/ipykernel_1447/3965963511.py:14: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  ax.plot(np.array([baseline_year, float(target_year)]), np.array([float(baseline_emissions), float(target_emissions)]),
[9]:
<matplotlib.legend.Legend at 0x7f4e33696130>
../_images/notebooks_great_britain_emissions_15_2.png

Now let’s do the same for net zero

[10]:
pred = linear_eq(df_gb, start_year=baseline_year)
X_pred = np.arange(baseline_year, net_zero_year + 1)
Y_pred = pred['equation'](X_pred)
[11]:
fig = plt.figure(figsize=(6, 6))
ax = fig.add_subplot(111)

ax.plot(np.array(df_gb['year']), np.array(df_gb['total_emissions']),
        linewidth=4,
        label='Great Britian annual emissions',
       color=[0.0,0.0,0.0])

ax.plot(X_pred, Y_pred, '--',
        linewidth=2,
        color=[0.6,0.6,0.6],
       label='Linear trend')

ax.plot(np.array((baseline_year, float(net_zero_year))), np.array((float(baseline_emissions), net_zero_emissions)),
        '-',
        linewidth=2,
        color=[0.6,0.6,0.6],
       label='linear decrease')

ylim = [0, 850]
ax.set_ylim(ylim)
ax.set_xlim([1990, 2055])

# Turn off the display of all ticks.
ax.tick_params(which='both',     # Options for both major and minor ticks
               top='off',        # turn off top ticks
               left='off',       # turn off left ticks
               right='off',      # turn off right ticks
               bottom='off')     # turn off bottom ticks

# Remove x tick marks
plt.setp(ax.get_xticklabels(), rotation=0)

# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)

# Only show ticks on the left and bottom spines
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')

# major/minor tick lines
ax.xaxis.set_minor_locator(AutoMinorLocator(5))
ax.grid(axis='y',
        which='major',
        color=[0.8, 0.8, 0.8], linestyle='-')

bline_emissions = baseline_emissions.values[0]
ylim_achieved = [(bline_emissions - ylim[0])/ (bline_emissions*target_percent)*100,
                 (bline_emissions - ylim[1])/ (bline_emissions*target_percent)*100]

ax.set_ylabel("Emissions (MtCO$_2$e)", fontsize=12)
ax.legend(loc='upper right', frameon=False)
/tmp/ipykernel_1447/2911775156.py:14: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  ax.plot(np.array((baseline_year, float(net_zero_year))), np.array((float(baseline_emissions), net_zero_emissions)),
[11]:
<matplotlib.legend.Legend at 0x7f4e33612f40>
../_images/notebooks_great_britain_emissions_18_2.png

In general, the emissions have been trending in the right direction over the past 30 years, but emissions will have to decline at an increasing rate in order to achieve these goals.