Source code for postreise.plot.plot_sim_vs_hist
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from postreise.analyze.generation.summarize import sum_generation_by_state
[docs]class PlotSettings:
width = 0.3 # width of bars
fontsize = 15
size_inches = (20, 10)
[docs]def plot_generation_sim_vs_hist(
scenario,
hist_gen,
state,
show_max=True,
plot_show=True,
):
"""Plot simulated vs historical generation of each resource in the scenario
for the given state. Optionally include max generation.
:param powersimdata.scenario.scenario.Scenario scenario: scenario instance.
:param pandas.DataFrame hist_gen: historical generation data frame. Columns are
resources and indices are state names.
:param str state: the US state
:param bool show_max: determine whether to additionally plot max generation of each
resource.
:param plot_show: show the plot or not, defaults to True.
:return: (*matplotlib.axes.Axes*) -- axes object of the plot.
:raises TypeError:
if ``hist_gen`` is not a data frame.
if ``state`` is not a str.
:raises ValueError: if ``state`` is not in ``hist_gen`` or ``scenario``.
"""
if not isinstance(hist_gen, pd.DataFrame):
raise TypeError("hist_gen must be a pandas.DataFrame")
if not isinstance(state, str):
raise TypeError("state must be a str")
sim_gen = sum_generation_by_state(scenario)
if state not in sim_gen.index or state not in hist_gen.index:
raise ValueError("Invalid state")
all_resources = list(sim_gen.columns)
sim = [int(round(sim_gen.loc[state, res])) for res in all_resources]
hist = [int(round(hist_gen.loc[state, res])) for res in all_resources]
grid = scenario.get_grid()
pg = scenario.get_pg()
def calc_max(fuel):
loadzone = list(grid.model_immutables.area_to_loadzone(state, "state")) # noqa
capacity = grid.plant.query("type == @fuel & zone_name == @loadzone")[
"Pmax"
].sum()
if capacity == 0:
print(f"No {fuel} generator in {state}")
return int(capacity * pg.shape[0] / 1000)
max_gen = []
if show_max:
max_gen = [calc_max(res) for res in all_resources]
x = np.arange(len(all_resources)) # the label locations
width = PlotSettings.width
fontsize = PlotSettings.fontsize
size_inches_x, size_inches_y = PlotSettings.size_inches
fig, ax = plt.subplots()
if show_max:
rects1 = ax.bar(x - width, hist, width, label="Historical")
rects2 = ax.bar(x, sim, width, label="Simulated")
rects3 = ax.bar(x + width, max_gen, width, label="Max Generation")
else:
rects1 = ax.bar(x - width / 2, hist, width, label="Historical")
rects2 = ax.bar(x + width / 2, sim, width, label="Simulated")
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel("GWh", fontsize=fontsize)
ax.set_title(state, fontsize=fontsize)
ax.set_xticks(x)
ax.set_xticklabels(all_resources, fontsize=fontsize)
ax.legend(fontsize=fontsize)
def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax.annotate(
str(height),
xy=(rect.get_x() + rect.get_width() / 2, height),
xytext=(0, 3), # 3 points vertical offset
textcoords="offset points",
ha="center",
va="bottom",
fontsize=8,
)
autolabel(rects1)
autolabel(rects2)
if show_max:
autolabel(rects3)
fig.tight_layout()
fig.set_size_inches(size_inches_x, size_inches_y)
if plot_show:
plt.show()
return ax