Skip to content

Commit

Permalink
Merge pull request #344 from Breakthrough-Energy/ben/si
Browse files Browse the repository at this point in the history
Remove dependency on ScenarioInfo objects
  • Loading branch information
rouille authored Apr 29, 2022
2 parents f9aa1f8 + f4136e9 commit cf3c53f
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 23 deletions.
75 changes: 52 additions & 23 deletions postreise/plot/plot_sim_vs_hist.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import warnings

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from postreise.analyze.generation.summarize import sum_generation_by_state


class PlotSettings:
Expand All @@ -10,41 +11,67 @@ class PlotSettings:
size_inches = (20, 10)


def plot_generation_sim_vs_hist(sim_gen, hist_gen, s_info, state, showmax=True):
"""
Plot simulated vs historical generation of each resource in the scenario
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 pandas.DataFrame sim_gen: simulated generation dataframe
:param pandas.DataFrame hist_gen: historical generation dataframe
:param powersimdata.design.ScenarioInfo s_info: scenario info instance.
: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 showmax: determine whether to additionally plot max generation of each resource
: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``.
"""
labels = list(sim_gen.columns)
all_resources = s_info.get_available_resource("all")
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]

def calc_max(gen_type):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
return int(
s_info.get_capacity(gen_type, state) * len(s_info.pg.index) / 1000
)
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 showmax:
if show_max:
max_gen = [calc_max(res) for res in all_resources]

x = np.arange(len(labels)) # the label locations
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 showmax:
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")
Expand All @@ -56,7 +83,7 @@ def calc_max(gen_type):
ax.set_ylabel("GWh", fontsize=fontsize)
ax.set_title(state, fontsize=fontsize)
ax.set_xticks(x)
ax.set_xticklabels(labels, fontsize=fontsize)
ax.set_xticklabels(all_resources, fontsize=fontsize)
ax.legend(fontsize=fontsize)

def autolabel(rects):
Expand All @@ -74,8 +101,10 @@ def autolabel(rects):

autolabel(rects1)
autolabel(rects2)
if showmax:
if show_max:
autolabel(rects3)
fig.tight_layout()
fig.set_size_inches(size_inches_x, size_inches_y)
plt.show()
if plot_show:
plt.show()
return ax
78 changes: 78 additions & 0 deletions postreise/plot/tests/test_plot_sim_vs_hist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import pandas as pd
import pytest
from powersimdata.tests.mock_scenario import MockScenario

from postreise.plot.plot_sim_vs_hist import plot_generation_sim_vs_hist

mock_plant = {
"plant_id": ["A", "B", "C", "D", "E", "F", "G", "H"],
"zone_id": [301, 302, 303, 304, 305, 306, 307, 308],
"Pmax": [100, 75, 150, 30, 50, 300, 200, 80],
"Pmin": [0, 0, 0, 0, 0, 100, 10, 0],
"type": ["solar", "wind", "hydro", "hydro", "wind", "coal", "ng", "wind"],
"zone_name": [
"Far West",
"North",
"West",
"South",
"North Central",
"South Central",
"Coast",
"East",
],
}

mock_pg = pd.DataFrame(
{
"A": [80, 75, 72, 81],
"B": [22, 22, 25, 20],
"C": [130, 130, 130, 130],
"D": [25, 26, 27, 28],
"E": [10, 11, 9, 12],
"F": [290, 295, 295, 294],
"G": [190, 190, 191, 190],
"H": [61, 63, 65, 67],
},
index=pd.date_range(start="2016-01-01", periods=4, freq="H"),
)

grid_attrs = {"plant": mock_plant}
scenario = MockScenario(grid_attrs, pg=mock_pg)
scenario.info["interconnect"] = "Texas"
scenario.info["start_date"] = pd.Timestamp(2016, 1, 1)
scenario.info["end_date"] = pd.Timestamp(2016, 1, 1, 3)
scenario.state.grid.id2zone = {
k: v for k, v in zip(mock_plant["zone_id"], mock_plant["zone_name"])
}
scenario.state.grid.zone2id = {v: k for k, v in scenario.state.grid.id2zone.items()}
scenario.state.grid.model = "usa_tamu"

hist_gen = pd.DataFrame(
{
"solar": 100 * 4,
"wind": 205 * 4,
"hydro": 180 * 4,
"coal": 300 * 4,
"ng": 200 * 4,
},
index=["Texas"],
)


def test_plot_generation_sim_vs_hist_argument_type():
with pytest.raises(TypeError, match="hist_gen must be a pandas.DataFrame"):
plot_generation_sim_vs_hist(scenario, 3, "Texas")
with pytest.raises(TypeError, match="state must be a str"):
plot_generation_sim_vs_hist(scenario, pd.DataFrame(), ["Texas"])


def test_plot_generation_sim_vs_hist_argument_value():
with pytest.raises(ValueError, match="Invalid state"):
plot_generation_sim_vs_hist(scenario, hist_gen, "Washington")


def test_plot_generation_sim_vs_hist():
plot_generation_sim_vs_hist(
scenario, hist_gen, "Texas", show_max=False, plot_show=False
)
plot_generation_sim_vs_hist(scenario, hist_gen, "Texas", plot_show=False)

0 comments on commit cf3c53f

Please sign in to comment.