Source code for postreise.plot.plot_scatter_capacity_vs_cost_curve_slope
import matplotlib.pyplot as plt
from powersimdata.input.helpers import get_plant_id_for_resources_in_area
from powersimdata.scenario.check import _check_scenario_is_in_analyze_state
[docs]def plot_scatter_capacity_vs_cost_curve_slope(
    scenario,
    area,
    resources,
    area_type=None,
    markersize=50,
    fontsize=20,
    title=None,
    plot_show=True,
):
    """Generate for a given scenario the scatter plot of the capacity (x-axis) vs
    cost curve slope (y-axis) of generators located in area and fueled by resources
    :param powersimdata.scenario.scenario.Scenario scenario: scenario instance
    :param str area: ame of the area to focus on. Could be a loadzone, a state, a
        country, etc. This will depend on the grid model.
    :param str/list resources: one or a list of resources.
    :param str area_type: area supported by the grid model. For more details, see the
        :func:`powersimdata.network.model.area_to_loadzone` function.
    :param int/float markersize: marker size, default to 50.
    :param int/float fontsize: font size, default to 20.
    :param str title: user specified figure title, default to None.
    :param bool plot_show: show the plot or not, default to True.
    :return: (*tuple*) -- the first entry is matplotlib.axes.Axes object of the plot,
        the second entry is the capacity weighted average of cost curve slopes over the
        selected time range.
    :raises TypeError:
        if ``area`` is not a str.
        if ``resources`` is not a str or a list of str.
        if ``markersize`` is not an int or a float.
        if ``fontsize`` is not an int or a float.
        if ``title`` is provided but not a str.
    """
    _check_scenario_is_in_analyze_state(scenario)
    if not isinstance(area, str):
        raise TypeError("area must be a str")
    if not isinstance(resources, (str, list)):
        raise TypeError("resources must be a list or str")
    if isinstance(resources, list) and not all(isinstance(r, str) for r in resources):
        raise TypeError("resources must be a list of str")
    if not isinstance(markersize, (int, float)):
        raise TypeError("markersize must be either an int or float")
    if not isinstance(fontsize, (int, float)):
        raise TypeError("fontsize must be either an int or float")
    if title is not None and not isinstance(title, str):
        raise TypeError("title must be a string")
    plant_id = get_plant_id_for_resources_in_area(
        scenario, area, resources, area_type=area_type
    )
    grid = scenario.get_grid()
    plant_df = grid.plant.loc[plant_id]
    cost_df = grid.gencost["after"].loc[plant_id]
    slope = (cost_df["f2"] - cost_df["f1"]) / (cost_df["p2"] - cost_df["p1"])
    total_cap = plant_df["Pmax"].sum()
    if total_cap == 0:
        data_avg = 0
    else:
        data_avg = (plant_df["Pmax"] * slope).sum() / total_cap
    _, ax = plt.subplots(figsize=[20, 10])
    ax.scatter(plant_df["Pmax"], slope, s=markersize)
    ax.plot(plant_df["Pmax"], [data_avg] * len(plant_df.index), c="red")
    ax.grid()
    if title is None:
        ax.set_title(
            f'{area} {" ".join(resources) if isinstance(resources, list) else resources}'
        )
    else:
        ax.set_title(title)
    ax.set_xlabel("Capacity (MW)")
    ax.set_ylabel("Slope")
    for item in (
        [ax.title, ax.xaxis.label, ax.yaxis.label]
        + ax.get_xticklabels()
        + ax.get_yticklabels()
    ):
        item.set_fontsize(fontsize)
    if plot_show:
        plt.show()
    return ax, data_avg