Import libraries¶
In [9]:
import time
import matplotlib as plt
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import bw2calc as bc
import bw2io as bi
import bw2data as bd
import os
from premise import *
Function to plot energy sector mixes¶
In [10]:
import pandas as pd
import matplotlib.pyplot as plt
def plot_energy_contribution(region='World', sector='electricity', relative=True):
# Load the DataFrame from the Excel file
df = pd.read_excel('tiam-ucl_all.xlsx')
# Define the columns to be removed
columns_to_remove = [2005, 2010, 2015, 2020, 2060, 2070, 2080, 2090, 2100]
columns_to_remove = [str(column) for column in columns_to_remove]
# Remove the specified columns from the DataFrame
df = df.drop(columns=columns_to_remove, errors='ignore')
# Filter the DataFrame for rows where the 'Region' column matches the specified region
df_region = df[df['Region'] == region]
# Define energy categories and color schemes for each sector
if sector == 'electricity':
df_filtered = df_region[df_region['Variable'].str.startswith(('Electricity|', 'Secondary Energy|Electricity|'))]
energy_categories = {
'Biomass': [
'Secondary Energy|Electricity|Biomass combustion|w/o CCS',
'Secondary Energy|Electricity|Biomass existing capacity|w/o CCS',
'Secondary Energy|Electricity|Biomass gasification|w/o CCS',
'Electricity|Biogas|w/o CCS',
'Electricity|Biomass CHP|w/o CCS',
'Secondary Energy|Electricity|MSW|w/o CCS'
],
'Biomass w CCS': [
'Secondary Energy|Electricity|Biomass combustion|w CCS',
'Secondary Energy|Electricity|Biomass gasification|w CCS'
],
'Coal': [
'Secondary Energy|Electricity|CHP existing coal|w/o CCS',
'Secondary Energy|Electricity|Coal IGCC|w/o CCS',
'Secondary Energy|Electricity|Co-firing coal:biomass 50:50|w/o CCS',
'Secondary Energy|Electricity|Co-firing coal:biomass 80:20|w/o CCS',
'Secondary Energy|Electricity|Existing coal generation|w/o CCS',
'Secondary Energy|Electricity|Ultra-supercritical pulverised coal|w/o CCS',
'Secondary Energy|Electricity|Supercritical pulverised coal|w/o CCS'
],
'Coal w CCS': [
'Secondary Energy|Electricity|Coal IGCC|w CCS',
'Secondary Energy|Electricity|Ultra-supercritical pulverised coal|w CCS'
],
'Gas': [
'Secondary Energy|Electricity|Gas CCGT|w/o CCS',
'Secondary Energy|Electricity|Gas CHP|w/o CCS',
'Secondary Energy|Electricity|Gas Fuel cells|w/o CCS',
'Secondary Energy|Electricity|Gas turbine|w/o CCS',
'Secondary Energy|Electricity|Existing gas generation|w/o CCS'
],
'Gas w CCS': [
'Secondary Energy|Electricity|Gas CCGT|w CCS'
],
'Geothermal': [
'Secondary Energy|Electricity|Geothermal'
],
'Hydro': [
'Secondary Energy|Electricity|Impoundment hydro',
'Secondary Energy|Electricity|Tidal',
'Secondary Energy|Electricity|ROR hydro'
],
'Nuclear': [
'Secondary Energy|Electricity|Nuclear',
'Secondary Energy|Electricity|Nuclear Fusion'
],
'Solar': [
'Secondary Energy|Electricity|Concentrated Solar CSP centralised',
'Secondary Energy|Electricity|Concentrated Solar PV centralised',
'Secondary Energy|Electricity|Concentrated Solar PV decentralised'
],
'Wind': [
'Secondary Energy|Electricity|Offshore wind centralised',
'Secondary Energy|Electricity|Onshore wind centralised'
],
'Oil': [
'Secondary Energy|Electricity|Existing oil electric generation|w/o CCS',
'Secondary Energy|Electricity|Oil CHP|w/o CCS',
'Secondary Energy|Electricity|Oil steam|w/o CCS'
],
'Storage': [
'Secondary Energy|Electricity|Storage'
]
}
colors = {
'Biomass': '#136729', # Light green
'Biomass w CCS': '#39B56B', # Green
'Coal': '#534A4E', # Dark red
'Coal w CCS': '#9A7F70', # Lighter red
'Gas': '#843033', # Greyish
'Gas w CCS': '#CA676F', # Light greyish
'Geothermal': '#882255', # Darkish blue
'Hydro': '#4C69B2', # Blue
'Nuclear': '#AA4499', # Purple pinkish
'Oil': '#878485', # Lightest grey
'Solar': '#F7C179', # Yellow
'Wind': '#51A5B2' # Light blue
}
elif sector == 'steel':
df_filtered = df_region[df_region['Variable'].str.startswith(('Production|Steel|'))]
energy_categories = {
'Primary, BF and BOF': [
'Production|Steel|Primary|BF and BOF 1|w/o CCS',
'Production|Steel|Primary|BF and BOF 2',
'Production|Steel|Primary|BF and BOF 3|w/o CCS',
'Production|Steel|Primary|BF and BOF 4',
],
'Primary, BF and BOF w CCS': [
'Production|Steel|Primary|BF and BOF 1|w CCS',
'Production|Steel|Primary|BF and BOF 3|w CCS',
],
'Secondary, DRH2 and EAF': [
'Production|Steel|Secondary|DRH2 and EAF',],
'Secondary, DRI and EAF': [
'Production|Steel|Secondary|DRI and EAF 1',
'Production|Steel|Secondary|DRI and EAF 2|w/o CCS',
'Production|Steel|Secondary|DRI and EAF 3',
'Production|Steel|Secondary|DRI and EAF 2|w CCS'],
'Secondary, EAF': [
'Production|Steel|Secondary|EAF 1',
'Production|Steel|Secondary|EAF 2',
'Production|Steel|Secondary|EAF 3'
],
}
colors = {
'Primary, BF and BOF': '#843033',
'Primary, BF and BOF w CCS': '#CA676F',
'Secondary, DRH2 and EAF': '#51A5B2',
'Secondary, DRI and EAF': '#AA4499',
'Secondary, EAF': '#4C69B2'
}
elif sector == 'diesel':
df_filtered = df_region[df_region['Variable'].str.contains(r'^Secondary Energy\|Liquids.*diesel', case=False, regex=True)]
energy_categories = {
'Synthetic': [
'Secondary Energy|Liquids|Biomass residues|FT Diesel|w CCS',
'Secondary Energy|Liquids|Biomass residues|FT Diesel|w/o CCS',
'Secondary Energy|Liquids|Coal|FT Diesel|w CCS',
'Secondary Energy|Liquids|Coal|FT Diesel|w/o CCS',
'Secondary Energy|Liquids|Hydrogen|Diesel',
'Secondary Energy|Liquids|Natural Gas|FT Diesel|w CCS',
'Secondary Energy|Liquids|Natural Gas|FT Diesel|w/o CCS',
],
'Biomass': [
'Secondary Energy|Liquids|Biomass|Biodiesel|w CCS',
'Secondary Energy|Liquids|Biomass|Biodiesel|w/o CCS',
],
'Fossil': [
'Secondary Energy|Liquids|Oil|Diesel',],
}
colors = {
'Synthetic': '#AA4499',
'Biomass': '#39B56B',
'Fossil': '#843033',
}
elif sector == 'hydrogen':
df_filtered = df_region[df_region['Variable'].str.startswith(('Secondary Energy|Hydrogen'))]
energy_categories = {
'Biomass': [
'Secondary Energy|Hydrogen|Biomass|w/o CCS',
],
'Biomass w CCS': [
'Secondary Energy|Hydrogen|Biomass|w CCS',
],
'Fossil': [
'Secondary Energy|Hydrogen|Coal|w/o CCS',
'Secondary Energy|Hydrogen|Natural Gas|w/o CCS'
],
'Fossil w CCS': [
'Secondary Energy|Hydrogen|Coal|w CCS',
],
'Electrolysis': [
'Secondary Energy|Hydrogen|Electrolysis',
],
}
colors = {
'Biomass': '#136729',
'Biomass w CCS': '#39B56B',
'Fossil': '#843033',
'Fossil w CCS': '#CA676F',
'Electrolysis': '#4C69B2',
}
else:
raise ValueError("Invalid sector specified. Choose from 'electricity', 'steel', 'diesel', or 'hydrogen'.")
# Drop unnecessary columns
df_filtered.drop(['Model', 'Region', 'Unit'], axis=1, inplace=True)
# Replace 'Variable' entries according to the new categories
for category, variables in energy_categories.items():
df_filtered.loc[df_filtered['Variable'].isin(variables), 'Variable'] = category
# Group by 'Scenario' and 'Variable', then sum all numerical columns
df_grouped = df_filtered.groupby(['Scenario', 'Variable']).sum().reset_index()
# Define scenarios and corresponding titles
scenarios = ["SSP2-RCP60", "SSP2-RCP45", "SSP2-RCP26", "SSP2-RCP19"]
titles = ["No climate action", "Baseline (NDCs)", "Ambitious (< 2C)", "Very ambitious (< 1.5C)"]
# Filter the scenarios of interest
filtered_df = df_grouped[df_grouped['Scenario'].isin(scenarios)]
# Set the list of years to plot as x-axis values
years = [2025, 2030, 2035, 2040, 2045, 2050]
# Define larger font sizes for better readability
title_fontsize = 16
label_fontsize = 15
legend_fontsize = 14
tick_fontsize = 13
# Create a figure with subplots for each scenario
fig, axs = plt.subplots(1, len(scenarios), figsize=(12, 4), sharey=True)
# Plot each scenario
for idx, (scenario, title) in enumerate(zip(scenarios, titles)):
# Filter the data for the current scenario
scenario_data = filtered_df[filtered_df['Scenario'] == scenario]
# Prepare the data for plotting
labels = scenario_data['Variable'].unique()
data_to_plot = [scenario_data[scenario_data['Variable'] == label][years].iloc[0].tolist() for label in labels if label != 'Storage']
color_sequence = [colors[label] for label in labels if label != 'Storage']
if relative:
# Calculate total per year and normalize data for percentage contribution
total_per_year = scenario_data[years].sum(axis=0)
data_to_plot = [(data / total_per_year * 100).tolist() for data in data_to_plot]
# Plot percentage contribution
axs[idx].stackplot(years, data_to_plot, labels=[label for label in labels if label != 'Storage'], colors=color_sequence)
axs[idx].set_ylabel('Percentage (%)' if idx == 0 else '', fontsize=label_fontsize)
# Plot Storage as a line
if 'Storage' in labels:
storage_data = scenario_data[scenario_data['Variable'] == 'Storage'][years].iloc[0]
storage_percentage = (storage_data / total_per_year * 100).tolist()
axs[idx].plot(years, storage_percentage, label='Storage', color='black', linewidth=2)
else:
# Plot actual production volume
axs[idx].stackplot(years, data_to_plot, labels=[label for label in labels if label != 'Storage'], colors=color_sequence)
axs[idx].set_ylabel('PJ/year' if idx == 0 else '', fontsize=label_fontsize)
# Plot Storage as a line
if 'Storage' in labels:
storage_data = scenario_data[scenario_data['Variable'] == 'Storage'][years].iloc[0]
axs[idx].plot(years, storage_data, label='Storage', color='black', linewidth=2)
axs[idx].set_title(title, fontsize=title_fontsize)
axs[idx].tick_params(axis='x', labelsize=tick_fontsize, rotation=45)
axs[idx].tick_params(axis='y', labelsize=tick_fontsize)
axs[idx].set_xlim(min(years), max(years))
# Set x-ticks to show every five years
axs[idx].set_xticks(years)
axs[idx].set_xticklabels(years, fontsize=tick_fontsize)
# Add a legend to the main figure
handles, labels = axs[-1].get_legend_handles_labels()
fig.legend(handles, labels, loc='upper right', bbox_to_anchor=(1.22, 0.95), fontsize=legend_fontsize, frameon=False)
# Adjust layout and spacing between subplots
plt.subplots_adjust(wspace=0.01) # Decrease this value to reduce the space between plots
plt.tight_layout() # Adjust padding as needed to avoid clipping
# Save the plot
plt.savefig(f'{region}_{sector}.svg', format='svg', bbox_inches='tight')
plt.show()
Call function and generate plots¶
You can input individual 16-regions of TIAM-UCL, and also sectors for electricity, steel, diesel, and hydrogen
In [25]:
plot_energy_contribution(region='World', sector='electricity', relative=False) #You can switch relative to True if you want a 0-100% contribution version.
C:\Users\js3700\AppData\Local\Temp\ipykernel_20740\1988520216.py:193: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df_filtered.drop(['Model', 'Region', 'Unit'], axis=1, inplace=True)