Skip to content

v3.16.0

Latest
Compare
Choose a tag to compare
@probberechts probberechts released this 17 Dec 23:58
· 4 commits to master since this release

✨ Highlights ✨

Load DFL Open Data by @UnravelSports in #365

We've added support for loading a new public dataset! The dataset contains seven full matches of raw event and position data collected by Sportec Solutions from the German Men's Bundesliga season 2022/23 first and second division.

from kloppy import sportec

event_dataset = sportec.load_open_event_data(match_id="J03WMX")
tracking_dataset = sportec.load_open_tracking_data(match_id="J03WMX")

For more info about the dataset, see

Bassek, M., Weber, H., Rein, R., & Memmert, D. (2024). "An integrated dataset of synchronized spatiotemporal and event data in elite soccer." In Submission.

Standardized player positions by @DriesDeprest in #334

Instead of relying on provider-specific player positions, kloppy now implements a standardized PositionType.

>>> from kloppy import statsbomb

>>> event_dataset = statsbomb.load_open_data(match_id="15946")
>>> event = event_dataset.get_event_by_id("549567bd-36de-4ac8-b8dc-6b5d3f1e4be8")
>>> event.player.starting_position
<PositionType.LeftMidfield: ('Left Midfield', 'LM', 'WideMidfield')>

The positions are ordered hierarchically.

>>> from kloppy.domain import PositionType

>>> print(PositionType.LeftBack.parent) 
FullBack

>>> print(PositionType.Defender.is_subtype_of(PositionType.Defender))
True
>>> print(PositionType.LeftCenterBack.is_subtype_of(PositionType.Defender))  
True
>>> print(PositionType.LeftBack.is_subtype_of(PositionType.Midfielder))  
False

>>> print(PositionType.LeftCenterBack) 
Left Center Back
>>> print(PositionType.LeftCenterBack.code) 
LCB

Team formation changes by @DriesDeprest in #332

In addition to a starting_formation attribute, a Team entity now also has a formations attribute that holds the team's formation changes throughout the game.

>>> from kloppy import statsbomb

>>> event_dataset = statsbomb.load_open_data(match_id="15946")
>>> event = event_dataset.get_event_by_id("549567bd-36de-4ac8-b8dc-6b5d3f1e4be8")
>>> event.team.starting_formation
<FormationType.FOUR_FIVE_ONE: '4-5-1'>
>>> event.team.formations
TimeContainer[FormationType]({'P2T22:53': <FormationType.FOUR_FOUR_TWO: '4-4-2'>})

🚀 Other updates

🪲 Fixes

  • Fix common bug in parsing of UTC datetimes by @probberechts in #373
  • [Stats Perform - Event] Fix creation of goalkeeper events for event type 10/Save when an outfield player blocks a shot (qualifier 94) by @DriesDeprest in #335
  • [Stats Perform - Tracking] Recognize referee player type and handle accordingly by @DriesDeprest in #357
  • [Stats Perform - Tracking] Support frames with no player data by @DriesDeprest in #349
  • [Stats Perform - Tracking] Handle missing end period for abandoned matches by @DriesDeprest in #355
  • [SkillCorner] Support renaming "time" → "timestamp" by @UnravelSports in #338
  • [Tracab] Support new meta data format by @UnravelSports in #353
  • [Wyscout v3] Fix location for blocked crosses by @DriesDeprest in #343
  • Use positions in get_player_by_position by @DriesDeprest in #342

👷 Refactoring

🚨 Testing

  • [Wyscout v3] Use publicly available Wyscout v3 event data in tests by @DriesDeprest in #350

👋 New Contributors

Full Changelog: v3.15.0...v3.16.0