Running performance analysis built from our own Garmin sessions, enriched with real weather data, then explored through dashboards and reporting tools.
From field collection to data pipeline to interactive storytelling
Do environmental conditions (weather) have a measurable impact on running performance, and does that impact vary across runners?
Temperature, wind, humidity, and rain: do these variables impact 400m time?
Does each runner respond differently to the same weather conditions?
How can we separate real physical progress from weather effects across sessions?
All analyses focus on Lap 2 only: a maximal effort of about 400m, automatically extracted from second-by-second FIT files.
Sensors, data collection protocol, team, and running site
FIT extraction, database, and automation
Streamlit & Power BI dashboards, weather data, key findings
Interactive Streamlit + live Power BI
Limitations, bias, interpretation, outlook
The collection setup combines a multi-sensor Garmin watch for movement data and a Polar optical sensor for cleaner heart-rate tracking.

This watch provides the backbone of the project: route geometry, speed evolution, cadence and estimated power, all at second-level resolution.

Reims · 49.2408°N 4.0543°E · 400m asphalt track
Adaptive threshold at 75% of peak speed: works across runner levels.
Conditions retrieved at each session’s exact timestamp and GPS coordinates.
New FIT dropped in → extraction → DB update → dashboard refreshed automatically.
| Runner | S. | Duration | Dist. | Pace | Best | Avg HR | Max HR | Cadence | Power |
|---|---|---|---|---|---|---|---|---|---|
| Adrien | 1 | 92s | 399m | 3:43 | 3:27 | 167 | 170 | 175 | 454W |
| Adrien | 2 | 96s | 393m | 3:58 | 3:42 | 179 | 182 | 170 | 445W |
| Adrien | 3 | 91s | 397m | 3:51 | 3:35 | 169 | 172 | 179 | 419W |
| Adrien | 4 | 79s | 333m | 3:53 | 3:38 | 145 | 158 | 166 | 446W |
| Arthur | 1 | 58s | 411m | 2:14 | 2:04 | 178 | 188 | 196 | 686W |
| Arthur | 2 | 52s ★ | 362m | 2:18 | 1:59 | 177 | 181 | 206 | 647W |
| Arthur | 3 | 57s | 395m | 2:25 | 2:11 | 150 | 157 | 208 | 619W |
| Arthur | 4 | 60s | 395m | 2:22 | 2:15 | 176 | 183 | 198 | 624W |
| Khalil | 1 | 76s | 403m | 3:02 | 2:47 | 190 | 196 | 178 | 493W |
| Khalil | 2 | 86s | 398m | 3:32 | 3:23 | 163 | 169 | 172 | 462W |
| Khalil | 4 | 81s | 423m | 3:16 | 2:58 | 186 | 193 | 178 | 474W |
| Nathan | 1 | 89s | 409m | 3:38 | 3:24 | 192 | 196 | 161 | 479W |
| Nathan | 2 | 71s | 386m | 3:00 | 2:53 | 115* | 165 | 176 | 537W |
| Nathan | 3 | 78s | 400m | 3:13 | 3:04 | 158 | 161 | 174 | 493W |
| Nathan | 4 | 89s | 393m | 3:49 | 3:07 | 160 | 165 | 163 | 452W |
★ Best overall run · * Likely sensor artifact (Avg HR 115 bpm vs Max HR 165 bpm) · Khalil absent in S3 (illness)
The Streamlit dashboard includes 17 analysis sections built on Lap 2 data. It works with or without PostgreSQL (local CSV fallback).
400m time, Max HR, power, cadence
Second-by-second m/s curve
Dual-axis time/temperature, correlations
Real positions on the route
Pacing strategy by segment
HR drop after Lap 2
Interactive dashboard based on real data: 15 runs, 4 sessions, and 4 runners.
Before visualization, raw data extracted from PostgreSQL was standardized and modeled in Power Query to make the report understandable, robust, and presentation-ready.
Columns converted to correct types: durations as integers, pace as decimals, and dates as Date, to avoid DAX calculation errors.
All technical fields were renamed (allure_moyenne_s → Avg pace) so visuals remain understandable without technical context.
Tables activites, coureurs, seances, and meteo were joined directly in Power Query in a star-schema model.
Dedicated table containing all calculated measures: progress %, normalized 400m time, W/kg power corrected by real weight, and deviation from average.
Direct read from the performances_avec_meteo view: the FIT × weather × runners join was precomputed in the database and imported in one block.
Source: Open-Meteo · Parc de Champagne · Real hourly data
Arthur in S3 (5.3°C): Avg HR 150 vs 178 bpm in S1 for a similar time, likely because thermal dissipation was easier.
Four points are not enough for statistical conclusions: the trends are descriptive, not causal.
Adrien ran S4 at 12:34 PM, about 3 hours after the others. Weather was slightly different.
Record at 52s (2:04/km) in S2. Very stable (52–60s). Max cadence: 208 spm. Peak power: 686W.
92s → 79s across 4 sessions: −14%. Controlled HR. Slight S4 bias (different time).
Best run in S2 (71s, 2:53/km). S2 HR anomaly (115 bpm avg): likely sensor artifact.
Max HR 196 bpm in S1. Absent in S3 (illness). Higher cardiovascular cost than the others.
No generalization is possible. Each runner is their own control. Observed correlations have no statistical significance.
Temperature, humidity, and wind are correlated. S3 and S4 are both cold and humid, so it is impossible to disentangle the effects.
S1→S2 improvement may come from familiarity with the route, not real physical progress.
Being measured can influence effort. Relative effort vs max capacity is not constant across sessions.
Nutrition, sleep, accumulated fatigue, and stress: these variables may outweigh weather effects.
Arthur (57s) vs others (79–96s): comparing absolute HR or power is not meaningful. W/kg partially mitigates this bias.
Arthur is the fastest runner over 400m.
Adrien shows the strongest relative progression across sessions.
Khalil and Nathan reach very high maximum heart-rate values.
Heart rate tends to be lower in colder weather at similar effort.
Real value of the project: despite statistical limits, it demonstrates the full feasibility of a real-world data pipeline, from field collection to interactive visualization.
FIT → Python → PostgreSQL → Streamlit. Full VM automation. 15 runs analyzed. Scalable without manual intervention.
Second-by-second FIT data: acceleration profiles, 100m splits, and heart-rate recovery that remain invisible in summary CSV exports.
All biases were identified, documented, and integrated. The W/kg correction changes the rankings; without it, the analysis would be biased.
A consistent trend is visible (lower HR in colder weather at similar effort), but with n=4 sessions, no causal weather/performance correlation can be established. More sessions are needed.