Skip to main content

A spatial analytics computation engine for football/soccer tracking data

Project description

PitchAura

A spatial analytics computation engine for football/soccer tracking data.

PyPI version Python License: GPL v3

PitchAura transforms raw player tracking coordinates into spatial control matrices, Voronoi territories, tactical metrics, and cognitive vision models — built on NumPy/SciPy with no mandatory heavy dependencies.


Features

Module What it does
Space / Pitch Control Kinematic control model (Spearman 2018) + Voronoi tessellation
Tactics Space creation, passing lane lifespan, defensive line-breaking pockets
Cognitive Player vision cones, blind-spot maps, VisionModel
Sync Frame alignment across tracking streams + moving-average / Kalman filtering
I/O kloppy adapter (from_tracking, from_events)
Viz Plotly-based pitch control heatmaps, Voronoi plots, animations

Installation

pip install pitch-aura

Optional extras

# kloppy I/O adapter
pip install "pitch-aura[kloppy]"

# Plotly visualisation
pip install "pitch-aura[viz]"

# Everything
pip install "pitch-aura[kloppy,viz]"

Runtime requirements: Python ≥ 3.12, NumPy ≥ 1.24, SciPy ≥ 1.10, pandas ≥ 2.0.


Quick Start

Build a FrameRecord manually

import numpy as np
import pitch_aura as pa

frame = pa.FrameRecord(
    frame_id=1,
    timestamp=0.04,
    home_positions=np.array([[30.0, 0.0], [20.0, 10.0]]),   # (N, 2) metres
    away_positions=np.array([[-25.0, 5.0], [-15.0, -8.0]]),
    home_velocities=np.array([[2.0, 0.5], [1.0, -1.0]]),
    away_velocities=np.array([[-1.5, 0.0], [-2.0, 1.0]]),
    home_team_id="home",
    ball_position=np.array([5.0, 0.0]),
)

Kinematic pitch control

model = pa.KinematicControlModel()
grid = model.compute(frame)          # returns ProbabilityGrid
print(grid.values.shape)             # (68, 105) by default

Voronoi territories

voronoi = pa.VoronoiModel()
result = voronoi.compute(frame)      # returns VoronoiResult
# result.regions: list of (player_idx, team, polygon_vertices) tuples

Load from kloppy

# pip install "pitch-aura[kloppy]"
import kloppy
dataset = kloppy.tracab.load(...)

sequence = pa.from_tracking(dataset)   # FrameSequence
frame = sequence.frames[0]             # FrameRecord

Tactics

from pitch_aura.tactics.space_creation import space_creation
from pitch_aura.tactics.passing_lanes import passing_lane_lifespan
from pitch_aura.tactics.line_breaking import line_breaking_pockets

# How much space each attacking player is creating
scores = space_creation(frame, model)

# How many frames a passing lane stays open
lifespan = passing_lane_lifespan(sequence, passer_idx=7, receiver_idx=9, model=model)

# Pockets in the defensive line
pockets = line_breaking_pockets(frame)
for p in pockets:
    print(f"Pocket at depth {p.line_depth:.1f}m, y={p.y_left:.1f}{p.y_right:.1f}m")

Cognitive Models

from pitch_aura.cognitive.vision_cone import player_heading, vision_cone_mask
from pitch_aura import VisionModel

# Per-frame vision cone mask for a single player
heading = player_heading(frame, player_idx=0, team="home")
mask = vision_cone_mask(frame, player_idx=0, team="home", grid=grid)

# Full VisionModel: blind-spot pressure surface
vision = VisionModel()
pressure = vision.blind_spot_pressure(frame, grid)

Sync Utilities

from pitch_aura.sync.alignment import align
from pitch_aura.sync.filters import smooth

# Align two FrameSequences by timestamp
aligned_home, aligned_away = align(seq_home, seq_away)

# Smooth positions with a Kalman filter
smoothed = smooth(sequence, method="kalman")

Visualisation

Requires pip install "pitch-aura[viz]". All functions return plotly.graph_objects.Figure and never call .show().

from pitch_aura.viz import plot_pitch_control, plot_voronoi_control

# Pitch control heatmap with player overlay
fig = plot_pitch_control(grid, frame, home_team_id="home")
fig.write_html("pitch_control.html")

# Voronoi territories
from pitch_aura.viz import plot_voronoi_control
fig = plot_voronoi_control(result, frame, home_team_id="home")
fig.show()

# Frame-by-frame animation
from pitch_aura.viz import animate_sequence
fig = animate_sequence(sequence, model)
fig.write_html("match_animation.html")

Composable low-level API

from pitch_aura.viz._pitch_draw import pitch_background
from pitch_aura.viz.heatmap import plot_heatmap
from pitch_aura.viz.players import plot_players
from pitch_aura.viz.tactics import plot_pockets, plot_passing_lane

fig = pitch_background()
fig = plot_heatmap(grid, fig=fig)
fig = plot_players(frame, fig=fig, show_pitch=False)
fig = plot_pockets(pockets, fig=fig)

API Reference

Core types

Class Description
FrameRecord Single tracking frame: positions, velocities, team IDs, ball
FrameSequence Ordered sequence of frames + PitchSpec
ProbabilityGrid (H, W) control probability array with coordinate metadata
VoronoiResult Clipped Voronoi regions per player
PitchSpec Pitch dimensions and coordinate convention
EventRecord Discrete event (pass, shot, etc.) aligned to a frame

Models

Class / function Description
KinematicControlModel Spearman (2018) time-to-intercept pitch control
VoronoiModel Mirror-augmented Voronoi with Sutherland-Hodgman clipping
VisionModel Sigmoid vision cone + blind-spot pressure surface

Acknowledgements

The kinematic pitch control model is based on:

Spearman, W. (2018). Beyond Expected Goals. MIT Sloan Sports Analytics Conference.


License

GNU General Public License v3.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pitch_aura-0.1.0.tar.gz (14.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pitch_aura-0.1.0-py3-none-any.whl (61.0 kB view details)

Uploaded Python 3

File details

Details for the file pitch_aura-0.1.0.tar.gz.

File metadata

  • Download URL: pitch_aura-0.1.0.tar.gz
  • Upload date:
  • Size: 14.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pitch_aura-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6d2b775d72e2c3d76aaab41b1592e1649a126b921ffb2a305c0ae04d22b3a0bb
MD5 5a20ed222b393195d048fcb09ef0dbd8
BLAKE2b-256 6ca88929f97cdbd7265186022d79b7bf8d0ec150f52b6d08085e5e84f695e6c1

See more details on using hashes here.

File details

Details for the file pitch_aura-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pitch_aura-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 61.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pitch_aura-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 17e91bc00add73920a4ac76bad11a1d3842b54443ee591c7d84bc83d097dbab9
MD5 432c95776368d00c7866b81b277423fa
BLAKE2b-256 c94870efa71bc80492d0aff43434f9cbb29a421a1bcb747df2dd23d54bffdea8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page