Skip to content

Commit 297f70d

Browse files
committed
Create supplementary plots for all figures
1 parent 631424b commit 297f70d

13 files changed

+284
-30
lines changed
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from switch_model.tools.graph.main import GraphTools
66

7-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
7+
from papers.Martin_Staadecker_et_al_2022.util import (
88
set_style,
99
get_scenario, save_figure,
1010
)
@@ -209,8 +209,6 @@ def rolling_avg(df):
209209
save_figure("figure-1-baseline.png")
210210
# %% CALCULATIONS
211211

212-
import pandas as pd
213-
214212
# Panel A analysis
215213
df = curtailment.copy()
216214
df = df[["Solar"]]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from matplotlib.ticker import PercentFormatter
66

77
from switch_model.tools.graph.main import GraphTools
8-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
8+
from papers.Martin_Staadecker_et_al_2022.util import (
99
get_scenario,
1010
set_style, save_figure,
1111
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from switch_model.tools.graph.main import GraphTools
55

6-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
6+
from papers.Martin_Staadecker_et_al_2022.util import (
77
set_style,
88
get_scenario, save_figure,
99
)
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import pandas as pd
21
from matplotlib import pyplot as plt
32
from matplotlib.cm import get_cmap, ScalarMappable
43
from matplotlib.colors import (
@@ -7,7 +6,7 @@
76
from matplotlib.ticker import PercentFormatter
87

98
from switch_model.tools.graph.main import GraphTools
10-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
9+
from papers.Martin_Staadecker_et_al_2022.util import (
1110
get_scenario,
1211
set_style, save_figure,
1312
)
@@ -23,7 +22,7 @@
2322
tools = GraphTools(scenarios=scenarios, set_style=False)
2423
tools.pre_graphing(multi_scenario=True)
2524

26-
tools_supplementary = GraphTools(scenarios=scenarios_supplementary)
25+
tools_supplementary = GraphTools(scenarios=scenarios_supplementary, set_style=False)
2726
tools_supplementary.pre_graphing(multi_scenario=True)
2827

2928
zones_to_highlight = [
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from matplotlib.colors import Normalize
1010
import labellines
1111

12-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
12+
from papers.Martin_Staadecker_et_al_2022.util import (
1313
set_style,
1414
get_set_e_scenarios, save_figure,
1515
)
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from matplotlib import gridspec
77
import labellines
88

9-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
9+
from papers.Martin_Staadecker_et_al_2022.util import (
1010
set_style,
1111
get_set_e_scenarios, save_figure,
1212
)
@@ -259,3 +259,5 @@
259259
cap.loc[20, :]
260260
df = cap.loc[64, :].sort_values(ascending=False)
261261
df
262+
# %% CHANGE IN PRICE SURGE IN 99th percentile
263+
1 - variability.loc[20, 0.99] / variability.loc[1.94, 0.99]
Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
# %% IMPORT + CREATE tools
22
from matplotlib import pyplot as plt
33

4+
from papers.Martin_Staadecker_et_al_2022.util import set_style, get_scenario, save_figure
45
from switch_model.tools.graph.main import GraphTools
56

6-
from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import (
7-
set_style,
8-
get_scenario,
9-
)
10-
11-
tools_baseline = GraphTools([get_scenario("1342", "Baseline Scenario")])
7+
tools_baseline = GraphTools([get_scenario("1342", "Baseline Scenario")], set_style=False)
128
tools_baseline.pre_graphing(multi_scenario=False)
139

14-
tools_hydro = GraphTools([get_scenario("H050", "50% Hydro Scenario (from Set B)")])
10+
tools_hydro = GraphTools([get_scenario("H050", "50% Hydro Scenario (from Set B)")], set_style=False)
1511
tools_hydro.pre_graphing(multi_scenario=False)
1612

1713
ROLLING_AVERAGE_DAYS = 7
@@ -20,7 +16,6 @@
2016
set_style()
2117
plt.close()
2218
fig = plt.figure()
23-
fig.set_size_inches(12, 8)
2419
ax1 = fig.add_subplot(1, 2, 1, projection=tools_baseline.maps.get_projection())
2520
ax2 = fig.add_subplot(1, 2, 2, projection=tools_hydro.maps.get_projection())
2621

@@ -108,3 +103,5 @@ def plot(tools, ax, data, legend=True):
108103
plot(tools_baseline, ax1, get_data(tools_baseline), legend=False)
109104
plt.tight_layout()
110105
plt.tight_layout() # Twice to ensure it works properly, it's a bit weird at times'
106+
# %% SAVE FIGURE
107+
save_figure("figure-s1-impact-of-half-hydro.png")
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
from matplotlib import pyplot as plt
2+
from matplotlib.cm import get_cmap, ScalarMappable
3+
from matplotlib.colors import (
4+
TwoSlopeNorm,
5+
)
6+
from matplotlib.ticker import PercentFormatter
7+
8+
from switch_model.tools.graph.main import GraphTools
9+
from papers.Martin_Staadecker_et_al_2022.util import (
10+
get_scenario,
11+
set_style, save_figure,
12+
)
13+
14+
scenarios_supplementary = [
15+
get_scenario("1342", "Baseline"),
16+
get_scenario("T5", "10x Tx Build Costs"),
17+
]
18+
19+
tools_supplementary = GraphTools(scenarios=scenarios_supplementary, set_style=False)
20+
tools_supplementary.pre_graphing(multi_scenario=True)
21+
22+
# Uncomment to make supplementary figure
23+
tools = tools_supplementary
24+
zones_to_highlight = None
25+
26+
n = len(scenarios_supplementary)
27+
28+
29+
# %% GET DATA
30+
31+
32+
def get_data(scenario_index):
33+
dispatch = tools.get_dataframe("dispatch_zonal_annual_summary.csv")
34+
dispatch = dispatch[dispatch.scenario_index == scenario_index]
35+
dispatch = tools.transform.gen_type(dispatch)
36+
dispatch = tools.transform.load_zone(dispatch, load_zone_col="gen_load_zone")
37+
dispatch = dispatch[dispatch.gen_type != "Storage"]
38+
dispatch = dispatch.groupby("gen_load_zone")[["Energy_GWh_typical_yr"]].sum()
39+
dispatch.columns = ["generation_gwh"]
40+
41+
demand = tools.get_dataframe("load_balance_annual_zonal.csv")
42+
demand = demand[demand.scenario_index == scenario_index]
43+
demand = demand.set_index("load_zone")
44+
demand = demand["zone_demand_mw"]
45+
demand *= -1e-3
46+
demand = demand.rename("demand_gwh")
47+
48+
df = dispatch.join(demand)
49+
df["percent_gen"] = df["generation_gwh"] / df["demand_gwh"] * 100
50+
df = df["percent_gen"]
51+
52+
duration = tools.get_dataframe("storage_capacity.csv").rename(
53+
{"load_zone": "gen_load_zone"}, axis=1
54+
)
55+
duration = duration[duration.scenario_index == scenario_index]
56+
duration = duration[duration["period"] == 2050].drop(columns="period")
57+
duration = duration.groupby("gen_load_zone", as_index=False).sum()
58+
duration["value"] = (
59+
duration["OnlineEnergyCapacityMWh"] / duration["OnlinePowerCapacityMW"]
60+
)
61+
duration = duration[["gen_load_zone", "value", "OnlinePowerCapacityMW"]]
62+
duration["OnlinePowerCapacityMW"] *= 1e-3
63+
64+
demand = tools.get_dataframe("loads.csv", from_inputs=True)
65+
demand = demand[demand.scenario_index == scenario_index]
66+
demand = demand.groupby("LOAD_ZONE").zone_demand_mw.max()
67+
demand *= 1e-3
68+
duration = duration.set_index("gen_load_zone")
69+
duration = duration.join(demand)
70+
duration = duration.reset_index()
71+
duration["percent_power"] = (
72+
duration["OnlinePowerCapacityMW"] / duration["zone_demand_mw"] * 100
73+
)
74+
75+
return df, duration
76+
77+
78+
data = [get_data(i) for i in range(n)]
79+
80+
# %% DEFINE FIGURE AND PLOTTING FUNCTIONS
81+
set_style()
82+
plt.close()
83+
fig = plt.figure()
84+
85+
# Define axes
86+
axes = []
87+
for i in range(n):
88+
axes.append(fig.add_subplot(1, n, i + 1, projection=tools.maps.get_projection()))
89+
90+
plt.subplots_adjust(left=0.02, right=0.98, wspace=0.05)
91+
92+
Y_LIM = 11 * 100
93+
cmap = get_cmap("bwr")
94+
95+
normalizer = TwoSlopeNorm(vmin=0, vcenter=100, vmax=Y_LIM)
96+
97+
98+
def percent_to_color(percent):
99+
return cmap(normalizer(percent))
100+
101+
102+
def plot(ax, data, legend):
103+
percent_gen, duration = data
104+
105+
max_size = 400
106+
max = 50
107+
duration["size"] = duration["OnlinePowerCapacityMW"] / max * max_size
108+
tools.maps.draw_base_map(ax)
109+
percent_gen = percent_gen.apply(percent_to_color)
110+
tools.maps.graph_load_zone_colors(percent_gen, ax)
111+
legend_handles = tools.maps.graph_duration(
112+
duration, ax=ax, legend=False, bins=(0, 6, 10, 20, float("inf"))
113+
)
114+
115+
if legend:
116+
fig.legend(
117+
title="Storage Duration (h)",
118+
handles=legend_handles,
119+
bbox_to_anchor=(0.6, 0),
120+
loc="lower center",
121+
fontsize="small",
122+
title_fontsize="small",
123+
ncol=4,
124+
)
125+
# Add legend for power capacity
126+
sizes = [5, 10, 30]
127+
fig.legend(
128+
title="Storage Capacity (GW)",
129+
handles=[
130+
tools.plt.lines.Line2D(
131+
[],
132+
[],
133+
color="dimgray",
134+
marker=".",
135+
markersize=l,
136+
label=l,
137+
linestyle="None",
138+
markeredgewidth=1,
139+
markeredgecolor="dimgray",
140+
)
141+
for l, s in zip(sizes, [x / max * max_size for x in sizes])
142+
],
143+
bbox_to_anchor=(0.35, 0),
144+
loc="lower center",
145+
fontsize="small",
146+
title_fontsize="small",
147+
ncol=3,
148+
labelspacing=1.5,
149+
)
150+
151+
152+
for i, ax in enumerate(axes):
153+
plot(ax, data[i], legend=(i == n - 1))
154+
ax.set_title(tools.scenarios[i].name)
155+
156+
fig.colorbar(
157+
ScalarMappable(norm=normalizer, cmap=cmap),
158+
format=PercentFormatter(),
159+
ticks=[0, 20, 40, 60, 80, 100, 300, 500, 700, 900, 1100],
160+
extend="max",
161+
ax=axes,
162+
location="right",
163+
label="Yearly Generation / Yearly Demand",
164+
)
165+
166+
167+
def highlight_zones(zones, ax):
168+
if zones is None:
169+
return
170+
for _, lz in tools.maps._wecc_lz.iterrows():
171+
if lz.gen_load_zone in zones:
172+
# Add load zone borders
173+
ax.add_geometries(
174+
lz.geometry,
175+
crs=tools.maps.get_projection(),
176+
facecolor=(0, 0, 0, 0), # Transparent
177+
edgecolor="tab:green",
178+
linewidth=1,
179+
# linestyle="--",
180+
# alpha=0,
181+
)
182+
183+
184+
highlight_zones(zones_to_highlight, axes[0])
185+
186+
# %% SAVE FIGURE
187+
save_figure("figure-s2-impact-of-10x-tx.png")
188+
189+
# %%
190+
df = tools_supplementary.get_dataframe("storage_capacity.csv")
191+
df = df.set_index("load_zone")
192+
df_baseline = df[df.scenario_index == 0]
193+
df_compare = df[df.scenario_index == 1]
194+
df = df_baseline.join(df_compare, lsuffix="_base", rsuffix="_compare")
195+
# df["change_in_cap"] = (
196+
# df["OnlineEnergyCapacityMWh_compare"] - df["OnlineEnergyCapacityMWh_base"]
197+
# ) * 1e-3
198+
df["change_in_cap"] = (
199+
df["OnlineEnergyCapacityMWh_compare"] / df["OnlineEnergyCapacityMWh_base"]
200+
) * 100 - 100
201+
df = df["change_in_cap"]
202+
# df = df[df > 0]
203+
# df.sum()
204+
# df_compare["OnlineEnergyCapacityMWh"].sum() / df_baseline[
205+
# "OnlineEnergyCapacityMWh"
206+
# ].sum() * 100 - 100
207+
# df_compare["OnlineEnergyCapacityMWh"].sum() - df_baseline[
208+
# "OnlineEnergyCapacityMWh"
209+
# ].sum()
210+
df
211+
212+
# %% Num of load zones generating less than 25% of demand
213+
scenario_index = 0
214+
# scenario_index = 1 # For baseline
215+
df = data[scenario_index][0].copy()
216+
df = df[df < 50]
217+
len(df)
218+
219+
# %% Contribution of zones to highlight
220+
221+
scenario_index = 0
222+
# scenario_index = 1 # For baseline
223+
dispatch = tools.get_dataframe("dispatch_zonal_annual_summary.csv")
224+
dispatch = dispatch[dispatch.scenario_index == scenario_index]
225+
dispatch = tools.transform.gen_type(dispatch)
226+
dispatch = dispatch[dispatch.gen_type != "Storage"]
227+
dispatch = dispatch.groupby("gen_load_zone")[["Energy_GWh_typical_yr"]].sum()
228+
dispatch.columns = ["generation_gwh"]
229+
dispatch = dispatch.reset_index()
230+
dispatch.sort_values("generation_gwh")
231+
total = dispatch.generation_gwh.sum()
232+
total_for_zone = dispatch[
233+
dispatch.gen_load_zone.isin(zones_to_highlight)
234+
].generation_gwh.sum()
235+
total_for_zone / total
236+
237+
# %% Num zones to highlight
238+
len(zones_to_highlight)
239+
240+
# %% Power contribution for load zones
241+
df = tools.get_dataframe("storage_capacity.csv")
242+
df = df.set_index("load_zone")
243+
cities = ["CA_LADWP", "WA_SEATAC", "CA_PGE_BAY", "CA_SCE_S", "AZ_PHX"]
244+
# df = df.loc[cities]
245+
df["OnlineEnergyCapacityMWh"] *= 1e-3
246+
df_compare = df[df.scenario_index == 0]
247+
df_baseline = df[df.scenario_index == 1]
248+
df = df_baseline.join(df_compare, lsuffix="_base", rsuffix="_compare")
249+
df["change_in_cap"] = (
250+
df["OnlineEnergyCapacityMWh_compare"] - df["OnlineEnergyCapacityMWh_base"]
251+
)
252+
# df["change_in_cap"] = (df["OnlineEnergyCapacityMWh_compare"] / df["OnlineEnergyCapacityMWh_base"]) * 100
253+
df = df["change_in_cap"]
254+
df.sort_values()
255+
# df.sum()
256+
# df_compare["OnlineEnergyCapacityMWh"].sum() / df_baseline["OnlineEnergyCapacityMWh"].sum() * 100

0 commit comments

Comments
 (0)