|
6 | 6 | from matplotlib.ticker import PercentFormatter |
7 | 7 |
|
8 | 8 | from papers.Martin_Staadecker_Value_of_LDES_and_Factors.LDES_paper_graphs.util import ( |
9 | | - get_scenario, |
10 | 9 | set_style, |
| 10 | + get_set_e_scenarios, |
11 | 11 | ) |
12 | 12 | from switch_model.tools.graph.main import GraphTools |
13 | 13 |
|
14 | 14 |
|
15 | 15 | # Prepare graph tools |
16 | | -tools = GraphTools( |
17 | | - scenarios=[ |
18 | | - get_scenario("1342", name=1.94), |
19 | | - get_scenario("M7", name=2), |
20 | | - get_scenario("M10", name=2.5), |
21 | | - get_scenario("M9", name=3), |
22 | | - get_scenario("M6", name=4), |
23 | | - get_scenario("M5", name=8), |
24 | | - get_scenario("M11", name=12), |
25 | | - get_scenario("M4", name=16), |
26 | | - get_scenario("M14", name=18), |
27 | | - get_scenario("M13", name=20), |
28 | | - get_scenario("M8", name=24), |
29 | | - get_scenario("M3", name=32), |
30 | | - get_scenario("M12", name=48), |
31 | | - get_scenario("M2", name=64), |
32 | | - ] |
33 | | -) |
| 16 | +tools = GraphTools(scenarios=get_set_e_scenarios()) |
34 | 17 | tools.pre_graphing(multi_scenario=True) |
35 | 18 |
|
36 | 19 | # %% CREATE FIGURE |
|
43 | 26 | ax3 = fig.add_subplot(2, 2, 3) |
44 | 27 | ax4 = fig.add_subplot(2, 2, 4) |
45 | 28 |
|
46 | | -# %% Daily LMP |
47 | | - |
48 | | -ax = ax3 |
49 | | -ax.clear() |
50 | | -time_mapping = { |
51 | | - 0: "Midnight", |
52 | | - 4: "4am", |
53 | | - 8: "8am", |
54 | | - 12: "Noon", |
55 | | - 16: "4pm", |
56 | | - 20: "8pm" |
57 | | -} |
58 | | -daily_lmp = tools.get_dataframe( |
59 | | - "load_balance.csv", |
60 | | - usecols=[ |
61 | | - "timestamp", |
62 | | - "normalized_energy_balance_duals_dollar_per_mwh", |
63 | | - "scenario_name", |
64 | | - ], |
65 | | -).rename(columns={"normalized_energy_balance_duals_dollar_per_mwh": "value"}) |
66 | | -daily_lmp = tools.transform.timestamp(daily_lmp) |
67 | | -daily_lmp = daily_lmp.groupby(["scenario_name", "hour"], as_index=False)["value"].mean() |
68 | | -daily_lmp = daily_lmp.pivot(index="scenario_name", columns="hour", values="value") |
69 | | -daily_lmp *= 0.1 # Convert from $/MWh to cents/kWh |
70 | | -daily_lmp = daily_lmp.rename(time_mapping, axis=1).rename_axis("Time of day (PST)", axis=1) |
71 | | -daily_lmp.plot( |
72 | | - ax=ax, |
73 | | - xlabel="WECC-wide storage capacity (TWh)", |
74 | | - marker=".", |
75 | | - ylabel=u"Estimated LMP (\xa2/kWh)", |
76 | | - # cmap="tab10" |
77 | | -) |
78 | | -ax.set_title("C. Average estimated LMP by time of day") |
79 | | -# %% YEARLY LMP |
80 | | -ax = ax4 |
81 | | -ax.clear() |
82 | | -scenarios_for_yearly_lmp = [5, 7, 8, 11, 12] |
83 | | - |
84 | | -cap = tools.get_dataframe( |
85 | | - "load_balance.csv", |
86 | | - usecols=[ |
87 | | - "timestamp", |
88 | | - "normalized_energy_balance_duals_dollar_per_mwh", |
89 | | - "scenario_name", |
90 | | - ], |
91 | | -).rename(columns={"normalized_energy_balance_duals_dollar_per_mwh": "value"}) |
92 | | -cap = cap.groupby(["scenario_name", "timestamp"], as_index=False).mean() |
93 | | -cap = tools.transform.timestamp(cap) |
94 | | -cap = cap.set_index("datetime") |
95 | | -cap["month"] = cap.index.month |
96 | | -cap = cap.groupby(["scenario_name", "month"]).value.mean() |
97 | | -cap = cap.unstack("month").rename_axis("Storage Capacity (TWh)", axis=1) |
98 | | -# Convert from $/MWh to cents/kWh |
99 | | -cap *= 0.1 |
100 | | -cap = cap[scenarios_for_yearly_lmp] |
101 | | -cap = cap.rename({ |
102 | | - 5: "May", |
103 | | - 7: "July", |
104 | | - 8: "August", |
105 | | - 11: "November", |
106 | | - 12: "December", |
107 | | -}, axis=1) |
108 | | -cap.plot( |
109 | | - ax=ax, |
110 | | - xlabel="WECC-wide storage capacity (TWh)", |
111 | | - marker=".", |
112 | | - ylabel=u"Monthly-average estimated LMP (\xa2/kWh)", |
113 | | - # cmap="tab10" |
114 | | -) |
115 | | -ax.set_title("D. Average estimated LMP during key months") |
116 | 29 | # %% IMPACT ON TX AND GEN |
117 | 30 |
|
118 | 31 | ax = ax2 |
|
149 | 62 | # Filter out storage since it's not considered generation |
150 | 63 | buildout = buildout[buildout["gen_type"] != "Storage"] |
151 | 64 | # Sum across the entire scenario |
152 | | -buildout = buildout.groupby("scenario_name")["BuildGen"].sum().rename("Built Generation") |
| 65 | +buildout = ( |
| 66 | + buildout.groupby("scenario_name")["BuildGen"].sum().rename("Built Generation") |
| 67 | +) |
153 | 68 |
|
154 | 69 | cap = tools.get_dataframe( |
155 | 70 | "gen_cap.csv", |
|
166 | 81 | # Convert to percent against baseline |
167 | 82 | df = (df / df.iloc[0] - 1) * 100 |
168 | 83 |
|
169 | | -dotted_tx = df.loc[[1.94,3,20,64], ["Built Transmission"]] |
| 84 | +dotted_tx = df.loc[[1.94, 3, 20, 64], ["Built Transmission"]] |
170 | 85 |
|
171 | 86 | # Plot |
172 | 87 | colors = tools.get_colors() |
|
200 | 115 | # Add the gen_type column |
201 | 116 | curtailment = tools.transform.gen_type(curtailment) |
202 | 117 | # Convert to GW |
203 | | -curtailment["value"] = curtailment["Curtailment_MW"] * curtailment["tp_weight_in_year_hrs"] / 1000 |
204 | | -curtailment = curtailment.groupby(["scenario_name", "gen_type"], as_index=False).value.sum() |
205 | | -curtailment = curtailment.pivot(index="scenario_name", columns="gen_type", values="value") |
| 118 | +curtailment["value"] = ( |
| 119 | + curtailment["Curtailment_MW"] * curtailment["tp_weight_in_year_hrs"] / 1000 |
| 120 | +) |
| 121 | +curtailment = curtailment.groupby( |
| 122 | + ["scenario_name", "gen_type"], as_index=False |
| 123 | +).value.sum() |
| 124 | +curtailment = curtailment.pivot( |
| 125 | + index="scenario_name", columns="gen_type", values="value" |
| 126 | +) |
206 | 127 | curtailment /= 1000 |
207 | 128 | curtailment = curtailment.rename_axis("Technology", axis=1) |
208 | 129 | curtailment.plot(ax=ax, color=tools.get_colors(), marker=".") |
|
211 | 132 | ax.set_title("A. Impact of LDES on curtailment") |
212 | 133 | ax.tick_params(top=False, bottom=False, right=False, left=False) |
213 | 134 | # %% |
214 | | -plt.subplots_adjust(hspace=0.2, wspace=0.25, left=0.07, right=0.97, top=0.95, bottom=0.07) |
| 135 | +plt.subplots_adjust( |
| 136 | + hspace=0.2, wspace=0.25, left=0.07, right=0.97, top=0.95, bottom=0.07 |
| 137 | +) |
215 | 138 |
|
216 | 139 | # %% CALCULATIONS |
217 | 140 | cap_total = cap["Solar"] + cap["Wind"] |
|
224 | 147 | 1 - cap / cap.iloc[0] |
225 | 148 | cap - cap.iloc[0] |
226 | 149 | # %% change from 20 to 64 |
227 | | -1 - cap / cap.loc[20] # wind decrease % |
228 | | -cap / cap.loc[20] - 1 # solar increase % |
| 150 | +1 - cap / cap.loc[20] # wind decrease % |
| 151 | +cap / cap.loc[20] - 1 # solar increase % |
229 | 152 | (cap - cap.loc[20]) / 1000 |
230 | 153 | # %% transmission |
231 | 154 | tx / tx.iloc[0] * 100 |
|
237 | 160 | # %% average drop in daily duals |
238 | 161 | df = daily_lmp.mean(axis=1) |
239 | 162 | df / df.iloc[0] - 1 |
240 | | -daily_lmp / daily_lmp.iloc[0] - 1 |
| 163 | +# daily_lmp / daily_lmp.iloc[0] - 1 |
| 164 | +# %% night time drop |
| 165 | +df = daily_lmp[["Midnight", "8pm", "4am"]].mean(axis=1) |
| 166 | +(1 - df.loc[3] / df.iloc[0]) * 100 / ((3 - 1.94) * 10) |
0 commit comments