KK-1729/f1-telemetry
F1 Telemetry Dashboard
A professional pit-wall style Formula 1 telemetry and race analysis dashboard built with Plotly Dash and FastF1. Load any grand prix session from 2018–2025 and analyse driver performance corner-by-corner.
Features
Stack
- [FastF1 3.8](https://docs.fastf1.dev/) — historical session data (2018–2025), telemetry, timing, weather
- [Plotly Dash 2.18](https://dash.plotly.com/) — reactive web framework with background callbacks
- [dash-bootstrap-components](https://dash-bootstrap-components.opensource.faculty.ai/) — DARKLY theme
- [Plotly 5.24](https://plotly.com/python/) — interactive charts
- [pandas](https://pandas.pydata.org/) / [NumPy](https://numpy.org/) / [SciPy](https://scipy.org/) — data processing and regression
- [diskcache](https://grantjenks.com/docs/diskcache/) — background callback manager (local dev)
- [Celery](https://docs.celeryq.dev/) + [Redis](https://redis.io/) — background callback manager (production)
Quick Start
1. Clone and set up
git clone https://github.com/yourname/f1-telemetry.git
cd f1-telemetry
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt2. Run
./run.sh
# or
python app.pyOpen http://localhost:8050 in your browser.
The first time you load a session FastF1 will download data from the internet and cache it to ./cache/. Subsequent loads of the same session are instant.
Environment Variables
Copy .env.example to .env to override defaults:
Project Structure
f1-telemetry/
├── app.py # Dash app factory and root layout
├── wsgi.py # Gunicorn/WSGI entrypoint
├── run.sh # Local dev launcher
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
│
├── config/
│ ├── settings.py # Env-driven configuration
│ └── constants.py # Colour tokens, compound colours, font
│
├── data/
│ ├── loader.py # FastF1 session loading (LRU-cached), telemetry helpers
│ ├── transforms.py # Analytics: degradation regression, minisectors, evolution
│ ├── openf1.py # OpenF1 REST client for live session data
│ └── schedule.py # Season schedule helpers
│
├── charts/
│ ├── base.py # Shared dark-theme figure factory and axis helpers
│ ├── telemetry.py # Multi-panel synchronized telemetry chart
│ ├── delta.py # Time delta trace between two drivers
│ ├── track_map.py # 2D circuit scatter + minisector strip
│ ├── degradation.py # Tyre degradation scatter and stint timeline
│ ├── evolution.py # Session lap time evolution + weather overlay
│ └── placeholders.py # Skeleton ghost figures shown before a session loads
│
├── pages/
│ ├── session_explorer.py # Page 1: Session selector + stat cards + results table
│ ├── telemetry_compare.py # Page 2: Driver telemetry overlay
│ ├── track_map_page.py # Page 3: Track map + minisector dominance
│ ├── tyre_degradation.py # Page 4: Degradation curves + stint timeline
│ └── track_evolution.py # Page 5: Track rubbering-in + weather
│
├── components/
│ ├── navbar.py # Top navigation bar
│ ├── stat_card.py # KPI cards (winner, fastest lap, weather)
│ ├── loading_overlay.py # F1-car progress bar overlay for background loads
│ └── driver_picker.py # Colour-coded driver checklist
│
├── assets/
│ ├── custom.css # Dark theme, F1 aesthetic, scrollbars, results table
│ └── f1_logo.svg # Official F1 logo
│
└── cache/ # FastF1 disk cache — gitignored, grows ~5–150 MB per sessionSession Types
Sprint weekends replace FP2 and FP3 with Sprint Qualifying and the Sprint race. Selecting FP2/FP3 on a sprint weekend will show a helpful error.
Production Deployment
Use Docker Compose to run the app with Redis and a Celery worker for production-grade background callbacks:
docker-compose up --buildThis starts:
- Redis — message broker
- Celery worker — handles background session loading (concurrency 2)
- Dash app — served by Gunicorn on port 8050
For single-server deploys without Redis, just run the container directly — diskcache is used automatically when REDIS_URL is not set.
Data & Caching
FastF1 uses a two-stage cache:
- HTTP cache — raw API responses stored as SQLite in
./cache/ - Pickle cache — parsed session objects
The app adds a Python @lru_cache (max 8 sessions) on top so navigating between pages never re-loads a session from disk.
Cache size grows roughly 5–150 MB per session depending on telemetry density. The ./cache/ directory is gitignored.
Notes
- Sprint Qualifying results — FastF1 cannot reconstruct the SQ1/SQ2/SQ3 sector splits without race control messages in the cache. Results are shown ranked by best overall lap time instead.
- Telemetry x-axis is distance (metres), not time — this enables true corner-by-corner comparison regardless of when each driver hit a given point on track.
- macOS fork safety —
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YESandMPLBACKEND=Aggare set at startup to prevent crashes in forked Dash background callback workers.
