Main Content

Analyze Transition Scenarios for Climate-Related Financial Risks

This example shows how to visualize transition scenarios to understand climate-related risks to the economy and financial systems.

Background

In late 2020, the Bank of Canada initiated a project to understand the climate impact on financial systems of Canada and the United States. The resulting data set [1] is the basis of the Bank of Canada report "Transition Scenarios for Analyzing Climate-Related Financial Risk" [2]. From this project, data for three climate scenarios captures the evolution of the global economy. These three climate scenarios are in the BankOfCanadaClimateScenarioData.mat file. The Bank of Canada report summarizes the global economy by ten emission-intensive sectors across eight global regions from 2020 to 2050. A fourth scenario is the benchmark scenario and reflects the climate policies of 2019, which mitigates effects due to the COVID-19 pandemic that started in 2020.

This example consists of two parts that relate to section 2 and section 4 of the Bank of Canada report.

Climate Impact of Green House Gas Emissions, uses MATLAB® code to re-create the graphs for each scenario that show the progress in the mitigation of greenhouse gas emissions to 2050 and the impact of natural-based solutions such us forests.

Impact of Climate Policies, uses MATLAB® code to re-create the graphs that demonstrate how the scenario policies affect economies at a global, regional, and sectoral level with the focus on Canada and the United States. Graphs in this example provide the following information:

  • Impacts in greenhouse gas emissions due to the increase in shadow carbon price

  • Financial impacts in terms of net income

  • Macroeconomic impacts in terms of gross domestic product (GDP)

For information on the climate impact of different transition scenarios on loan default probabilities, see Measure Transition Risk for Loan Portfolios with Respect to Climate Scenarios.

Impact of Green House Gas Emissions

Climate Scenario Data

The data for this example includes these climate scenarios developed by MIT using the Economic Projection and Policy Analysis (EPPA) Mode in collaboration with the Bank of Canada [3].

  • Baseline (2019 Policies) — Baseline scenario consistent with climate policies in place at the end of 2019

  • Below 2°C Immediate — Immediate policy action scenario to limit average global warming to below 2°C by 2100

  • Below 2°C Delayed — Delayed policy action scenario to limit average global warming to below 2°C by 2100

  • Net-Zero 2050 (1.5°C) — More ambitious immediate policy action scenario to limit average global warming to 1.5°C by 2050 that includes current net-zero commitments by some countries

The climate transition scenario data is provided by the Bank of Canada and is available free of charge at www.bankofcanada.ca. [1]

Load this data, converted to a MAT-file from BankOfCanadaClimateScenarioData.mat.

load BankOfCanadaClimateScenarioData.mat;
head(ClimateTransitionScenarioData);
    k    CL_GEOGRAPHY    CL_SECTOR              CL_VARIABLE                    CL_UNIT                CL_SCENARIO           CL_YEAR    CL_VALUE
    _    ____________    _________    _______________________________    ___________________    ________________________    _______    ________

    1       Canada       National     Carbon price                       US$2014/tCO2e          Baseline (2019 policies)     2020       12.106 
    2       Canada       National     Carbon price                       US$2014/tCO2e          Below 2°C immediate          2020       12.106 
    3       Canada       National     Emissions | total GHG (scope 1)    Million tonnes CO2e    Baseline (2019 policies)     2020       781.04 
    4       Canada       National     Emissions | total GHG (scope 1)    Million tonnes CO2e    Below 2°C immediate          2020       781.04 
    5       Canada       National     Input price | Coal                 Index (2014 = 1)       Baseline (2019 policies)     2020       1.2875 
    6       Canada       National     Input price | Coal                 Index (2014 = 1)       Below 2°C immediate          2020       1.2875 
    7       Canada       National     Input price | Crops                Index (2014 = 1)       Baseline (2019 policies)     2020       1.0031 
    8       Canada       National     Input price | Crops                Index (2014 = 1)       Below 2°C immediate          2020       1.0031 

Use the preprocessBankOfCanadaData helper function to keep only the variables that this example uses for analysis.

 [ClimateTransitionScenarioData, options] = preprocessBankOfCanadaData(ClimateTransitionScenarioData);
 regions = options.regions;

Global Carbon Dioxide Emissions

The following plot shows the impact of each climate scenario in terms of carbon dioxide (CO2) emissions. To understand the various scenarios and their effect on the economy, first you need to explore how each scenario affects the total emissions of carbon dioxide globaly and for each geographic region. The contribution of the forests is important in this analysis because forests can act as both carbon dioxide emitters and carbon dioxide sinks.

Use the plotVariableByCountry function to plot the global greenhouse gas (GHG) emissions.

options = updateOptions(options,1e-3,"Global GHG Emissions","GigaTons/Year of CO_2 Emissions");
plotVariableByCountry('Global',{'Emissions | total GHG (scope 1)'},'Global', options);

