TacticScope is an end-to-end football analytics project that analyses 1,140 professional matches across La Liga, Premier League and Serie A (2015/16) using StatsBomb open data. It extracts tactical patterns, builds advanced metrics, and applies machine learning to uncover team playing styles.
- 4 Professional Visualisations — Shot maps, pass networks, pressing heatmaps, position maps
- 3 Tactical Metrics — PPDA (pressing intensity), build-up progression, defensive block depth
- ML Models (coming soon) — Tactical style clustering, formation classifier, custom xG model
- Live Dashboard (coming soon) — Interactive Streamlit app hosted on HuggingFace Spaces
- Source: StatsBomb Open Data (free, professional match data)
- Competitions: La Liga, Premier League, Serie A — 2015/16 season
- Scale: 1,140 matches | ~4.5 million events | 60 teams
- Python 3.11 | pandas | numpy | scikit-learn
- matplotlib | mplsoccer | StatsBombPy | Streamlit
- NetworkX | plotly | HuggingFace Spaces
TacticScope/
├── notebooks/
│ ├── 01_data_exploration.ipynb # Data collection and exploration
│ ├── 02_exploratory_analysis.ipynb # Visualisations and EDA
│ └── 03_feature_engineering.ipynb # Tactical metrics calculation
├── data/
│ ├── processed/
│ │ └── features/ # Calculated tactical metrics
│ └── raw/ # Raw event data (gitignored)
├── reports/ # Generated visualisations
├── src/ # Reusable source modules
└── requirements.txt
| Metric | Description | Insight |
|---|---|---|
| PPDA | Passes allowed per defensive action | Pressing intensity |
| Progressive Pass Rate | % of passes moving ball 10+ units forward | Build-up style |
| Final Third Entry Rate | % of passes entering danger zone | Attacking threat |
| Avg Defensive X | Average position of defensive actions | Block depth |
| Defensive Compactness | Spread of defensive actions | Organisation |
- Celta Vigo were the most aggressive pressers in all three leagues (PPDA: 4.49)
- Napoli played the deepest defensive line (avg x: 55.28) — Sarri's high block confirmed
- Leicester City's title winning style visible in data — low press, high direct progression
- Serie A teams cluster as passive pressers, La Liga as aggressive pressers
- Barcelona's selective central pressing confirmed by heatmap analysis
- Champions League free data limited to 1 match per season — switched to domestic leagues
- Location data stored as strings in CSV — built parse_loc() helper function
- Pass network pitch orientation flipped — fixed with y-axis mirroring
- Player position duplicates on season map — resolved with primary position deduplication
- PPDA values unrealistically low — identified wrong pitch half filter, corrected to x<=60
- PPDA denominator inflated by Pressure events — aligned with industry standard definition
# Clone repository
git clone https://github.com/swarooppawar/TacticScope.git
cd TacticScope
# Create conda environment
conda create -n tacticscope python=3.11
conda activate tacticscope
# Install dependencies
pip install -r requirements.txt
# Launch Jupyter
jupyter notebook- Phase 1 — Data Collection & Pipeline
- Phase 2 — Exploratory Data Analysis
- Phase 3 — Feature Engineering
- Phase 4 — ML Modelling (clustering, classification, xG)
- Phase 5 — Advanced Analytics (graph networks, pitch control)
- Phase 6 — Streamlit Dashboard & Deployment
Swaroop Pawar — AI & Data Science Engineer swaroop.p@somaiya.edu GitHub
Data provided by StatsBomb under their free data license