Skip to main content

A project to analyze sports event and tracking data

Project description

unravelsports logo

UnravelSports tl;dr legal

๐ŸŒ€ pip install unravelsports

๐ŸŒ€ Documentation

Finally, we have documentation! Check out:

๐Ÿ‘‰ unravelsports.readthedocs.io

๐ŸŒ€ What is it?

The unravelsports package aims to aid researchers, analysts and enthusiasts by providing intermediary steps in the complex process of converting raw sports data into meaningful information and actionable insights.

This package currently supports:

๐ŸŒ€ Features

Polars DataFrames

โšฝ๐Ÿˆ Convert Tracking Data into Polars DataFrames for rapid data conversion and data processing.

โšฝ For soccer we rely on Kloppy and as such we support Sportec, SkillCorner, PFF / GradientSports, Metrica, StatsPerform, Tracab (CyronHego), SecondSpectrum, HawkEye and Signality tracking data.

from unravel.soccer import KloppyPolarsDataset

from kloppy import sportec

kloppy_dataset = sportec.load_open_tracking_data()
kloppy_polars_dataset = KloppyPolarsDataset(
    kloppy_dataset=kloppy_dataset
)
period_id timestamp frame_id ball_state id x y z team_id position_name game_id vx vy vz v ax ay az a ball_owning_team_id is_ball_carrier
0 1 0 days 00:00:00 10000 alive DFL-OBJ-00008F -20.67 -4.56 0 DFL-CLU-000005 RCB DFL-MAT-J03WPY 0.393 -0.214 0 0.447 0 0 0 0 DFL-CLU-00000P False
1 1 0 days 00:00:00 10000 alive DFL-OBJ-0000EJ -8.86 -0.94 0 DFL-CLU-000005 UNK DFL-MAT-J03WPY -0.009 0.018 0 0.02 0 0 0 0 DFL-CLU-00000P False
2 1 0 days 00:00:00 10000 alive DFL-OBJ-0000F8 -2.12 9.85 0 DFL-CLU-00000P RM DFL-MAT-J03WPY 0 0 0 0 0 0 0 0 DFL-CLU-00000P False
3 1 0 days 00:00:00 10000 alive DFL-OBJ-0000NZ 0.57 23.23 0 DFL-CLU-00000P RB DFL-MAT-J03WPY 0.179 -0.134 0 0.223 0 0 0 0 DFL-CLU-00000P False
4 1 0 days 00:00:00 10000 alive DFL-OBJ-0001HW -46.26 0.08 0 DFL-CLU-000005 GK DFL-MAT-J03WPY 0.357 0.071 0 0.364 0 0 0 0 DFL-CLU-00000P False

๐Ÿˆ For American Football we use BigDataBowl Data directly.

from unravel.american_football import BigDataBowlDataset

bdb = BigDataBowlDataset(
    tracking_file_path="week1.csv",
    players_file_path="players.csv",
    plays_file_path="plays.csv",
)

Graph Neural Networks

โšฝ๐Ÿˆ Convert Polars Dataframes into Graphs to train graph neural networks. These Graphs can be used with PyTorch Geometric or Spektral. unravelsports allows you to randomize and split data into train, test and validation sets along matches, sequences or possessions to avoid leakage and improve model quality. And finally, train, validate and test your (custom) Graph model(s) and easily predict on new data.

from unravel.soccer import SoccerGraphConverter

converter = SoccerGraphConverter(
    dataset=kloppy_polars_dataset,
    self_loop_ball=True,
    adjacency_matrix_connect_type="ball",
    adjacency_matrix_type="split_by_team",
    label_type="binary",
    defending_team_node_value=0.1,
    non_potential_receiver_node_value=0.1,
    random_seed=False,
    pad=False,
    verbose=False,
)

Pressing Intensity

Compute Pressing Intensity for a whole game (or segment) of Soccer tracking data.

See Pressing Intensity Jupyter Notebook for an example how to create mp4 videos.

from unravel.soccer import PressingIntensity

import polars as pl

model = PressingIntensity(
    dataset=kloppy_polars_dataset
)
model.fit(
    start_time = pl.duration(minutes=1, seconds=53),
    end_time = pl.duration(minutes=2, seconds=32),
    period_id = 1,
    method="teams",
    ball_method="max",
    orient="home_away",
    speed_threshold=2.0,
) 

1. FC Kรถln vs. FC Bayern Mรผnchen (May 27th 2023)


Formation and Position Identification

Compute Elastic Formation and Position Identification, EFPI for individual frames, possessions, periods or specific time intervals for Soccer.

For more information on all possibilities for "every" check out Polars Documentation.

from unravel.soccer import EFPI

model = EFPI(dataset=kloppy_polars_dataset)
model.fit(
    # Default 65 formations , or specify a subset (e.g. ["442" , "433"])
    formations=None,
    # specific time intervals (e.g. 1m, 1m14s, 2m30s etc.), or specify "possession", "period" or "frame".
    every="5m",
    substitutions="drop",
    change_threshold=0.1,
    change_after_possession=True,
)

Elastic Formation and Position Identification Example

โŒ› More to come soon...!

๐ŸŒ€ Quick Start

๐Ÿ“– โšฝ The Quick Start Jupyter Notebook explains how to convert any positional tracking data from Kloppy to Spektral GNN in a few easy steps while walking you through the most important features and documentation.

๐Ÿ“– โšฝ The Graph Converter Tutorial Jupyter Notebook gives an in-depth walkthrough.

๐Ÿ“– ๐Ÿˆ The BigDataBowl Converter Tutorial Jupyter Notebook gives an guide on how to convert the BigDataBowl data into Graphs.

๐Ÿ“– โšฝ The Pressing Intensity Tutorial Jupyter Notebook gives a description on how to create Pressing Intensity videos.

๐ŸŒ€ Additional Reading

๐Ÿ“– A Graph Neural Network Deep-dive into Successful Counterattacks {A. Sahasrabudhe J. Bekkers, 2023}

๐ŸŽค Cutting Edge Football Analytics: using polars, keras and spektral (PyData London, 2025)

๐ŸŒ€ Installation

The easiest way to get started is:

pip install unravelsports

๐ŸŒ€ Licenses

This project is licensed under the Mozilla Public License Version 2.0 (MPL), which requires that you include a copy of the license and provide attribution to the original authors. Any modifications you make to the MPL-licensed files must be documented, and the source code for those modifications must be made open-source under the same license.

๐ŸŒ€ Citation

If you use this repository for any educational purposes, research, project etc., please reference both:

๐Ÿ“Ž The unravelsports package.

BibTex
@software{unravelsports2024repository,
  author = {Bekkers, Joris},
  title = {unravelsports},
  version = {2.0.0},
  year = {2024},
  publisher = {GitHub},
  url = {https://github.com/unravelsports/unravelsports}
}

๐Ÿ“Ž Bekkers, J., & Sahasrabudhe, A. (2024). A Graph Neural Network deep-dive into successful counterattacks. arXiv preprint arXiv:2411.17450.

BibTex
@inproceedings{sahasrabudhe2023graph,
  title={A Graph Neural Network deep-dive into successful counterattacks},
  author={Sahasrabudhe, Amod and Bekkers, Joris},
  booktitle={17th Annual MIT Sloan Sports Analytics Conference. Boston, MA, USA: MIT},
  pages={15},
  year={2023}
}

๐Ÿ“Ž Bekkers, J. (2024). Pressing Intensity: An Intuitive Measure for Pressing in Soccer. arXiv preprint arXiv:2501.04712.

BibTex
@article{bekkers2024pressing,
  title={Pressing Intensity: An Intuitive Measure for Pressing in Soccer},
  author={Bekkers, Joris},
  journal={arXiv preprint arXiv:2501.04712},
  year={2024}
}

๐Ÿ“Ž Bekkers, J. (2025). EFPI: Elastic Formation and Position Identification in Football (Soccer) using Template Matching and Linear Assignment. arXiv preprint arXiv:2506.23843.

BibTex
@article{bekkers2025efpi,
  title={EFPI: Elastic Formation and Position Identification in Football (Soccer) using Template Matching and Linear Assignment},
  author={Bekkers, Joris},
  journal={arXiv preprint arXiv:2506.23843},
  year={2025}
}

๐ŸŒ€ Social Media

<img alt="LinkedIn" width="40px" src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png"/> <img alt="Bluesky" width="40px" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Bluesky_Logo.svg/2319px-Bluesky_Logo.svg.png"/>

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

unravelsports-1.2.1.tar.gz (108.0 kB view details)

Uploaded Source

Built Distribution

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

unravelsports-1.2.1-py3-none-any.whl (108.2 kB view details)

Uploaded Python 3

File details

Details for the file unravelsports-1.2.1.tar.gz.

File metadata

  • Download URL: unravelsports-1.2.1.tar.gz
  • Upload date:
  • Size: 108.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for unravelsports-1.2.1.tar.gz
Algorithm Hash digest
SHA256 ba674a29ae945394cce3d5a816c6ce67e665a05abbad35e9424e6aba9726afd9
MD5 a18e9eff22612cf21b3a8ec335625efa
BLAKE2b-256 f4d1397e8042611c9247bcd2f943d69b1f13dd049f843fd3aec69055417c999c

See more details on using hashes here.

File details

Details for the file unravelsports-1.2.1-py3-none-any.whl.

File metadata

  • Download URL: unravelsports-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 108.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for unravelsports-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4e85d94d475dfd1c07d7665e2b89c86e21fee60ea1288ba750d049ed77c85200
MD5 6ea246fb42f8163b427018601262eb95
BLAKE2b-256 55cca418b8cc6bc441180a1bea34b7da687f54c7ef77afb23771845997d34cde

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