As expected, the global GHG emissions for the Baseline (2019 Policies) are increasing. The GHG emissions for the Below 2°C Delayed scenario are increasing in the same manner until 2030, when a reduction in carbon dioxde emissions begins, and then shows a sharp reduction in emissions until 2050. The two other scenarios, Below 2°C Immediate and Net-Zero 2050 (1.5°C) show sharper decreases as the actions for emission mitigation start on 2020. The Net-Zero 2050 (1.5°C) scenario shows a faster decrease in carbon dioxied emissions because the target is an average decrease in global temperature of abour 1.5 degrees by 2050. This target is a more aggressive assumption than the Below 2°C Delayed scenario, which aims to acheive an average decrease in global temperature of about 2 degrees by 2100.

Forestry Carbon Dioxide Emissions and Removal

The global forests, a nature-based solution to cardon dioxide emissions, have a modest but not negligible contribution to the climate scenarios. Observe the impact of removing carbon dioxide emissions from forestry.

% C02 emissions and removal from forestry
baseline_C02FOR = options.baseline(ismember(options.baseline.CL_VARIABLE,'Emissions/removals from forestry'),:);
b2delayed_C02FOR = options.b2delayed(ismember(options.b2delayed.CL_VARIABLE,'Emissions/removals from forestry'),:);
b2immediate_C02FOR = options.b2immediate(ismember(options.b2immediate.CL_VARIABLE,'Emissions/removals from forestry'),:);
netzero2050_C02FOR = options.netzero2050(ismember(options.netzero2050.CL_VARIABLE,'Emissions/removals from forestry'),:);

% Global C02 emissions and removal from forestry
baseline_C02FOR_GLOBAL = sortrows(baseline_C02FOR(ismember(baseline_C02FOR.CL_GEOGRAPHY,'Global'),:),"CL_YEAR","ascend");
b2delayed_C02FOR_GLOBAL = sortrows(b2delayed_C02FOR(ismember(b2delayed_C02FOR.CL_GEOGRAPHY,'Global'),:),"CL_YEAR","ascend");
b2immediate_C02FOR_GLOBAL = sortrows(b2immediate_C02FOR(ismember(b2immediate_C02FOR.CL_GEOGRAPHY,'Global'),:),"CL_YEAR","ascend");
netzero2050_C02FOR_GLOBAL = sortrows(netzero2050_C02FOR(ismember(netzero2050_C02FOR.CL_GEOGRAPHY,'Global'),:),"CL_YEAR","ascend");

figure
x_value = [baseline_C02FOR_GLOBAL.CL_VALUE(1);baseline_C02FOR_GLOBAL.CL_VALUE(end);b2delayed_C02FOR_GLOBAL.CL_VALUE(end);b2immediate_C02FOR_GLOBAL.CL_VALUE(end);netzero2050_C02FOR_GLOBAL.CL_VALUE(end)];
y_value = categorical(["Baseline (2019 Policies) 2020";strcat(["Baseline (2019 Policies)"; "Below 2^oC Delayed"; "Below 2^oC Immediate";"Net-Zero 2050 (1.5^oC)"]," 2050")]);
b = barh(y_value, x_value*1e-3,0.2,'BaseValue',0);
xlabel ("Gigatons per Year of CO_2 Emissions")
title("CO_2 Emissions and Removal from Forestry")
grid on

In 2020, global forests were responsible for 4 gigatons of carbon dioxed emissions. By 2050, the carbon dioxide emissions from global forests are projected to decrease for all scenarios. In the projection for the Below 2°C Immediate and the Net-Zero 2050 (1.5°C) scenarios, the global forests become a natural carbon sink.

Regional Carbon Dioxide Emissions

The following plots present the projected GHG emissions for various regions that you can select using the dropdown control. Use the plotVariableByCountry function to plot the GHG emissions for the selected region.

region = regions(9);
options = updateOptions(options,1,strcat("GHG Emissions in ", region),"Million Tons/Year of CO_2 Emissions");
plotVariableByCountry(region,'Emissions | total GHG (scope 1)',{'National','Global'},options);

The patterns for Canada and the United States are similar to the patterns for the Global GHG Emissions plot. As described in [2], these countries have different climate policies. The climate policies for the United States include:

  • Renewable shares in electricity generation

  • Corporate Average Fuel Economy standards for both passenger and commercial vehicles

The climate policies for Canada [4] include:

  • Phaseout of traditional coal-fired generation of electricity

  • Renewable shares in electricity generation

  • Corporate Average Fuel Economy standards for both passenger and commercial vehicles

  • Regulations on methane emissions

Impact of Climate Policies

Transitioning to low-carbon economies brings significant changes across industries. Industries must move away from fossil-fuel sources to meet their energy demands and adapt noncarbon emitting energy sources like electricity. The plots in this section show the carbon price, GHG emissions, and energy production for the four climate scenarios.

Shadow Carbon Price

