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

Added several plot methods and fixed a few minor bugs/warnings #262

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@
from calendar import month_abbr
from concurrent.futures import ProcessPoolExecutor

# pylint: enable=E0401

import numpy as np
import numpy.typing as npt
import pandas as pd
from ladybug.datacollection import HourlyContinuousCollection
from ladybug.datatype.temperature import (
UniversalThermalClimateIndex as LB_UniversalThermalClimateIndex,
)
from ladybug.datatype.temperature import \
UniversalThermalClimateIndex as LB_UniversalThermalClimateIndex
from ladybug.epw import EPW
from ladybug_comfort.collection.solarcal import OutdoorSolarCal
from ladybug_comfort.collection.utci import UTCI
from python_toolkit.bhom.analytics import bhom_analytics
from scipy.interpolate import interp1d, interp2d
from tqdm import tqdm

from python_toolkit.bhom.analytics import bhom_analytics
from ..categorical.categories import UTCI_DEFAULT_CATEGORIES, CategoricalComfort
from ..categorical.categories import (UTCI_DEFAULT_CATEGORIES,
CategoricalComfort)
from ..helpers import evaporative_cooling_effect, month_hour_binned_series
from ..ladybug_extension.datacollection import (
collection_from_series,
collection_to_series,
)
from ..ladybug_extension.datacollection import (collection_from_series,
collection_to_series)

# pylint: enable=E0401




def _saturated_vapor_pressure_hpa(dry_bulb_temperature: np.ndarray):
Expand Down
17 changes: 7 additions & 10 deletions LadybugTools_Engine/Python/src/ladybugtools_toolkit/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,19 @@
from caseconverter import snakecase
from honeybee.config import folders as hb_folders
from ladybug.datatype.temperature import WetBulbTemperature
from ladybug.epw import EPW, AnalysisPeriod, HourlyContinuousCollection, Location
from ladybug.epw import (EPW, AnalysisPeriod, HourlyContinuousCollection,
Location)
from ladybug.psychrometrics import wet_bulb_from_db_rh
from ladybug.skymodel import (
calc_horizontal_infrared,
calc_sky_temperature,
estimate_illuminance_from_irradiance,
get_extra_radiation,
zhang_huang_solar,
zhang_huang_solar_split,
)
from ladybug.skymodel import (calc_horizontal_infrared, calc_sky_temperature,
estimate_illuminance_from_irradiance,
get_extra_radiation, zhang_huang_solar,
zhang_huang_solar_split)
from ladybug.sunpath import Sunpath
from ladybug_geometry.geometry2d import Vector2D
from meteostat import Hourly, Point

from python_toolkit.bhom.analytics import bhom_analytics
from python_toolkit.bhom.logging import CONSOLE_LOGGER

from .ladybug_extension.dt import lb_datetime_from_datetime

# pylint: enable=E0401
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
from pathlib import Path
from typing import Any

# pylint: enable=E0401

import numpy as np
import pandas as pd
from ladybug.analysisperiod import AnalysisPeriod
Expand All @@ -24,32 +22,28 @@
from ladybug.epw import EPW, EPWFields, MonthlyCollection
from ladybug.header import Header
from ladybug.location import Location
from ladybug.psychrometrics import (
dew_point_from_db_wb,
enthalpy_from_db_hr,
humid_ratio_from_db_rh,
rel_humid_from_db_wb,
wet_bulb_from_db_rh,
)
from ladybug.psychrometrics import (dew_point_from_db_wb, enthalpy_from_db_hr,
humid_ratio_from_db_rh,
rel_humid_from_db_wb, wet_bulb_from_db_rh)
from ladybug.skymodel import clearness_index as lb_ci
from ladybug.sunpath import Sun, Sunpath
from ladybug_comfort.degreetime import cooling_degree_time, heating_degree_time

from python_toolkit.bhom.analytics import bhom_analytics
from ..helpers import (
air_pressure_at_height,
radiation_at_height,
temperature_at_height,
timedelta_tostring,
wind_speed_at_height,
)

from ..helpers import (air_pressure_at_height, radiation_at_height,
temperature_at_height, timedelta_tostring,
wind_speed_at_height)
from .analysisperiod import analysis_period_to_datetimes
from .datacollection import average as average_collection
from .datacollection import collection_to_series
from .groundtemperature import hourly_ground_temperature
from .header import header_to_string
from .location import average_location, location_to_string

# pylint: enable=E0401




