Calendar Heatmap

Fitness Workout Calendar

Annual workout tracking calendar showing exercise intensity and consistency.

Output
Fitness Workout Calendar
Python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
import matplotlib.patches as mpatches

np.random.seed(123)

# Generate workout data (0-4 scale: rest, light, moderate, intense, extreme)
days = 365
workouts = np.random.choice([0, 0, 1, 2, 2, 3, 3, 4], size=days, p=[0.15, 0.1, 0.15, 0.2, 0.15, 0.1, 0.1, 0.05])

# Reshape into weeks
weeks = 53
data = np.zeros((7, weeks))
for i, val in enumerate(workouts):
    week = i // 7
    day = i % 7
    if week < weeks:
        data[day, week] = val

# Coral to cyan gradient
colors = ['#0a0a0f', '#1a1a3f', '#F5276C', '#F54927', '#F5B027']
cmap = LinearSegmentedColormap.from_list('fitness', colors, N=256)

fig, ax = plt.subplots(figsize=(16, 4), facecolor='#0a0a0f')
ax.set_facecolor('#0a0a0f')

im = ax.imshow(data, cmap=cmap, aspect='auto', vmin=0, vmax=4)

ax.set_yticks(range(7))
ax.set_yticklabels(['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], fontsize=9, color='#e2e8f0')
ax.set_xticks(range(0, 52, 4))
ax.set_xticklabels(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ''], 
                   fontsize=9, color='#e2e8f0')

ax.set_title('Annual Workout Intensity Tracker', fontsize=16, color='white', fontweight='bold', pad=15)

for i in range(8):
    ax.axhline(y=i-0.5, color='#1e293b', linewidth=0.5)
for i in range(weeks+1):
    ax.axvline(x=i-0.5, color='#1e293b', linewidth=0.5)

ax.tick_params(colors='#e2e8f0', length=0)
for spine in ax.spines.values():
    spine.set_visible(False)

legend_elements = [mpatches.Patch(facecolor=c, label=l, edgecolor='#334155') 
                   for c, l in zip(colors, ['Rest', 'Light', 'Moderate', 'Intense', 'Extreme'])]
ax.legend(handles=legend_elements, loc='upper left', bbox_to_anchor=(0, -0.15), ncol=5, 
          fontsize=8, facecolor='#1e293b', edgecolor='#334155', labelcolor='white')

workout_days = int(np.sum(workouts > 0))
ax.annotate(f'{workout_days} workout days ({workout_days*100//365}% consistency)', xy=(0.98, 1.1), xycoords='axes fraction',
            fontsize=11, color='#F5276C', ha='right', fontweight='bold')

plt.tight_layout()
plt.subplots_adjust(bottom=0.25)
plt.show()
Library

Matplotlib

Category

Time Series

Did this help you?

Support PyLucid to keep it free & growing

Support