To achieve the emission mitigation targets, the model must increase the shadow price of carbon. The shadow carbon price applies a theoretical surcharge per ton of carbon emissions. The more aggressive the scenario, the greater the increase of the carbon price. Use the plotVariableByCountry function to plot the shadow carbon price for the selected region. When region is Global, the "global" price is the GDP-weighted average across geographies. As described in [2], the carbon price is an output in this model. The model aims to reduce emissions by a predetermined amount, incorporating noncarbon tax policies first. Then, the model calculates a shadow carbon price to capture the remaining intensity required in government climate policy to meet the emissions targets. The carbon price is modeled as a tax, where the tax revenue is returned to households as lump-sum transfers in the same period.

region = regions(5);
options = updateOptions(options,1,strcat(region, " Shadow Carbon Price"),"2014 US Dollars/Ton of CO_2 Emissions");
plotVariableByCountry(region,'Carbon price',{'Global','National'},options)

The Baseline (2019 Policies) scenario does not reflect any significant change in the carbon shadow price. On the other hand, the shadow carbon price for the Below 2°C Delayed scenario shows sharp increases because after 2030 countries have to make up for the lost time in mitigating the gas emissions. The Below 2°C Immediate and the Net-Zero 2050 (1.5°C) scenarios have a smoother increase of the shadow carbon price because there is time to achieve the goals by 2100 and 2050, respectively. However, the Net-Zero 2050 (1.5°C) scenario exhibits faster increases of the shadow carbon price as the target of 2050 is more aggressive.

Regional Sectorial Carbon Dioxide Emissions

Use the plotVariableBySector function to show bar graphs for the predicted GHG emissions, by sector, for the four climate scenarios. Low-carbon policies lead to changes in all economies and not only the fossil-fuel economies like coal, oil, natural gas, and refined oil.

region = regions(9);
if (strcmp(region, "Global"))
    options = updateOptions(options,1e-3,strcat(region, " GHG Emissions Per Sector"),"Gigatons/year of CO_2 Emissions");
else
    options = updateOptions(options,1,strcat(region, " GHG Emissions Per Sector"),"Million Tons/Year of CO_2 Emissions");
end
plotVariableBySector(region,{'Emissions | total GHG (scope 1)','Emissions and removals from forestry'},options)

You can see that the contribution of the fossil-fuel sectors to gas emissions significantly lowers by midcentrury as the demand for these products goes down.

The largest impact in the reduction of gas emissions is achieved by the electricity sector. The electricity sector uses low to zero emission technologies like wind and solar. Also many sectors leverage electricity as a substitute to fossil-fuel products. For example, in the commercial transportation sector, you can see the transition to electric vehicles.

For Canada and the United States, the patterns are similar to the Global GHG Emissions plot, but there are some key differences. In Canada, the electricity sector completely substitutes the fossil-fuel products, achieving negative gas emissions by midcentury, while leveraging sophisticated technologies. In the United States, the forest carbon sequestration plays a major role in the carbon budget.

Sectorial Energy Production

Use the plotEnergyBySector function to visualize the use of primary and secondary energy, globally, by sector. Primary energy refers to the amount of energy that a sector delivers and secondary energy refers to the amount of electrical energy each sector generates.

options.energytype='secondary';
if strcmp(options.energytype,"primary")
    options = updateOptions(options,1e-3,"Global Primary Energy","Exajoules");
else
    %1TWh = 0.0036 EJ
    options = updateOptions(options,36*1e-4,"Global Secondary Energy (Electricity Generation)","Exajoules");
end
plotEnergyBySector('Global',{'Global','Electricity'},options)

Globally, the dominant energy type is fossil fuels. However, by midcentury renewable energies become the dominant energy types. Electrification supports decarbonization in many sectors. The production sectors are moving away from fossil-fuel products and adapting electrification, contributing to the increased generation of electricity.

Regional Electricity Generation

Use the plotEnergyBySector function to show bar graphs for electricity generation by region.

region = regions(4);
options = updateOptions(options, 1,strcat(region," Electricity Generation"), "TW/H",'secondary');
plotEnergyBySector(region,'Electricity',options)

Regional Net Component Changes for Electricity Sector

When a sector is not efficient, the direct emission costs increase because the sector produces more emissions, which also increases indirect costs. Similarly, the revenue decreases because the sector is not very efficient and the capital expenditures are projected to be low.

Therefore, the net income of a company is computed as:

Net Income = Revenues - Direct Emission Costs - Indirect Costs - Capital Expenditures [2]

  • Revenues = (output price * production)

  • Direct Emissions costs = (carbon price * scope1 emissions), where direct emissions cost refers to the increase in a sector's cost associated with the release of greenhouse gases from burning fossil fuels

  • Indirect Costs = (input price * inputs in production), where indirect cost refers to the direct emission cost of upstream sectors that is passed to the sector.

  • Capital Expenditures = (capital price * new capital added), where capital expenditures refers to the cost of investing in new technologies so the sector can become more efficient

Use the plotNetComponents function to show the bar graphs for the evolution of the net components for the electricity sector in a selected region.

region = regions(2);
options = updateOptions(options, 1,region, " Change from Baseline (2019 Policies) (%)");
plotNetComponents(region,'Electricity',options)

For Canada and the United States the direct emission costs are dropping as the policies become stricter and the carbon price increases. To maintain efficiency, the Capital Expenditures also rise. You can see a large impact in both components for the Net-Zero 2050 (1.5°C) scenario where energy technology shows a rapid evolution. However, this change results in lower revenue than the Below 2°C Immediate and Below 2°C Delayed scenarios where the technology evolution remains steady.

Regional and Sectorial Net Component Changes

Use the plotNetIncomeBySector function to generate the bar graphs for net component changes by sector and region.

sector = "Electricity";
region = regions(5);
options = updateOptions(options, 1,strcat(region, " - " ,sector), "Change from Baseline (2019 Policies) (%)");
plotNetIncomeBySector(region,sector,options)

The fossil-fuel sectors present negative net income change as the demand for their products become less. Electricity, on the other hand, presents a positive change in net income as this becomes the dominant energy source in the future.

GDP Impact

Use the plotVariableByCountry function to generate a plot that shows the GDP change across all three climate scenarios compared with the Baseline (2019 Policies) scenario.

region = "Global";
options = updateOptions(options, 1,strcat("GDP ", region), "Deviation from Baseline Percentage");
plotVariableByCountry(region,'GDP', [], options);

The regional and global GDP impacts show similar patterns. Delayed policy action results in sharper impacts to the GDP by 2050 (see Below 2°C Delayed), while immediate policy action results in more gradual decrease of the GDP (see Below 2°C Immediate and Net-Zero 2050 (1.5°C)).

Summary

The climate scenarios illustrate the important sectoral restructuring that the global economies need to undertake to meet climate targets. The climate scenarios show that every sector contributes to the transition and that the financial impacts vary across sectors. These impacts depend on how emissions and capital expenditures affect the sectors and on how the decarbonization of economies affects product demand. The four climate scenarios also highlight the risks of significant macroeconomic impacts, in particular for commodity-exporting countries like Canada. The economic impacts for Canada are driven mostly by declines in global prices of commodities rather than by domestic policy decisions. Finally, the climate scenarios show that delaying climate policy action increases the overall economic impacts and risks to financial stability.

References

[1] https://www.bankofcanada.ca/2022/01/climate-transition-scenario-data

[2] "Transition Scenarios for Analyzing Climate-Related Financial Risks" available at: https://www.bankofcanada.ca/wp-content/uploads/2021/11/sdp2022-1.pdf.

[3] EPPA Model Structure available at https://globalchange.mit.edu/research/research-tools/eppa and https://globalchange.mit.edu/research/research-tools/human-system-model.

[4] "Government of Canada's Pan-Canadian Framework on Clean Growth and Climate Change" available at https://www.canada.ca/en/services/environment/weather/climatechange/pan-canadian-framework.html.

Local Functions

plotVariableByCountry

function plotVariableByCountry(country,variable,sector,options)

GDPflag = false; % Flag that the function is going to be used for GDP plots
if strcmp(variable,'GDP')
    GDPflag = true;
    if strcmp(country,'Global')
        variable = "Global GDP";
        sector = "Global";
    elseif strcmp(country,'Canada')
        variable = "Real GDP";
        sector = "National";
    else
        variable = "US GDP";
        sector = "National";
    end
end


% C02 emissions removal from forestry
baseline_sc = options.baseline(ismember(options.baseline.CL_VARIABLE,variable),:);
b2delayed_sc = options.b2delayed(ismember(options.b2delayed.CL_VARIABLE,variable),:);
b2immediate_sc = options.b2immediate(ismember(options.b2immediate.CL_VARIABLE,variable),:);
netzero2050_sc = options.netzero2050(ismember(options.netzero2050.CL_VARIABLE,variable),:);

