Energy Signature#
Goal
Plot an energy signature: daily heating energy against the daily mean outdoor temperature, colored by season. The cloud shows how the heating demand rises as it gets colder; where it drops to zero lies roughly the balance point temperature (fitted with regression lines in Energy Signature (PES)).
Data Basis
Building energy signature data (bldg_engy_sig_simple.csv) bundled with the pyedautils package. Contains columns timestamp, temperature, and value (daily heating energy).
Data Preparation#
import numpy as np
import pandas as pd
from importlib import resources
data_path = resources.files("pyedautils") / "data" / "bldg_engy_sig_simple.csv"
df = pd.read_csv(data_path, sep=";")
def remove_outliers_by_temp_bin(df, temp_col, value_col, bin_width=2,
lower_q=0.01, upper_q=0.99):
"""Remove rows where value_col falls outside the per-temperature-bin quantiles."""
df = df.copy()
df["_bin"] = pd.cut(df[temp_col], bins=np.arange(
df[temp_col].min() - bin_width,
df[temp_col].max() + bin_width * 2,
bin_width,
))
bounds = df.groupby("_bin", observed=True)[value_col].quantile(
[lower_q, upper_q]
).unstack()
bounds.columns = ["lo", "hi"]
df = df.join(bounds, on="_bin")
mask = df[value_col].between(df["lo"], df["hi"])
print(f"Removed {(~mask).sum()} outliers out of {len(df)} rows")
return df.loc[mask].drop(columns=["_bin", "lo", "hi"])
df = remove_outliers_by_temp_bin(df, "temperature", "value")
df.head()
Removed 29 outliers out of 576 rows
| timestamp | temperature | value | |
|---|---|---|---|
| 0 | 2018-03-21 | 2.82 | 176.54 |
| 1 | 2018-03-22 | 1.08 | 196.75 |
| 2 | 2018-03-23 | 5.33 | 148.92 |
| 3 | 2018-03-24 | 9.90 | 101.15 |
| 4 | 2018-03-25 | 9.11 | 100.82 |
Visualization#
from pyedautils.plots import plot_energy_signature
fig = plot_energy_signature(
data=df,
title="Building Energy Signature",
xlab="Outside Temperature [°C]",
ylab="Heating Energy [kWh/d]",
)
fig.show()
Customization
You can adjust the axis labels and title. To analyze a different time period, filter the DataFrame before plotting.
df["timestamp"] = pd.to_datetime(df["timestamp"])
df_winter = df[df["timestamp"].dt.month.isin([11, 12, 1, 2, 3])]
fig = plot_energy_signature(df_winter, title="Energy Signature — Winter Only")