Usage

To use pitchly in a project:

import pitchly

As of now , pitchly works only with Metrica Sports data format (old and new EPTS FIFA). So the recommended starting point for now is from pitchly.metrica import ...

Data Loading

kloppy is used to load the tracking and event data from Metrica. Click here for the sample open data

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import glob
import kloppy

# match directory
match_dir = "/match/folder/with/metrica/data/"

# tracking data [METRICA]
metadata_file = glob.glob(f"{match_dir}/*metadata*")[0]  # xml file
tracking_file = glob.glob(f"{match_dir}/*tracking*")[0]  # txt file

dataset = kloppy.load_epts_tracking_data(raw_data_filename=tracking_file, metadata_filename=metadata_file, options=None)

metadata = dataset.metadata
tracking_dataset = kloppy.to_pandas(dataset)

# event data [METRICA]
events_file = glob.glob(f"{match_dir}/*events*")[0]  # txt file

event_dataset = kloppy.load_metrica_json_event_data(
    raw_data_filename=events_file, metadata_filename=metadata_file, options=None
)

Basic Football Pitch

pitchly can be used to plot a basic football pitch (currently Metrica data dimensions) and building further on it as needed.

1
2
3
4
from pitchly.pitch import Pitch

pitch = Pitch()
fig = pitch.plot_pitch()
Empty pitch

This is however not needed for any further plots as demonstrated below.

Tracking Data

1
2
3
4
5
# import the pitchly wrapper for metrica tracking data
from pitchly.metrica import TrackingData

# feed the loaded data
data = TrackingData(tracking_dataset,metadata)

Plot Frame by FrameID

data.plot_frame(frameID=3264)
Output of plot_frame by frameID

Plot Frame by Time

data.plot_frame(time='17:20')
Output of plot_frame by time

Plot Sequence by FrameIDs

You can plot a sequence of frames with a slider to animate/track an event.

data.plot_sequence(f0=15850,f1=15950)
Output of plot_sequence by frameID

Plot Sequence by Time

Or use the start time and end time for an interval sequence.

data.plot_sequence(t0='72',t1='72:06')
Output of plot_sequence by time

Pitch Control

The pitch control is calculated by adapting Laurie Shaw’s work on William Spearman’s model. Since generating pitch control visualization on the fly gets sluggish, it is recommended to proceed with slight patience using the sliders (the pitch control overlay reloads with a tiny delay for every frame). The example shown here is for a very small time range (5 seconds / 125 frames) and generating the viz takes 7 minutes.

data.plot_sequence(t0='72',t1='72:05', pitch_control = True)
Output of plot_sequence by time

Generating pitch control overlay for individual frame/time inputs is fairly faster.

data.plot_frame(time='17:20', pitch_control = True)
Output of plot_frame by time

Event Data

1
2
3
4
5
# import the pitchly wrapper for metrica event data
from pitchly.metrica import EventData

# feed the loaded data
data = EventData(event_dataset.events)

You can now plot various events cumulatively from the match by calling for type

Shots

data.plot(type="shots")
shots

You can set trace=True to see the trace of the shots

Goals

data.plot(type="goals")
goals

You can set trace=True to see the trace of the goals

Corners

data.plot(type="corners")
corners

Freekicks

data.plot(type="freekicks")
freekicks

You can set trace=True to see the trace of the freekicks

Challenges

data.plot(type="challenges")
challenges

Challenges do not have trace option

Recoveries

data.plot(type="recoveries")
recoveries

Recoveries do not have trace option

Shot Assists

data.plot(type="shot_assists")
shot assists

You can set trace=True to see the trace of the shot assists

Assists

data.plot(type="assists")
assists

You can set trace=True to see the trace of the assists

Passes

data.plot(type="passes")
passes

Passers

data.plot(type="passers")
passers

Receivers

data.plot(type="receivers")
receivers

Plot Event by Index

You can plot a specific event with its chain as follows:

data.plot(index=3478)
event chain

In order to know the index, you can browse the subset of choice using a kloppy helper:

kloppy.to_pandas(data.get_shots(),
                 additional_columns={'index_to_plot': lambda row: row.raw_event['index']}).set_index('index_to_plot')

Old Metrica Format (csv)

The older samples of Metrica data follow the .csv format and they can be loaded and used with pitchly in the following way:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import glob
from pitchly.utils import load_data
from pitchly.metrica_old import TrackingData,EventData

# match directory
match_dir = "/match/folder/with/metrica/data/"

# load the data
tracking_home, tracking_away, events = load_data(match_dir)

# tracking
data = TrackingData(tracking_home, tracking_away)
data.plot_sequence(...)

# events
data = data = EventData(events)
data.plot(type="shots", trace=True)