% Global C02 emissions removal from forestry
baseline_sc_co = sortrows(baseline_sc((ismember(baseline_sc.CL_GEOGRAPHY,country) & ismember(baseline_sc.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_sc_co = sortrows(b2delayed_sc((ismember(b2delayed_sc.CL_GEOGRAPHY,country) & ismember(b2delayed_sc.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2immediate_sc_co = sortrows(b2immediate_sc((ismember(b2immediate_sc.CL_GEOGRAPHY,country) &ismember(b2immediate_sc.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
netzero2050_sc_co = sortrows(netzero2050_sc((ismember(netzero2050_sc.CL_GEOGRAPHY,country) & ismember(netzero2050_sc.CL_SECTOR,sector)),:),"CL_YEAR","ascend");

figure
if ~GDPflag, plot(baseline_sc_co.CL_YEAR,baseline_sc_co.CL_VALUE.*options.factor), end
hold on
plot(b2delayed_sc_co.CL_YEAR,b2delayed_sc_co.CL_VALUE.*options.factor)
plot(b2immediate_sc_co.CL_YEAR, b2immediate_sc_co.CL_VALUE.*options.factor)
plot(netzero2050_sc_co.CL_YEAR,netzero2050_sc_co.CL_VALUE.*options.factor)
hold off
if ~GDPflag
    legend('Baseline (Policies 2019)','Below 2^oC Delayed','Below 2^oC Immediate','Net-Zero 2050 1.5^oC','Location','southoutside','NumColumns',2)
else
    legend('Below 2^oC Delayed','Below 2^oC Immediate','Net-Zero 2050 1.5^oC','Location','southoutside','NumColumns',3)
end
ylabel(options.yLabel)
title(options.title)
grid on

end

plotVariableBySector

function plotVariableBySector(country,variable,options)

baseline_sc = options.baseline(ismember(options.baseline.CL_VARIABLE,variable),:);
b2delayed_sc = options.b2delayed(ismember(options.b2delayed.CL_VARIABLE,variable),:);
b2immediate_sc = options.b2immediate(ismember(options.b2immediate.CL_VARIABLE,variable),:);
netzero2050_sc = options.netzero2050(ismember(options.netzero2050.CL_VARIABLE,variable),:);

baseline_sc_co = sortrows(baseline_sc(ismember(baseline_sc.CL_GEOGRAPHY,country),:),"CL_YEAR","ascend");
b2delayed_sc_co = sortrows(b2delayed_sc(ismember(b2delayed_sc.CL_GEOGRAPHY,country),:),"CL_YEAR","ascend");
b2immediate_sc_co = sortrows(b2immediate_sc(ismember(b2immediate_sc.CL_GEOGRAPHY,country),:),"CL_YEAR","ascend");
netzero2050_sc_co = sortrows(netzero2050_sc(ismember(netzero2050_sc.CL_GEOGRAPHY,country),:),"CL_YEAR","ascend");

YRS = unique(baseline_sc_co.CL_YEAR);
SEC = unique(baseline_sc_co.CL_SECTOR); SEC(SEC=="Oil & Gas") = []; SEC(SEC=="Global") = []; SEC(SEC=="National") = [];

scenariosTitles = {'Baseline (Policies 2019)','Below 2^oC Delayed','Below 2^oC Immediate','Net-Zero 2050 1.5^oC'};

% Perform initiatilization
for ii = 1:length(YRS)
    for jj = 1:length(SEC)
        idx = jj+((ii-1)*length(SEC));
        fun = @max;
        max_baseline_sc_co(idx,:) = varfun(fun,baseline_sc_co((ismember(baseline_sc_co.CL_YEAR,YRS(ii)) & ismember(baseline_sc_co.CL_SECTOR,SEC(jj))),["CL_VALUE","CL_YEAR","CL_SECTOR","CL_VARIABLE"]),'GroupingVariables',{'CL_SECTOR','CL_VARIABLE'});
        max_b2delayed_sc_co(idx,:) = varfun(fun,b2delayed_sc_co((ismember(b2delayed_sc_co.CL_YEAR,YRS(ii))& ismember(b2delayed_sc_co.CL_SECTOR,SEC(jj))),["CL_VALUE","CL_YEAR","CL_SECTOR","CL_VARIABLE"]),'GroupingVariables',{'CL_SECTOR','CL_VARIABLE'});
        max_b2immediate_sc_co(idx,:) = varfun(fun,b2immediate_sc_co((ismember(b2immediate_sc_co.CL_YEAR,YRS(ii))& ismember(b2immediate_sc_co.CL_SECTOR,SEC(jj))),["CL_VALUE","CL_YEAR","CL_SECTOR","CL_VARIABLE"]),'GroupingVariables',{'CL_SECTOR','CL_VARIABLE'});
        max_netzero2050_sc_co(idx,:) = varfun(fun,netzero2050_sc_co((ismember(netzero2050_sc_co.CL_YEAR,YRS(ii))& ismember(netzero2050_sc_co.CL_SECTOR,SEC(jj))),["CL_VALUE","CL_YEAR","CL_SECTOR","CL_VARIABLE"]),'GroupingVariables',{'CL_SECTOR','CL_VARIABLE'});
    end
end

T1 = [];
T2 = [];
T3 = [];
T4 = [];

% Prepare data to stack
for ii = 1:length(YRS)
    T1 = [T1; table2array(max_baseline_sc_co(ismember(max_baseline_sc_co.max_CL_YEAR,YRS(ii)),"max_CL_VALUE"))'.*options.factor];
    T2 = [T2; table2array(max_b2delayed_sc_co(ismember(max_b2delayed_sc_co.max_CL_YEAR,YRS(ii)),"max_CL_VALUE"))'.*options.factor];
    T3 = [T3; table2array(max_b2immediate_sc_co(ismember(max_b2immediate_sc_co.max_CL_YEAR,YRS(ii)),"max_CL_VALUE"))'.*options.factor];
    T4 = [T4; table2array(max_netzero2050_sc_co(ismember(max_netzero2050_sc_co.max_CL_YEAR,YRS(ii)),"max_CL_VALUE"))'.*options.factor];

end

% Create colorSet
rng(0)
colorSet = round(rand(length(SEC),3),1);

figure
t = tiledlayout(1,4);
t.Title.String = options.title;
t.YLabel.String = options.yLabel;
colororder(colorSet)

ax1 = nexttile;
bar(ax1,YRS,T1,'stacked');
xtickangle(90)
grid on
title(scenariosTitles(1))


ax2 = nexttile;
bar(ax2,YRS,T2,'stacked');
xtickangle(90)
grid on
title(scenariosTitles(2))

ax3 = nexttile;
bar(ax3,YRS,T3,'stacked');
xtickangle(90)
grid on
title(scenariosTitles(3))

ax4 = nexttile;
bar(ax4,YRS,T4,'stacked')
xtickangle(90)
grid on
title(scenariosTitles(4))

linkaxes([ax1 ax2 ax3 ax4],'xy')

lg = legend(SEC,'Location','southoutside','NumColumns',3);
lg.Layout.Tile = 'South'; % Legend placement with tiled layout

end

plotEnergyBySector

function plotEnergyBySector(country,sector,options)

Prim =  {'Primary Energy | Bioenergy','Primary Energy | Coal','Primary Energy | Gas', 'Primary Energy | Hydro', ...
    'Primary Energy | Nuclear','Primary Energy | Oil','Primary Energy | Renewables (wind&solar)'};
Sec =  {'Secondary Energy | Electricity| Bioelectricity (CCS)', ...
    'Secondary Energy | Electricity| Bioelectricity and other', ...
    'Secondary Energy | Electricity| Coal (CCS)', ...
    'Secondary Energy | Electricity| Gas (CCS)', ...
    'Secondary Energy | Electricity| Hydro', ...
    'Secondary Energy | Electricity| Nuclear', ...
    'Secondary Energy | Electricity| Gas (without CCS)', ...
    'Secondary Energy | Electricity| Coal (without CCS)', ...
    'Secondary Energy | Electricity| Oil', ...
    'Secondary Energy | Electricity| Wind&Solar'};
if strcmp(options.energytype,'primary')
    EnergyVars = Prim;
else
    EnergyVars = Sec;
end


baseline_co = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,EnergyVars) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_co = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,EnergyVars)),:),"CL_YEAR","ascend");
b2immediate_co = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,EnergyVars)),:),"CL_YEAR","ascend");
netzero2050_co = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,EnergyVars)),:),"CL_YEAR","ascend");

scenariosTitles = {'Baseline (Policies 2019)','Below 2^oC Delayed','Below 2^oC Immediate','Net-Zero 2050 1.5^oC'};


YRS = unique(baseline_co.CL_YEAR);
VARS = unique(baseline_co.CL_VARIABLE);

T1 = [];
T2 = [];
T3 = [];
T4 = [];


% Prepare data to stack
for ii = 1:length(YRS)
    T1 = [T1; table2array(baseline_co(ismember(baseline_co.CL_YEAR,YRS(ii)),"CL_VALUE"))'.*options.factor];
    T2 = [T2; table2array(b2delayed_co(ismember(b2delayed_co.CL_YEAR,YRS(ii)),"CL_VALUE"))'.*options.factor];
    T3 = [T3; table2array(b2immediate_co(ismember(b2immediate_co.CL_YEAR,YRS(ii)),"CL_VALUE"))'.*options.factor];
    T4 = [T4; table2array(netzero2050_co(ismember(netzero2050_co.CL_YEAR,YRS(ii)),"CL_VALUE"))'.*options.factor];

end

rng(0)
colorSet = round(rand(length(VARS),3),1);

figure
t = tiledlayout(1,4);
t.Title.String = options.title;
t.YLabel.String = options.yLabel;
colororder(colorSet)

ax1 = nexttile;
area(YRS,T1);
grid on
xtickangle(90)
title(scenariosTitles(1))


ax2 = nexttile;
area(YRS,T2);
grid on
xtickangle(90)
title(scenariosTitles(2))

ax3 = nexttile;
area(YRS,T3);
xtickangle(90)
grid on
title(scenariosTitles(3))


ax4 = nexttile;
area(YRS,T4)
xtickangle(90)
grid on
title(scenariosTitles(4))

if strcmp(options.energytype,'primary')
    newVars = strrep(EnergyVars,'Primary Energy | ','');
else
    newVars = strrep(EnergyVars,'Secondary Energy | Electricity| ','');
end
lg  = legend(newVars,'Location','southoutside','NumColumns',3) ;
lg.Layout.Tile = 'South'; % Legend placement with tiled layout

linkaxes([ax1 ax2 ax3 ax4],'xy')
xtickangle(90)

end

plotNetComponents

function plotNetComponents(country,sector,options)

NetVars =  {'Direct emissions costs', ...
    'Capital expenditure', ...
    'Revenue'};
NetVarsTitles = {'Direct Emissions Costs', 'Capital Expenditure', 'Revenue'};

figure
t = tiledlayout(1,length(NetVars));
t.Title.String = options.title;
t.YLabel.String = options.yLabel;

for ii = 1:length(NetVars)
    baseline_co = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,NetVars(ii)) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
    b2delayed_co = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,NetVars(ii))),:),"CL_YEAR","ascend");
    b2immediate_co = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,NetVars(ii))),:),"CL_YEAR","ascend");
    netzero2050_co = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,NetVars(ii))),:),"CL_YEAR","ascend");

    nexttile(ii)
    bar(unique(baseline_co.CL_YEAR),[(b2delayed_co.CL_VALUE-baseline_co.CL_VALUE)./baseline_co.CL_VALUE, ...
        (b2immediate_co.CL_VALUE-baseline_co.CL_VALUE)./baseline_co.CL_VALUE,...
        (netzero2050_co.CL_VALUE-baseline_co.CL_VALUE)./baseline_co.CL_VALUE].*100);
    grid on


    title(NetVarsTitles(ii))

end
lg  =  legend('Below 2^oC Delayed','Below 2^oC Immediate','Net-Zero 2050 (1.5^oC)','Location','southoutside','NumColumns',3);
lg.Layout.Tile = 'South'; % Legend placement with tiled layout
end

plotNetIncomeBySector

function plotNetIncomeBySector(country,sector, options)

NetVars =  {'Capital expenditure', ...
    'Direct emissions costs', ...
    'Revenue', ...
    'Indirect costs'};

figure
t = tiledlayout(1,3);
t.Title.String = options.title;
t.YLabel.String = options.yLabel;

% Capital expenditure
baseline_CE = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,NetVars(1)) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_CE = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,NetVars(1))),:),"CL_YEAR","ascend");
b2immediate_CE = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,NetVars(1))),:),"CL_YEAR","ascend");
netzero2050_CE = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,NetVars(1))),:),"CL_YEAR","ascend");


% Direct emissions costs
baseline_DEC = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,NetVars(2)) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_DEC  = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,NetVars(2))),:),"CL_YEAR","ascend");
b2immediate_DEC  = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,NetVars(2))),:),"CL_YEAR","ascend");
netzero2050_DEC  = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,NetVars(2))),:),"CL_YEAR","ascend");


% Revenue
baseline_RE = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,NetVars(3)) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_RE = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,NetVars(3))),:),"CL_YEAR","ascend");
b2immediate_RE = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,NetVars(3))),:),"CL_YEAR","ascend");
netzero2050_RE = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,NetVars(3))),:),"CL_YEAR","ascend");


