Heatmap kalender menata metrik harian berdasarkan hari dan minggu dalam bulan, sehingga pola musiman dan bias hari kerja mudah terlihat.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
date_index = pd.date_range("2024-01-01", "2024-12-31", freq="D")
# Metrik sintetis dengan musiman + efek hari kerja + noise
seasonal = 40 + 25 * np.sin(2 * np.pi * date_index.dayofyear / 365)
weekday_boost = np.where(date_index.weekday < 5, 8, -10)
rng = np.random.default_rng(42)
metric = seasonal + weekday_boost + rng.normal(0, 5, len(date_index))
calendar_df = pd.DataFrame({"date": date_index, "value": metric})
calendar_df["month"] = calendar_df["date"].dt.month
calendar_df["weekday"] = calendar_df["date"].dt.weekday
month_start_weekday = (
calendar_df["date"].dt.to_period("M").dt.to_timestamp().dt.weekday
)
calendar_df["week_of_month"] = (
(month_start_weekday + calendar_df["date"].dt.day - 1) // 7
).astype(int)
fig, axes = plt.subplots(3, 4, figsize=(12, 7), sharex=True, sharey=True)
vmin, vmax = calendar_df["value"].min(), calendar_df["value"].max()
for month in range(1, 13):
ax = axes[(month - 1) // 4, (month - 1) % 4]
month_df = calendar_df[calendar_df["month"] == month]
matrix = np.full((7, 6), np.nan)
for row in month_df.itertuples():
matrix[row.weekday, row.week_of_month] = row.value
im = ax.imshow(
matrix,
origin="upper",
aspect="auto",
cmap="viridis",
vmin=vmin,
vmax=vmax,
)
ax.set_title(f"Bulan {month}", fontsize=11, pad=8)
ax.set_xticks(range(6), labels=["Minggu 1", "Minggu 2", "Minggu 3", "Minggu 4", "Minggu 5", "Minggu 6"], fontsize=8)
ax.set_yticks(range(7), labels=["Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Min"], fontsize=8)
ax.tick_params(length=0)
fig.suptitle("Durasi sesi harian 2024 (menit)", fontsize=14, y=0.98)
cbar = fig.colorbar(im, ax=axes, orientation="horizontal", fraction=0.035, pad=0.08)
cbar.set_label("Durasi rata-rata (menit)")
fig.tight_layout()
plt.show()

Kiat membaca #
- Jika hari kerja tampak lebih gelap, penggunaan condong ke hari kerja.
- Perubahan warna antar bulan sering menandakan kampanye musiman atau kejadian eksternal.
- Bandingkan minggu tinggi dengan inisiatif pemasaran untuk melihat kontribusinya.