Case Study 01: Analyzing Pressing Intensity Using Tracking Data in the Bundesliga
Overview
The Bundesliga has been at the forefront of tracking data availability, with its partnership with AWS making positional data accessible to broadcasters and analysts since the 2019/20 season. This openness has accelerated research into pressing --- the tactical cornerstone of many German clubs' philosophies.
In this case study we use synthetic tracking data modelled on Bundesliga match characteristics to build a comprehensive pressing intensity analysis pipeline. The pipeline quantifies when, where, and how effectively a team presses, going well beyond aggregate metrics like PPDA (Passes Per Defensive Action) to capture the spatiotemporal dynamics of pressing sequences.
Objectives
- Detect pressing triggers from tracking data (moments when the defending team initiates a coordinated press).
- Compute counterpressure intensity (CPI) --- the collective closing speed of defenders toward the ball.
- Measure team compactness evolution during pressing sequences.
- Compare first-half and second-half pressing intensity to assess fatigue effects.
- Classify pressing outcomes (ball won, foul, press broken) and identify predictive spatial features.
Data and Setup
We simulate a full match of tracking data at 25 Hz for 22 players (plus ball), using a centre-origin coordinate system ($x \in [-52.5, 52.5]$, $y \in [-34, 34]$). The home team plays a high-pressing 4-2-3-1 formation reminiscent of several top Bundesliga sides.
Key parameters:
- Frame rate: 25 Hz
- Match duration: 95 minutes (including stoppage time)
- Coordinate system: Centre-origin, metres
- Pressing definition: At least 3 defending players within 15 m of the ball, moving toward it (closing speed > 0)
Step 1: Pressing Trigger Detection
A pressing trigger occurs when the defending team transitions from passive to active pressing. We define this algorithmically:
- Identify turnovers (ball changes team).
- In the 0.5 s following a turnover, count the number of defending players within 15 m of the ball with positive closing speed.
- If $\geq 3$ players qualify, mark the frame as a pressing trigger.
def detect_pressing_triggers(
tracking_df, ball_df, defending_team, radius=17.0, min_players=3
):
"""Detect frames where a coordinated press is initiated."""
# See code/case-study-code.py for full implementation
In our simulated match, the home team initiates 42 pressing sequences in the first half and 31 in the second half --- a 26% decline consistent with empirical Bundesliga data.
Step 2: Counterpressure Intensity
For each pressing sequence, we compute the CPI at each frame:
$$ \text{CPI}(t) = \frac{1}{|S|} \sum_{i \in S} s_i(t) \cdot \cos(\alpha_i(t)) $$
where $S$ is the set of defenders within 15 m of the ball, $s_i$ is their speed, and $\alpha_i$ is the angle between their velocity vector and the direction toward the ball.
Peak CPI values in our simulation:
| Half | Mean Peak CPI (m/s) | Max Peak CPI (m/s) |
|---|---|---|
| First | 3.8 | 7.6 |
| Second | 3.2 | 4.9 |
The 16% decline in mean peak CPI from first to second half is a clear fatigue signal.
Step 3: Team Compactness During Pressing
We track the defending team's stretch index and convex hull area during each pressing sequence:
- Stretch index at trigger: 16.2 m (compact)
- Stretch index at t+3s (successful press): 14.8 m (more compact)
- Stretch index at t+3s (failed press): 18.1 m (expanding --- players bypassed)
The relationship between compactness at the trigger moment and pressing success is strong: sequences starting with a stretch index below 14 m succeed 58% of the time, versus 32% for those starting above 16 m.
Step 4: Fatigue Effects on Pressing
We divide the match into 5-minute intervals and compute pressing metrics per interval:
- Pressing frequency: Triggers per 5 minutes
- CPI per trigger: Average counterpressure intensity
- Success rate: Fraction of presses resulting in ball recovery
All three metrics show a systematic decline beginning around the 65th minute, with a temporary recovery between minutes 70--75 (possibly reflecting the impact of substitutions). The sharpest decline is in CPI, which drops 22% from the first-half average in the final 15 minutes.
Step 5: Pressing Outcome Classification
We classify each pressing sequence into four outcomes:
| Outcome | Count | Avg CPI | Avg Stretch Index |
|---|---|---|---|
| Ball recovered | 28 | 4.1 | 15.5 |
| Foul won | 8 | 3.5 | 16.2 |
| Press broken (short pass) | 22 | 2.9 | 17.8 |
| Press broken (long ball) | 15 | 3.1 | 16.9 |
Successful presses are characterised by higher CPI and lower stretch index, confirming that coordinated, intense pressing is more effective than disorganised pressure.
Tactical Insights
-
Pressing asymmetry: The home team presses more aggressively down the left channel (55% of triggers), exploiting the opponent's right-back who is slower to distribute under pressure.
-
Goalkeeper as pressure valve: When the opponent involves their goalkeeper in build-up, the pressing team's CPI drops by 0.8 m/s on average, because the GK's positioning stretches the press.
-
Substitution timing: The data suggests that introducing a fresh pressing forward at minute 60--65 could maintain first-half pressing intensity for an additional 10--15 minutes.
Code Reference
The full implementation of this case study is provided in code/case-study-code.py (Section 1), including pressing trigger detection, CPI computation, compactness tracking, and fatigue visualisation.
Discussion Questions
- How would you adapt the pressing trigger detection for a team that uses a mid-block press rather than a high press? What radius and player-count thresholds would you adjust?
- The CPI metric weighs all defending players equally. Propose a modification that gives more weight to the player closest to the ball carrier.
- If the opposing team deliberately slows their build-up to tire the pressing team, how would this strategy appear in the CPI and success-rate metrics?