Comfort Compass

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.

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")