% Indirect costs
baseline_IC = sortrows(options.baseline((ismember(options.baseline.CL_GEOGRAPHY,country) & ismember(options.baseline.CL_VARIABLE,NetVars(4)) & ismember(options.baseline.CL_SECTOR,sector)),:),"CL_YEAR","ascend");
b2delayed_IC = sortrows(options.b2delayed((ismember(options.b2delayed.CL_GEOGRAPHY,country) & ismember(options.b2delayed.CL_SECTOR,sector) & ismember(options.b2delayed.CL_VARIABLE,NetVars(4))),:),"CL_YEAR","ascend");
b2immediate_IC = sortrows(options.b2immediate((ismember(options.b2immediate.CL_GEOGRAPHY,country) & ismember(options.b2immediate.CL_SECTOR,sector) & ismember(options.b2immediate.CL_VARIABLE,NetVars(4))),:),"CL_YEAR","ascend");
netzero2050_IC = sortrows(options.netzero2050((ismember(options.netzero2050.CL_GEOGRAPHY,country) & ismember(options.netzero2050.CL_SECTOR,sector) & ismember(options.netzero2050.CL_VARIABLE,NetVars(4))),:),"CL_YEAR","ascend");

if strcmp(sector,"Electricity")
    baseline_NI = baseline_RE.CL_VALUE -baseline_DEC.CL_VALUE  - baseline_CE.CL_VALUE;
    b2delayed_NI = b2delayed_RE.CL_VALUE -b2delayed_DEC.CL_VALUE  - b2delayed_CE.CL_VALUE;
    b2immediate_NI = b2immediate_RE.CL_VALUE -b2immediate_DEC.CL_VALUE  - b2immediate_CE.CL_VALUE;
    netzero2050_NI = netzero2050_RE.CL_VALUE -netzero2050_DEC.CL_VALUE  - netzero2050_CE.CL_VALUE;
else
    % Net incomes
    baseline_NI = baseline_RE.CL_VALUE -baseline_DEC.CL_VALUE - baseline_IC.CL_VALUE - baseline_CE.CL_VALUE;
    b2delayed_NI = b2delayed_RE.CL_VALUE -b2delayed_DEC.CL_VALUE - b2delayed_IC.CL_VALUE - b2delayed_CE.CL_VALUE;
    b2immediate_NI = b2immediate_RE.CL_VALUE -b2immediate_DEC.CL_VALUE - b2immediate_IC.CL_VALUE - b2immediate_CE.CL_VALUE;
    netzero2050_NI = netzero2050_RE.CL_VALUE -netzero2050_DEC.CL_VALUE - netzero2050_IC.CL_VALUE - netzero2050_CE.CL_VALUE;
end