@bhom_analytics()
def epw_to_dataframe(
Expand Down Expand Up @@ -1054,7 +1048,7 @@ def seasonality_from_temperature_timeseries(
series = series.loc[~series.index.duplicated()]

# check that series is long enough
if max(series.index) - min(series.index) < pd.Timedelta(hours=364):
if max(series.index) - min(series.index) < pd.Timedelta(hours=364*24):
raise ValueError(
"Input dataset must be at least 365 days long to determine seasonality."
)
Expand Down Expand Up @@ -1217,7 +1211,7 @@ def seasonality_from_temperature_timeseries(
).date()

temp = dbt.to_frame()
s = pd.Series(index=dbt.index, data=np.nan)
s = pd.Series(index=dbt.index, data=np.nan, dtype=str)
s.loc[spring_start] = "Spring"
s.loc[summer_start] = "Summer"
s.loc[autumn_start] = "Autumn"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
"""Method for plotting evaporative cooling potential."""

import matplotlib.pyplot as plt
from pathlib import Path

import matplotlib.pyplot as plt
import pandas as pd
from ladybug.epw import EPW

from ._heatmap import heatmap
from ..ladybug_extension.datacollection import collection_to_series
from ..ladybug_extension.location import location_to_string
from ._heatmap import heatmap


def evaporative_cooling_potential(epw: EPW, ax: plt.Axes = None, **kwargs) -> plt.Axes:
def evaporative_cooling_potential(
dbt: pd.Series, dpt: pd.Series, ax: plt.Axes = None, agg_year: bool = False, agg: str = "mean", **kwargs
) -> plt.Axes:
"""Plot evaporative cooling potential (DBT - DPT).

Args:
epw (EPW):
An EPW object.
dbt (pd.Series):
A pandas Series containing Dry Bulb Temperature data.
dpt (pd.Series):
A pandas Series containing Dew Point Temperature data.
ax (plt.Axes, optional):
The matplotlib axes to plot the figure on. Defaults to None.
**kwargs:
Expand All @@ -24,27 +29,66 @@ def evaporative_cooling_potential(epw: EPW, ax: plt.Axes = None, **kwargs) -> pl
plt.Axes: The matplotlib axes.
"""

if len(dbt) != len(dpt):
raise ValueError("The length of the two series must be the same.")

if any(dbt.index != dpt.index):
raise ValueError("The indices of the two series must be the same.")

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

dpt = collection_to_series(epw.dew_point_temperature)
dbt = collection_to_series(epw.dry_bulb_temperature)
ecp = (dbt - dpt).clip(lower=0).rename("Evaporative Cooling Potential (C)")

if agg_year:
# check for presence of Feb 29 in ecp index
if len(ecp[(ecp.index.month == 2) & (ecp.index.day == 29)]) != 0:
idx = pd.date_range(start="2016-01-01", periods=8784, freq="h")
else:
idx = pd.date_range(start="2017-01-01", periods=8760, freq="h")

ecp = ecp.groupby([ecp.index.month, ecp.index.day, ecp.index.hour]).agg(agg)
ecp.index = idx

if "cmap" not in kwargs:
kwargs["cmap"] = "GnBu"

heatmap(series=ecp, ax=ax, **kwargs)
ax.text(
1,
1,
"*value shown indicate cooling effect from saturating air with moisture (DBT - DPT)",
"*values shown indicate cooling effect from saturating air with moisture (DBT - DPT)",
transform=ax.transAxes,
ha="right",
va="top",
fontsize="small",
)

return ax


def evaporative_cooling_potential_epw(epw: EPW, ax: plt.Axes = None, **kwargs) -> plt.Axes:
"""Plot evaporative cooling potential (DBT - DPT).

Args:
epw (EPW):
An EPW object.
ax (plt.Axes, optional):
The matplotlib axes to plot the figure on. Defaults to None.
**kwargs:
Additional keyword arguments to pass to the heatmap function.

Returns:
plt.Axes: The matplotlib axes.
"""

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

evaporative_cooling_potential(
dbt=collection_to_series(epw.dry_bulb_temperature), dpt=collection_to_series(epw.dew_point_temperature), ax=ax, **kwargs
)

ax.set_title(Path(epw.file_path).name)

return ax
65 changes: 13 additions & 52 deletions LadybugTools_Engine/Python/src/ladybugtools_toolkit/plot/_misc.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
"""Miscellaneous plots that don't really fit anywhere else."""

# pylint: disable=line-too-long
from calendar import month_abbr # pylint: disable=E0401

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

import numpy as np
import pandas as pd

from ladybug.epw import EPW, Location
from ladybug.sunpath import Sunpath

from ..ladybug_extension.datacollection import collection_to_series
from ..categorical.categories import Categorical
from ..helpers import sunrise_sunset
from ..ladybug_extension.datacollection import collection_to_series
from ._heatmap import heatmap
from ..categorical.categories import Categorical


def cloud_cover_categories(epw: EPW, ax: plt.Axes = None) -> plt.Axes:
Expand Down Expand Up @@ -49,9 +48,7 @@ def cloud_cover_categories(epw: EPW, ax: plt.Axes = None) -> plt.Axes:
9: "overcast",
10: "overcast",
}
mtx = mtx.T.groupby(mapper).sum()[
["clear", "mostly clear", "partly cloudy", "mostly cloudy", "overcast"]
]
mtx = mtx.T.groupby(mapper).sum()[["clear", "mostly clear", "partly cloudy", "mostly cloudy", "overcast"]]
mtx = (mtx.T / mtx.sum(axis=1)).T

mtx.plot.area(ax=ax, color=["#95B5DF", "#B1C4DD", "#C9D0D9", "#ACB0B6", "#989CA1"])
Expand Down Expand Up @@ -95,37 +92,20 @@ def hours_sunlight(location: Location, ax: plt.Axes = None) -> plt.Axes:
index=srss_df.index,
)
civil_twilight = (
[
i.seconds / (60 * 60)
for i in (srss_df["civil twilight end"] - srss_df["civil twilight start"])
]
- daylight
[i.seconds / (60 * 60) for i in (srss_df["civil twilight end"] - srss_df["civil twilight start"])] - daylight
).rename("civil twilight")
nautical_twilight = (
[
i.seconds / (60 * 60)
for i in (
srss_df["nautical twilight end"] - srss_df["nautical twilight start"]
)
]
[i.seconds / (60 * 60) for i in (srss_df["nautical twilight end"] - srss_df["nautical twilight start"])]
- daylight
- civil_twilight
).rename("nautical twilight")
astronomical_twilight = (
[
i.seconds / (60 * 60)
for i in (
srss_df["astronomical twilight end"]
- srss_df["astronomical twilight start"]
)
]
[i.seconds / (60 * 60) for i in (srss_df["astronomical twilight end"] - srss_df["astronomical twilight start"])]
- daylight
- civil_twilight
- nautical_twilight
).rename("astronomical twilight")
night = (
24 - (daylight + civil_twilight + nautical_twilight + astronomical_twilight)
).rename("night")
night = (24 - (daylight + civil_twilight + nautical_twilight + astronomical_twilight)).rename("night")

temp = pd.concat(
[daylight, civil_twilight, nautical_twilight, astronomical_twilight, night],
Expand Down Expand Up @@ -223,37 +203,20 @@ def hours_sunrise_sunset(location: Location, ax: plt.Axes = None) -> plt.Axes:
index=srss_df.index,
)
civil_twilight = (
[
i.seconds / (60 * 60)
for i in (srss_df["civil twilight end"] - srss_df["civil twilight start"])
]
- daylight
[i.seconds / (60 * 60) for i in (srss_df["civil twilight end"] - srss_df["civil twilight start"])] - daylight
).rename("civil twilight")
nautical_twilight = (
[
i.seconds / (60 * 60)
for i in (
srss_df["nautical twilight end"] - srss_df["nautical twilight start"]
)
]
[i.seconds / (60 * 60) for i in (srss_df["nautical twilight end"] - srss_df["nautical twilight start"])]
- daylight
- civil_twilight
).rename("nautical twilight")
astronomical_twilight = (
[
i.seconds / (60 * 60)
for i in (
srss_df["astronomical twilight end"]
- srss_df["astronomical twilight start"]
)
]
[i.seconds / (60 * 60) for i in (srss_df["astronomical twilight end"] - srss_df["astronomical twilight start"])]
- daylight
- civil_twilight
- nautical_twilight
).rename("astronomical twilight")
night = (
24 - (daylight + civil_twilight + nautical_twilight + astronomical_twilight)
).rename("night")
night = (24 - (daylight + civil_twilight + nautical_twilight + astronomical_twilight)).rename("night")

temp = pd.concat(
[daylight, civil_twilight, nautical_twilight, astronomical_twilight, night],
Expand Down Expand Up @@ -289,9 +252,7 @@ def hours_sunrise_sunset(location: Location, ax: plt.Axes = None) -> plt.Axes:
fc="#B9AC86",
label="Civil twilight",
)
ax.fill_between(
hours.index, hours["sunrise"], hours["sunset"], fc="#FCE49D", label="Day"
)
ax.fill_between(hours.index, hours["sunrise"], hours["sunset"], fc="#FCE49D", label="Day")
ax.fill_between(
hours.index,
hours["sunset"],
Expand Down
Loading