Comfort Compass#
Goal
Show the distribution of days across nine comfort states (cold / ok / warm × dry / ok / humid) with three severity stages, as an area-true polar “compass”: at a glance which way — and how strongly — the indoor climate drifts out of the comfort band.
Data Basis
We use the bundled dataset room_climate_sample.csv shipped with pyedautils —
anonymized hourly temperature and humidity from a real sensor in a cool,
humidity-controlled room. It is loaded directly from the installed package
(importlib.resources), so no download is needed.
Reading the compass
The pyedautils guide Reading the comfort compass explains how to read it, how to compare rooms, the comfort band and severity stages and how to save energy.
Data Preparation#
import pandas as pd
from importlib import resources
data_path = resources.files("pyedautils") / "data" / "room_climate_sample.csv"
df = pd.read_csv(data_path)
df["timestamp"] = pd.to_datetime(df["timestamp"])
df = df.set_index("timestamp") # DatetimeIndex -> the compass counts days
df.head()
| humidity | temperature | |
|---|---|---|
| timestamp | ||
| 2025-05-01 00:00:00 | 51.0 | 19.1 |
| 2025-05-01 01:00:00 | 51.0 | 19.1 |
| 2025-05-01 02:00:00 | 51.0 | 19.1 |
| 2025-05-01 03:00:00 | 51.0 | 19.1 |
| 2025-05-01 04:00:00 | 50.2 | 19.1 |
Visualization#
The compass is area-true: the green disc is the share of days in range, each arm the share of days off in one direction (warm at the top, humid on the right, as in an h-x diagram), split from light to dark into mild / moderate / severe. Disc and arms always add up to the dashed 100 % circle.
from pyedautils.comfort import comfort_compass_distribution
from pyedautils.plots import plot_comfort_compass
# Cool, humidity-controlled room -> target band 8-18 deg C / 40-70 %rH.
dist = comfort_compass_distribution(df, temp_band=(8, 18), hum_band=(40, 70))
fig = plot_comfort_compass(dist, title="Indoor comfort compass")
fig.show()
total = sum(dist.values())
warm = sum(n for key, n in dist.items() if key.startswith("w_"))
print(f"In range: {dist['ok'] / total:.0%} of {total} days")
print(f"Too warm: {warm / total:.0%} of the days, severely too warm: {dist['w_s'] / total:.0%}")
In range: 28% of 365 days
Too warm: 50% of the days, severely too warm: 30%
Most days off the band were too warm, and most of those severely (more than 2.5 K above 18 °C): that is the direction to act on first (saving energy in the guide).
Customization
Tune the bands and severity limits, or also judge humidity by its absolute limit with
hum_abs_band (a warm point above the absolute-humidity cap then reads as “warm + humid”).
The same stage limits give the warning bands of the Mollier h-x Diagram
via comfort_warning_bands(). To compare rooms, keep the default scale="fixed" (same 100 %
circle in every chart); scale="fit" zooms a single glyph to fill its panel. All texts
(title, names, direction_labels, stage_names, count_label, stats_text) can be replaced.
dist = comfort_compass_distribution(
df,
temp_band=(8, 18), hum_band=(40, 70),
hum_abs_band=(0.0, 0.0115), # also cap absolute humidity [kg/kg]
temp_stage_limits=(1.0, 2.5), # K over the band: mild / moderate
hum_stage_limits=(5.0, 10.0), # %-points over the band
)
fig = plot_comfort_compass(dist, title="Indoor comfort compass", scale="fit")