nexttile;
bar(unique(baseline_RE.CL_YEAR),((b2immediate_NI-baseline_NI)./baseline_NI) .*100);
title('Below 2^oC Immediate')
grid on

nexttile;
bar(unique(baseline_RE.CL_YEAR),((b2delayed_NI-baseline_NI)./baseline_NI) .*100);
title('Below 2^oC Delayed')
grid on

nexttile;
bar(unique(baseline_RE.CL_YEAR),((netzero2050_NI-baseline_NI)./baseline_NI) .*100);
title('Net-Zero 2050 1.5^oC')
grid on

end

preprocessBankOfCanadaData

function [ClimateTransitionScenarioData,options] = preprocessBankOfCanadaData(ClimateTransitionScenarioData)

VariableSubset = {'Direct emissions costs', ... % Emissions
    'Emission intensity','Emissions (scope 1)| CH4', ...
    'Emissions (scope 1)| CO2', ...
    'Emissions (scope 1)| HFC', ...
    'Emissions (scope 1)| N2O', ...
    'Emissions (scope 1)| PFC', ...
    'Emissions (scope 1)| SF6', ...
    'Emissions (scope 2)| total GHG', ...
    'Emissions | total GHG (scope 1)', ...
    'Emissions/removals from forestry', ...
    'Carbon price' ...  % Shadow carbon price
    'Primarsy Energy | Bioenergy', ...  % Primary energy
    'Primary Energy | Coal', ...
    'Primary Energy | Gas', ...
    'Primary Energy | Hydro', ...
    'Primary Energy | Nuclear', ...
    'Primary Energy | Oil', ...
    'Primary Energy | Renewables (wind&solar)', ...
    'Primary Energy | Total', ...
    'Secondary Energy | Electricity| Bioelectricity (CCS)', ... % Secondary energy for electricity
    'Secondary Energy | Electricity| Bioelectricity and other', ...
    'Secondary Energy | Electricity| Coal (CCS)', ...
    'Secondary Energy | Electricity| Coal (without CCS)', ...
    'Secondary Energy | Electricity| Gas (CCS)', ...
    'Secondary Energy | Electricity| Gas (without CCS)', ...
    'Secondary Energy | Electricity| Hydro', ...
    'Secondary Energy | Electricity| Nuclear', ...
    'Secondary Energy | Electricity| Oil', ...
    'Secondary Energy | Electricity| Wind&Solar', ...
    'Capital expenditure', ...     % Components of net income
    'Direct emissions costs', ...
    'Indirect costs', ...
    'Revenue', ...
    'US GDP', ... % GDPs
    'Global GDP', ...
    'Real GDP'};

% Keep only the specific VARIABLES
ClimateTransitionScenarioData = ClimateTransitionScenarioData(ismember(ClimateTransitionScenarioData.CL_VARIABLE, VariableSubset),:);

% Find unique values of the categories. These are useful for the controls
% that appear later.
regions = string(unique(ClimateTransitionScenarioData.CL_GEOGRAPHY));
sectors = string(unique(ClimateTransitionScenarioData.CL_SECTOR));
vars = string(unique(ClimateTransitionScenarioData.CL_VARIABLE));
SCE = unique(ClimateTransitionScenarioData.CL_SCENARIO);

% Remove table variables from data
ClimateTransitionScenarioData = removevars(ClimateTransitionScenarioData,{'k'});
ClimateTransitionScenarioData = sortrows(ClimateTransitionScenarioData);

% Pull data by scenario
baseline = ClimateTransitionScenarioData(ismember(ClimateTransitionScenarioData.CL_SCENARIO, 'Baseline (2019 policies)'),:);
b2delayed = ClimateTransitionScenarioData(ismember(ClimateTransitionScenarioData.CL_SCENARIO, 'Below 2°C delayed'),:);
b2immediate = ClimateTransitionScenarioData(ismember(ClimateTransitionScenarioData.CL_SCENARIO, 'Below 2°C immediate'),:);
netzero2050 = ClimateTransitionScenarioData(ismember(ClimateTransitionScenarioData.CL_SCENARIO, 'Net-zero 2050 (1.5°C)'),:);

% Options for local functions
options = struct;
options.regions = regions;
options.sectors = sectors;
options.var = vars;
options.scenarios = SCE;
options.baseline = baseline;
options.b2delayed = b2delayed;
options.b2immediate = b2immediate;
options.netzero2050 = netzero2050;
end

addData

function options = updateOptions(options,varargin)
% varargin
% 1st: factor
% 2nd: title
% 3rd: ylabel
% 4th: energy type
if nargin<3
    options.factor = varargin{1};
elseif nargin<4
    options.factor = varargin{1};
    options.title = varargin{2};
elseif nargin<5
    options.factor = varargin{1};
    options.title = varargin{2};
    options.yLabel = varargin{3};
else
    options.factor = varargin{1};
    options.title = varargin{2};
    options.yLabel = varargin{3};
    options.energytype  = varargin{4};
end

end

Related Topics

External Websites