Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add analysis period filtering to utci_comfort_band_comparison plot #252

Open
jamesramsden-bh opened this issue Sep 30, 2024 · 1 comment
Assignees
Labels
type:feature New capability or enhancement

Comments

@jamesramsden-bh
Copy link
Contributor

Add the ability to filter each HourlyContinuousCollection with an AnalysisPeriod to the utci_comfort_band_comparison plot.

Here is a rough version of something that works. It needs additional verification, e.g. to ensure that the length of the analysis_periods is the same as the length of the utci_collections, it is handled if this is not the case, and comments need updating. Add any additional necessary imports too. Further comments welcome.

def utci_comfort_band_comparison(
    utci_collections: tuple[HourlyContinuousCollection],
    ax: plt.Axes = None,
    identifiers: tuple[str] = None,
    utci_categories: CategoricalComfort = UTCI_DEFAULT_CATEGORIES,
    density: bool = True,
    analysis_periods = [],
    **kwargs,
) -> plt.Axes:
    """Create a proportional bar chart showing how different UTCI collections
    compare in terms of time within each comfort band.

    Args:
        utci_collections (list[HourlyContinuousCollection]):
            A list of UTCI collections.
        ax (plt.Axes, optional):
            The matplotlib Axes to plot on. Defaults to None which uses the current Axes.
        identifiers (list[str], optional):
            A list of names to give each collection. Defaults to None.
        utci_categories (Categories, optional):
            The UTCI categories to use. Defaults to UTCI_DEFAULT_CATEGORIES.
        density (bool, optional):
            If True, then show percentage, otherwise show count. Defaults to True.
        **kwargs:
            Additional keyword arguments to pass to the function.

    Returns:
        plt.Axes:
            A matplotlib Axes object.
    """

    for n, col in enumerate(utci_collections):
        if not isinstance(col.header.data_type, LB_UniversalThermalClimateIndex):
            raise ValueError(
                f"Collection {n} data type is not UTCI and cannot be used in this plot."
            )
    if any(len(i) != len(utci_collections[0]) for i in utci_collections):
        raise ValueError("All collections must be the same length.")

    if ax is None:
        ax = plt.gca()

    # set the title
    ax.set_title(kwargs.pop("title", None))

    if identifiers is None:
        identifiers = [f"{n}" for n in range(len(utci_collections))]
    if len(identifiers) != len(utci_collections):
        raise ValueError(
            "The number of identifiers given does not match the number of UTCI collections given!"
        )

    #new stuff starts here
    if len(analysis_periods) > 0 and len(analysis_periods) == len(utci_collections):
        series_zips = zip(utci_collections, analysis_periods)
        serieses = [collection_to_series(utci_collection.filter_by_analysis_period(analysis_period)) for utci_collection, analysis_period in series_zips]

    counts = pd.concat(
        [utci_categories.value_counts(i, density=density) for i in serieses],
        axis=1,
        keys=identifiers,
    )
    counts.T.plot(
        ax=ax,
        kind="bar",
        stacked=True,
        color=utci_categories.colors,
        width=0.8,
        legend=False,
    )

# rest of file.....
@jamesramsden-bh jamesramsden-bh added the type:feature New capability or enhancement label Sep 30, 2024
@Tom-Kingstone
Copy link
Contributor

After seeing this, we talked in person - I suggested that this functionality isn't really necessary as the HourlyContinuousCollection has a method to filter data by an analysis period (among other filter methods) - so a user can provide an already filtered collection to this method.

The only problem is that the method enforces that the lengths of both collections must be the same. Therefore to get the functionality that is needed, we should change the error to a warning that warns that the collections given were not the same size, but continue code execution anyway.

  for n, col in enumerate(utci_collections):
          if not isinstance(col.header.data_type, LB_UniversalThermalClimateIndex):
              raise ValueError(
                  f"Collection {n} data type is not UTCI and cannot be used in this plot."
              )
      if any(len(i) != len(utci_collections[0]) for i in utci_collections):
          CONSOLE_LOGGER.warn("The collections given have different lengths.")

And to make it clearer to users that the input collection doesn't actually have to be continuous, we should update the type hint to List[BaseCollection] instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New capability or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants