Home

Awesome

{soccerAnimate}

An R package to create 2D animations of soccer tracking data

<p align="center"> <img width="200" src="man/soccerAnimate.png"> </p>

How to install it?

# install.packages("remotes")
remotes::install_github("Dato-Futbol/soccerAnimate")

In case you have a previous version and you would like to update the package, don’t forget to add the argument force = T

Changelog

The following additions were added for the last version of the package (v1.1 at March 11th, 2024)

v1.0 (April 28th, 2023)

How to use it?

The package already has multiple functions to use, so it is usefulness to think about of them like a workflow for a either players or team level, as the following diagram shows:

<p align="center"> <img width="80%" src="man/mermaid-figure-1.png"> </p>

The functions allows you to do the following tasks:

1) To get and process the tracking data

The function get_tidy_data() reads, tidies and joins the rawdata of both the Home and Away teams.

Currently only data from the provider Metrica Sports is supported. Even though you can download the open tracking/event data following this link, it is also possible to get the processed data directly using the function get_tidy_data() with the URLs of rawdata like the following example for the Game #2:

library(soccerAnimate)
home_team_file <- "https://raw.githubusercontent.com/metrica-sports/sample-data/master/data/Sample_Game_2/Sample_Game_2_RawTrackingData_Home_Team.csv"
away_team_file <- "https://raw.githubusercontent.com/metrica-sports/sample-data/master/data/Sample_Game_2/Sample_Game_2_RawTrackingData_Away_Team.csv"
td <- get_tidy_data(home_team_file, away_team_file)

If you have another data provider or format, contact me in order to explore how can I help you adapting the code. I also could provide you some professional services related, even if you have tracking data from GPS devices. Check this link for more details.

2) To get events information

The function events_info() gets events information from the eventing dataset (Period, Team, Event, start and end time, start and end frame, etc.). You could get info for either shots, goals, free kicks or corner kicks. One of the current main usefulness of this is to know at which times/frames specific events occurs, then you will create both static plots and animations for those times/frames.

event_path = "https://raw.githubusercontent.com/metrica-sports/sample-data/master/data/Sample_Game_2/Sample_Game_2_RawEventsData.csv"
ed <- readr::read_csv(event_path)
goals <- events_info(ed, events = "GOAL")

# all_events <- events_info(ed, events = c("SHOT", "GOAL", "FREE KICK", "CORNER KICK"))

<img src="man/goals_info.png" style="width:80.0%" data-fig-align="center" />

Team level

3) To create a 2D static plot

The function soccer_plot() creates a static plot of one specific and unique frame. It is useful to explore and pre visualize your data, aesthetic and method setting, before to create the animation (whose creation time will be longer). You are able to export this plots as PNG files.

soccer_plot(tidy_data = td, target_frame = 12212, export_png = T)
<img src="man/plot.png" style="width:80.0%" data-fig-align="center" />

4) To create a 2D soccer animation

The function soccer_animate() creates 2D soccer animations using tracking data. You are able to set multiple arguments besides tidy tracking data, like the starting and the ending time to animate (in seconds, no frames!), geometric or spatial analysis method (options: “base”, “convexhull”, “voronoi”, “delaunay”), aesthetics setting (colors of pitch fill and lines, teams colors, titles, etc.), and some output settings. Most of this arguments are enabled also for soccer_plot() function.

# Example A: "base"
soccer_animate(td, 480, 490, "base", export_gif = T)
<img src="man/base.gif" style="width:80.0%" data-fig-align="center" />
# Example B "convexhull"
soccer_animate(td, 480, 490, "convexhull", export_gif = T, gif_name = "convexhull.gif")

<img src="man/convexhull.gif" style="width:80.0%" data-fig-align="center" />

# Example C: "voronoi"
soccer_animate(td, 2112, 2122, "voronoi", export_gif = T, gif_name = "voronoi.gif")

<img src="man/voronoi.gif" style="width:80.0%" data-fig-align="center" />

4) Team avg. postitioning and stats by ON/OFF ball possession states

With the function soccer_plot_poss() you can create a plot showing for each team the avg. position of players, its convex hull and position stats.

soccer_plot_poss(td, event_path, team = "Away", pitch_fill = "grey40",
                 on_ball_col = "white", off_ball_col = "#74a9cf")

<img src="man/avg_pos_stats.png" style="width:80.0%" data-fig-align="center" />

Player level

5) Player stats calculation and visualization:

With the function players_stats() you calculate for every player the minutes played, avg. speed, total distance and distance for different speed ranges.

Then you are able to visualize those stats with the function players_stats_graph() (Home team by default):

player_stats = players_stats(td)
players_stats_graph(player_stats, export_png = T)

<img src="man/players_stats.png" style="width:80.0%" data-fig-align="center" />

<img src="man/players_graph.png" style="width:80.0%" data-fig-align="center" />

6) To get players sprints information:

With the function sprints_info() you apply the needed data processing to get the number of sprints that every player for a chosen team (Home team by default) made. A sprint is considered when a player run a very high speed (higher than 7 [m/s]) for at least 1 second.

With this information you can observe a player ranking based on the number of sprints:

sprints = sprints_info(td)

library(dplyr)
player_sprints = sprints %>% 
                 summarise(n_sprint = sum(start)) %>% 
                 arrange(desc(n_sprint))

<img src="man/players_sprints.png" style="width:25.0%" data-fig-align="center" />

7) To create a player plot with specific actions:

With the function player_plot() you can create a plot showing where and when (labels show Time[s]) specific actions made by a player happened.

For example, the sprints made by the player 10 of the Home team:

player10_starts = sprints %>% filter(player == 10 & start == 1)
player10_ends = sprints %>% filter(player == 10 & end == 1)

player_plot(td, 10, player10_starts$n, player10_ends$n, export_png = T)

<img src="man/sprints_player_10.png" style="width:80.0%" data-fig-align="center" />

8) To create a player animation highlighting :

With the function player_animate() you are able to create a 2D animation for the specific time range when one specific player sprint happened.

player_animate(td, 10, player10_starts$n[1], player10_ends$n[1], export_gif = T)

<img src="man/player_10_sprint_1.gif" style="width:80.0%" data-fig-align="center" />

General considerations

Currently working on: