mplsoccer.pitch module

Module containing: Pitch and VerticalPitch, which are used to plot pitches in mplsoccer

class mplsoccer.pitch.Pitch(pitch_type='statsbomb', half=False, pitch_color=None, line_color=None, line_alpha=1, linewidth=2, linestyle=None, line_zorder=0.9, spot_scale=0.002, spot_type='circle', stripe=False, stripe_color='#c2d59d', stripe_zorder=0.6, pad_left=None, pad_right=None, pad_bottom=None, pad_top=None, positional=False, positional_zorder=0.8, positional_linewidth=None, positional_linestyle=None, positional_color='#eadddd', positional_alpha=1, shade_middle=False, shade_color='#f2f2f2', shade_alpha=1, shade_zorder=0.7, pitch_length=None, pitch_width=None, goal_type='line', goal_alpha=1, goal_linestyle=None, axis=False, label=False, tick=False, corner_arcs=False)[source]

Bases: BasePitchPlot

Attributes:
formations

Return a list of valid mplsoccer formations.

formations_dataframe

Return a dataframe of mplsoccer formations, positions and coordinates.

Methods

annotate(text, xy[, xytext, ax])

Utility wrapper around ax.annotate which automatically flips the xy and xytext coordinates if the pitch is vertical.

arrows(xstart, ystart, xend, yend, *args[, ax])

Utility wrapper around matplotlib.axes.Axes.quiver.

bin_statistic(x, y[, values, statistic, ...])

Calculates binned statistics using scipy.stats.binned_statistic_2d.

bin_statistic_positional(x, y[, values, ...])

Calculates binned statistics for the Juego de posición (position game) concept.

calculate_angle_and_distance(xstart, ystart, ...)

Calculates the angle in radians counter-clockwise and the distance between a start and end location.

convexhull(x, y)

Get lines of Convex Hull for a set of coordinates

draw([ax, figsize, nrows, ncols, ...])

Draws the specified soccer/ football pitch(es).

flip_side(x, y, flip)

A method to flip the coordinates to the other side of the pitch.

flow(xstart, ystart, xend, yend[, bins, ...])

Create a flow map by binning the data into cells and calculating the average angles and distances.

formation(formation[, positions, kind, ...])

A method to plot formations

get_formation(formation)

Get a formation.

get_positions([line, second_striker])

Get the player positions.

goal_angle(x, y[, ax, goal])

Plot a polygon with the angle to the goal using matplotlib.patches.Polygon.

grid([figheight, nrows, ncols, grid_height, ...])

A helper to create a grid of pitches in a specified location

grid_dimensions(figwidth, figheight, nrows, ...)

A helper method to propose a grid_width and grid_height for grid based on the inputs.

heatmap(stats[, ax])

Utility wrapper around matplotlib.axes.Axes.pcolormesh which automatically flips the x_grid and y_grid coordinates if the pitch is vertical.

heatmap_positional(stats[, ax])

Plots several heatmaps for the different Juegos de posición areas.

hexbin(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.hexbin, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

inset_axes(x, y[, width, height, aspect, ...])

A function to create an inset axes.

inset_image(x, y, image[, width, height, ax])

Adds an image as an inset_axes

jointgrid([figheight, left, grid_width, ...])

Create a grid with a pitch at the center and (marginal) axes at the sides of the pitch.

kdeplot(x, y[, ax])

Utility wrapper around seaborn.kdeplot, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

label_heatmap(stats[, str_format, ...])

Labels the heatmap(s) and automatically flips the coordinates if the pitch is vertical.

lines(xstart, ystart, xend, yend[, color, ...])

Plots lines using matplotlib.collections.LineCollection.

plot(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.plot, which automatically flips the x and y coordinates if the pitch is vertical.

polygon(verts[, ax])

Plot polygons.

scatter(x, y[, rotation_degrees, marker, ax])

Utility wrapper around matplotlib.axes.Axes.scatter, which automatically flips the x and y coordinates if the pitch is vertical.

text(x, y, s[, ax])

Utility wrapper around ax.text which automatically flips the x/y coordinates if the pitch is vertical.

triplot(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.triplot

voronoi(x, y, teams)

Get Voronoi vertices for a set of coordinates.

annotate(text, xy, xytext=None, ax=None, **kwargs)

Utility wrapper around ax.annotate which automatically flips the xy and xytext coordinates if the pitch is vertical.

Annotate the point xy with text. See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.annotate.html

Parameters:
  • text (str) – The text of the annotation.

  • xy ((float, float)) – The point (x, y) to annotate.

  • xytext ((float, float), optional) – The position (x, y) to place the text at. If None, defaults to xy.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.annotate.)

Returns:

annotation

Return type:

matplotlib.text.Annotation

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.annotate(text='center', xytext=(50, 50), xy=(60, 40), ha='center', va='center',
...                ax=ax, arrowprops=dict(facecolor='black'))
arrows(xstart, ystart, xend, yend, *args, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.quiver. Quiver uses locations and direction vectors usually. Here these are instead calculated automatically from the start and endpoints of the arrow. The function also automatically flips the x and y coordinates if the pitch is vertical.

Plot a 2D field of arrows. See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.quiver.html

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates of the lines.

  • C (1D or 2D array-like, optional) – Numeric data that defines the arrow colors by colormapping via norm and cmap. This does not support explicit colors. If you want to set colors directly, use color instead. The size of C must match the number of arrow locations.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • width (float, default 4) – Arrow shaft width in points.

  • headwidth (float, default 3) – Head width as a multiple of the arrow shaft width.

  • headlength (float, default 5) – Head length as a multiple of the arrow shaft width.

  • headaxislength (float, default: 4.5) – Head length at the shaft intersection. If this is equal to the headlength then the arrow will be a triangular shape. If greater than the headlength then the arrow will be wedge shaped. If less than the headlength the arrow will be swept back.

  • color (color or color sequence, optional) – Explicit color(s) for the arrows. If C has been set, color has no effect.

  • linewidth or linewidths or lw (float or sequence of floats) – Edgewidth of arrow.

  • edgecolor or ec or edgecolors (color or sequence of colors or ‘face’)

  • alpha (float or None) – Transparency of arrows.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.quiver.)

Returns:

PolyCollection

Return type:

matplotlib.quiver.Quiver

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.arrows(20, 20, 45, 80, ax=ax)
>>> from mplsoccer.quiver import arrows
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> arrows([0.1, 0.4], [0.1, 0.5], [0.9, 0.4], [0.8, 0.8], ax=ax)
>>> ax.set_xlim(0, 1)
>>> ax.set_ylim(0, 1)
bin_statistic(x, y, values=None, statistic='count', bins=(5, 4), normalize=False, standardized=False)

Calculates binned statistics using scipy.stats.binned_statistic_2d.

This method automatically sets the range, changes the scipy defaults, and outputs the grids and centers for plotting.

The default statistic has been changed to count instead of mean. The default bins have been set to (5,4).

Parameters:
  • x, y, values (array-like or scalar.) – Commonly, these parameters are 1D arrays. If the statistic is ‘count’ then values are ignored.

  • dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class

  • statistic (string or callable, optional) – The statistic to compute (default is ‘count’). The following statistics are available: ‘count’ (default), ‘mean’, ‘std’, ‘median’, ‘sum’, ‘min’, ‘max’, ‘circmean’ or a user-defined function. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic_2d.html

  • bins (int or [int, int] or array_like or [array, array], optional) –

    The bin specification.
    • the number of bins for the two dimensions (nx = ny = bins),

    • the number of bins in each dimension (nx, ny = bins),

    • the bin edges for the two dimensions (x_edge = y_edge = bins),

    • the bin edges in each dimension (x_edge, y_edge = bins). If the bin edges are specified, the number of bins will be, (nx = len(x_edge)-1, ny = len(y_edge)-1).

  • normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.

  • standardized (bool, default False) – Whether the x, y values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)

Returns:

bin_statistic – The keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), cx and cy (the bin centers) and ‘binnumber’ (the bin indices each point belongs to). ‘binnumber’ is a (2, N) array that represents the bin in which the observation falls if the observations falls outside the pitch the value is -1 for the dimension. The binnumber are zero indexed and start from the top and left handside of the pitch.

Return type:

dict.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
bin_statistic_positional(x, y, values=None, positional='full', statistic='count', normalize=False)

Calculates binned statistics for the Juego de posición (position game) concept. It uses scipy.stats.binned_statistic_2d.

Parameters:
  • x, y, values (array-like or scalar.) – Commonly, these parameters are 1D arrays. If the statistic is ‘count’ then values are ignored.

  • dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class

  • positional (str) – One of ‘full’, ‘horizontal’ or ‘vertical’ for the respective heatmaps.

  • statistic (string or callable, optional) – The statistic to compute (default is ‘count’). The following statistics are available: ‘count’ (default), ‘mean’, ‘std’, ‘median’, ‘sum’, ‘min’, ‘max’, or a user-defined function. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic_2d.html.

  • normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.

Returns:

bin_statistic – The dictionary keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

Return type:

A list of dictionaries.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic_positional(x, y)
>>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
calculate_angle_and_distance(xstart, ystart, xend, yend, standardized=False, degrees=False)

Calculates the angle in radians counter-clockwise and the distance between a start and end location. Where the angle 0 is this way → (the straight line from left to right) in a horizontally orientated pitch and this way ↑ in a vertically orientated pitch. The angle goes from 0 to 2pi. To convert the angle to degrees clockwise use degrees=True.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates to calculate the angle between.

  • standardized (bool, default False) – Whether the x, y values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)

  • degrees (bool, default False) – If False, the angle is returned in radians counter-clockwise in the range [0, 2pi] If True, the angle is returned in degrees clockwise in the range [0, 360].

Returns:

  • angle (ndarray) – The default is an array of angles in radians counter-clockwise in the range [0, 2pi]. Where 0 is the straight line left to right in a horizontally orientated pitch and the straight line bottom to top in a vertically orientated pitch. If degrees = True, then the angle is returned in degrees clockwise in the range [0, 360]

  • distance (ndarray) – Array of distances.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> pitch.calculate_angle_and_distance(0, 40, 30, 20, degrees=True)
(array([326.30993247]), array([36.05551275]))
convexhull(x, y)

Get lines of Convex Hull for a set of coordinates

Parameters:

x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

Returns:

hull_vertices

Return type:

a numpy array of vertoces [1, num_vertices, [x, y]] of the Convex Hull.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=11)
>>> y = np.random.uniform(low=0, high=80, size=11)
>>> hull = pitch.convexhull(x, y)
>>> poly = pitch.polygon(hull, ax=ax, facecolor='cornflowerblue', alpha=0.3)
draw(ax=None, figsize=None, nrows=1, ncols=1, tight_layout=True, constrained_layout=False)

Draws the specified soccer/ football pitch(es). If an ax is specified the pitch is drawn on an existing axis.

Parameters:
  • ax (matplotlib axis, default None) – A matplotlib.axes.Axes to draw the pitch on. If None is specified the pitch is plotted on a new figure.

  • figsize (tuple of float, default Matplotlib figure size) – The figure size in inches by default uses rcParams[“figure.figsize”].

  • nrows, ncols (int, default 1) – Number of rows/columns of the subplot grid.

  • tight_layout (bool, default True) – Whether to use Matplotlib’s tight layout.

  • constrained_layout (bool, default False) – Whether to use Matplotlib’s constrained layout.

Returns:

  • If ax=None returns a matplotlib Figure and Axes.

  • Else plotted on an existing axis and returns None.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> from mplsoccer import Pitch
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> pitch = Pitch()
>>> pitch.draw(ax=ax)
flip_side(x, y, flip)

A method to flip the coordinates to the other side of the pitch.

Parameters:
  • x, y (float) – The x, y coordinates that you want to flip.

  • flip (array-like of boolean or boolean) – Whether to flip each individual coordinate.

Return type:

x, y

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> new_x, new_y = pitch.flip_side(20, 20, True)
flow(xstart, ystart, xend, yend, bins=(5, 4), arrow_type='same', arrow_length=5, color=None, ax=None, **kwargs)

Create a flow map by binning the data into cells and calculating the average angles and distances.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates to calculate the angle between.

  • bins (int or [int, int] or array_like or [array, array], optional) –

    The bin specification for binning the data to calculate the angles/ distances.
    • the number of bins for the two dimensions (nx = ny = bins),

    • the number of bins in each dimension (nx, ny = bins),

    • the bin edges for the two dimensions (x_edge = y_edge = bins),

    • the bin edges in each dimension (x_edge, y_edge = bins). If the bin edges are specified, the number of bins will be, (nx = len(x_edge)-1, ny = len(y_edge)-1).

  • arrow_type (str, default ‘same’) – The supported arrow types are: ‘same’, ‘scale’, and ‘average’. ‘same’ makes the arrows the same size (arrow_length). ‘scale’ scales the arrow length by the average distance in the cell (up to a max of arrow_length). ‘average’ makes the arrow size the average distance in the cell.

  • arrow_length (float, default 5) – The arrow_length for the flow map. If the arrow_type=’same’, all the arrows will be arrow_length. If the arrow_type=’scale’, the arrows will be scaled by the average distance. If the arrow_type=’average’, the arrows_length is ignored This is automatically multipled by 100 if using a ‘tracab’ pitch (i.e. the default is 500).

  • color (A matplotlib color, defaults to None.) – Defaults to None. In that case the marker color is determined by the cmap (default ‘viridis’). and the counts of the starting positions in each bin.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.quiver.)

Returns:

PolyCollection

Return type:

matplotlib.quiver.Quiver

Examples

>>> from mplsoccer import Pitch, Sbopen
>>> parser = Sbopen()
>>> df, related, freeze, tactics = parser.event(7478)
>>> team1, team2 = df.team_name.unique()
>>> mask_team1 = (df.type_name == 'Pass') & (df.team_name == team1)
>>> df = df[mask_team1].copy()
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> bs_heatmap = pitch.bin_statistic(df.x, df.y, statistic='count', bins=(6, 4))
>>> hm = pitch.heatmap(bs_heatmap, ax=ax, cmap='Blues')
>>> fm = pitch.flow(df.x, df.y, df.end_x, df.end_y, color='black', arrow_type='same',
...                 arrow_length=6, bins=(6, 4), headwidth=2, headlength=2,
...                 headaxislength=2, ax=ax)
formation(formation, positions=None, kind='scatter', text=None, image=None, flip=False, half=False, height=None, width=None, aspect=None, polar=False, xoffset=None, yoffset=None, ax=None, **kwargs)

A method to plot formations

Parameters:
  • formation (str) – The formation to plot. For valid formations see the attribute formations For example, pitch = Pitch(); print(pitch.formations)

  • positions (Collection) – A collection of position identifiers to map the xoffset, yoffset, image and text arguments to mplsoccer positions. Only necessary for pitch_type=’statsbomb’, kind=’image’, kind=’text’ or where one of the xoffset/yoffset is not None

    For StatsBomb pitches, the position identifiers are between 1 and 25. For Opta pitches, the position identifiers are between 1 and 11. For Wyscout pitches, the position identifiers are: ‘gk’, ‘rwb’, ‘rb5’, ‘rb’, ‘rcb3’, ‘rcb’, ‘cb’, ‘lcb’, ‘lcb3’, ‘lb’, ‘lb5’, ‘lwb’, ‘rdmf’, ‘dmf’, ‘ldmf’, ‘rcmf3’, ‘rcmf’, ‘lcmf’, ‘lcmf3’, ‘rw’, ‘ramf’, ‘amf’, ‘lamf’, ‘lw’, ‘ss’, ‘cf’. For other pitches, the position identifiers are: ‘GK’, ‘RB’, ‘RCB’, ‘CB’, ‘LCB’, ‘LB’, ‘RWB’, ‘LWB’, ‘RDM’, ‘CDM’, ‘LDM’, ‘RM’, ‘RCM’, ‘CM’, ‘LCM’, ‘LM’, ‘RW’, ‘RAM’, ‘CAM’, ‘LAM’, ‘LW’, ‘RCF’, ‘ST’, ‘LCF’, ‘SS’.

  • kind (string, default ‘scatter’) – The kind of plot to produce: ‘scatter’, ‘text’, ‘image’, ‘pitch’, or ‘axes’.

  • text (Collection[string], default None) – The text data to plot if kind = ‘text’.

  • image (Collection[array-like or PIL image], default None) – The image data to plot if kind = ‘image’.

  • flip (bool, default False) – Whether to flip the positions horizontally so the direction of attack is right to left.

  • half (bool, default False) – Whether to fit the positions in one half of the pitch rather than the full pitch.

  • height, width (float, default None) – The height/width of the inset axes, inset pitch, or inset image in the x/y data coordinates.

  • aspect (float, default None) – The aspect ratio of the inset axes or inset image. You can specify a combination of height and aspect or width and aspect. This will make the axes visually have the given aspect ratio (length/width). For example, if you want an inset axes to appear square set aspect = 1. For polar plots, this is defaulted to 1.

  • polar (bool, default False) – Whether the inset axes if a polar projection for kind=’axes’.

  • xoffset, yoffset (Collection[float] or float, default None) – Offsets for the positions for plotting the positions off-center.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to:) –

    • Axes.scatter for kind=’scatter’

    • Axes.text for kind=’text’

    • Axes.imshow for kind=’image’

    • Temporarily amends the pitch attributes (e.g. line_color) for kind=’pitch’

    • Axes.inset_axes for kind=’axes’

Returns:

positions

  • A dictionary of player positions (e.g. GK) and matplotlib axes for kind=’image’, kind=’pitch’ or kind=’axes’. If the formation is a valid formation used by the data provider (pitch_type),

the dictionary keys will be the data provider’s position identifiers. - matplotlib.PathCollection for kind=’scatter’. - A list of matplotlib.Text for kind=’text’.

Return type:

dict[str, axes], matplotlib.PathCollection or list[matplotlib.Text]

Examples

>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_text = pitch.formation('442',
...                                 positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                 text=['GK', 'RB', 'RCB', 'LCB', 'LB', 'RDM', 'LDM',
...                                 'RM', 'LM', 'RCF', 'LCF'],
...                                 ax=ax,
...                                 kind='text')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_scatter = pitch.formation('442',
...                                    positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                    ax=ax,
...                                    kind='scatter')
>>> from mplsoccer import VerticalPitch
>>> from urllib.request import urlopen
>>> from PIL import Image
>>> image = Image.open(urlopen('https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg'))
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  image=[image] * 11,
...                                  height=15,
...                                  ax=ax,
...                                  kind='image')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  height=15,
...                                  ax=ax,
...                                  linewidth=1,
...                                  kind='pitch')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  height=15,
...                                  aspect=1,
...                                  ax=ax,
...                                  kind='axes')
property formations: List[str]

Return a list of valid mplsoccer formations.

property formations_dataframe: DataFrame

Return a dataframe of mplsoccer formations, positions and coordinates.

get_formation(formation)

Get a formation.

Parameters:

formation (str) – The formation. For valid formations see the attribute formations For example, pitch = Pitch() print(pitch.formations)

Returns:

formation – A list of the mplsoccer dataclass for holding the positions and coordinates

Return type:

list[mplsoccer.formations.Position]

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> formation = pitch.get_formation('442')
get_positions(line=5, second_striker=True) DataFrame

Get the player positions.

Parameters:
  • line (int, default 5) – Whether to have either five or four positions per line

  • second_striker (bool, default True) – Whether to have a separate line for the second striker. If False, the attacking players are more evenly spaced.

Returns:

positions

Return type:

pd.DataFrame

goal_angle(x, y, ax=None, goal='right', **kwargs)

Plot a polygon with the angle to the goal using matplotlib.patches.Polygon. See: https://matplotlib.org/stable/api/collections_api.html. Valid Collection keyword arguments: edgecolors, facecolors, linewidths, antialiaseds, transOffset, norm, cmap

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

  • goal (str default ‘right’.) – The goal to plot, either ‘left’ or ‘right’.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to) – matplotlib.collections.PathCollection.

Returns:

Polygon

Return type:

matplotlib.patches.Polygon

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.goal_angle(100, 30, alpha=0.5, color='red', ax=ax)
grid(figheight=9, nrows=1, ncols=1, grid_height=0.715, grid_width=0.95, space=0.05, left=None, bottom=None, endnote_height=0.065, endnote_space=0.01, title_height=0.15, title_space=0.01, axis=True)

A helper to create a grid of pitches in a specified location

Parameters:
  • figheight (float, default 9) – The figure height in inches.

  • nrows, ncols (int, default 1) – Number of rows/columns of pitches in the grid.

  • grid_height (float, default 0.715) – The height of the pitch grid in fractions of the figure height. The default is the grid height is 71.5% of the figure height.

  • grid_width (float, default 0.95) – The width of the pitch grid in fractions of the figure width. The default is the grid is 95% of the figure width.

  • space (float, default 0.05) – The total amount of the grid height reserved for spacing between the pitch axes. Expressed as a fraction of the grid_height. The default is 5% of the grid height. The spacing across the grid width is automatically calculated to maintain even spacing.

  • left (float, default None) – The location of the left-hand side of the axes in fractions of the figure width. The default of None places the axes in the middle of the figure.

  • bottom (float, default None) – The location of the bottom endnote axes in fractions of the figure height. The default of None places the axes in the middle of the figure. If the endnote_height=0 then the pitch grid is located at the bottom coordinate instead.

  • endnote_height (float, default 0.065) – The height of the endnote axes in fractions of the figure height. The default is the endnote is 6.5% of the figure height. If endnote_height=0, then the endnote axes is not plotted.

  • endnote_space (float, default 0.01) – The space between the pitch grid and endnote axis in fractions of the figure height. The default space is 1% of the figure height. If endnote_height=0, then the endnote_space is set to zero.

  • title_height (float, default 0.15) – The height of the title axis in fractions of the figure height. The default is the title axis is 15% of the figure height. If title_height=0, then the title axes is not plotted.

  • title_space (float, default 0.01) – The space between the pitch grid and title axis in fractions of the figure height. The default space is 1% of the figure height. If title_height=0, then the title_space is set to zero.

  • axis (bool, default True) – Whether the endnote and title axes are ‘on’.

Returns:

  • fig (matplotlib.figure.Figure)

  • axs (dict[label, Axes]) – A dictionary mapping the labels to the Axes objects. The possible keys are ‘pitch’, ‘title’, and ‘endnote’.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, axs = pitch.grid(nrows=3, ncols=3, grid_height=0.7, figheight=14)
grid_dimensions(figwidth, figheight, nrows, ncols, max_grid, space)

A helper method to propose a grid_width and grid_height for grid based on the inputs.

Parameters:
  • figwidth, figheight (float) – The figure width/height in inches.

  • nrows, ncols (int) – Number of rows/columns of pitches in the grid.

  • max_grid (float) – The longest side of the grid in fractions of the figure width / height. Should be between zero and one.

  • space (float) – The total amount of the grid height reserved for spacing between the pitch axes. Expressed as a fraction of the grid_height.

Returns:

grid_width, grid_height

Return type:

the suggested grid_width and grid_height

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> grid_width, grid_height = pitch.grid_dimensions(figwidth=16, figheight=9,
...                                                 nrows=1, ncols=1,
...                                                 max_grid=1,  space=0)
heatmap(stats, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.pcolormesh which automatically flips the x_grid and y_grid coordinates if the pitch is vertical.

See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.pcolormesh.html

Parameters:
  • stats (dict.) – This should be calculated via bin_statistic(). The keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.pcolormesh.)

Returns:

mesh

Return type:

matplotlib.collections.QuadMesh

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
heatmap_positional(stats, ax=None, **kwargs)

Plots several heatmaps for the different Juegos de posición areas.

Parameters:
  • stats (A list of dictionaries.) – This should be calculated via bin_statistic_positional(). The dictionary keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.pcolormesh.)

Returns:

mesh

Return type:

matplotlib.collections.QuadMesh

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic_positional(x, y)
>>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
hexbin(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.hexbin, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • mincnt (int > 0, default: 1) – If not None, only display cells with more than mincnt number of points in the cell.

  • gridsize (int or (int, int), default: (17, 8) for Pitch/ (17, 17) for VerticalPitch) – If a single int, the number of hexagons in the x-direction. The number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, if a tuple (nx, ny), the number of hexagons in the x-direction and the y-direction.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.hexbin.)

Returns:

polycollection

Return type:

matplotlib.collections.PolyCollection

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> pitch.hexbin(x, y, edgecolors='black', gridsize=(11, 5), cmap='Reds', ax=ax)
inset_axes(x, y, width=None, height=None, aspect=None, polar=False, ax=None, **kwargs)

A function to create an inset axes. This method produces the same axes with VerticalPitch and Pitch when the arguments are the same.

Parameters:
  • x, y (float) – The x/y coordinate of the center of the inset axes.

  • width, height (float, default None) – The width/height of the inset axes in the x/y data coordinates.

  • aspect (float, default None) – You can specify a combination of height and aspect or width and aspect. This will make the axes visually have the given aspect ratio (length/width). For example, if you want an inset axes to appear square set aspect = 1. For polar plots, this is defaulted to 1.

  • polar (bool, default False) – Whether the inset axes if a polar projection.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to the inset_axes.)

Returns:

ax

Return type:

matplotlib.axes.Axes

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> inset_axes = pitch.inset_axes(60, 40, width=20, aspect=1, ax=ax)
inset_image(x, y, image, width=None, height=None, ax=None, **kwargs)

Adds an image as an inset_axes

Parameters:
  • x, y (float)

  • image (array-like or PIL image) – The image data.

  • width, height (float, default None) – The width, height of the inset_axes for plotting the image. By default, in the data coordinates.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.imshow.)

Return type:

matplotlib.axes.Axes

Examples

>>> from mplsoccer import VerticalPitch
>>> from urllib.request import urlopen
>>> from PIL import Image
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw()
>>> image_url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg'
>>> image = urlopen(image_url)
>>> image = Image.open(image)
>>> ax_image = pitch.inset_image(60, 40, image, width=30, ax=ax)
jointgrid(figheight=9, left=None, grid_width=0.95, bottom=None, endnote_height=0.065, endnote_space=0.01, grid_height=0.715, title_space=0.01, title_height=0.15, space=0, marginal=0.1, ax_left=True, ax_top=True, ax_right=True, ax_bottom=False, axis=True)

Create a grid with a pitch at the center and (marginal) axes at the sides of the pitch.

Parameters:
  • figheight (float, default 9) – The figure height in inches.

  • left (float, default None) – The location of the left-hand side of the grid in fractions of the figure width. The default of None places the axes in the middle of the figure.

  • grid_width (float, default 0.95) – The width of the grid area in fractions of the figure width. The default is the grid is 80% of the figure width.

  • bottom (float, default None) – The location of the bottom endnote axes in fractions of the figure height. The default of None places the axes in the middle of the figure. If the endnote_height=0 then the joint grid is located at the bottom coordinate instead.

  • endnote_height (float, default 0.065) – The height of the endnote axes in fractions of the figure height. The default is the endnote is 6.5% of the figure height. If endnote_height=0, then the endnote axes is not plotted.

  • endnote_space (float, default 0.01) – The space between the joint grid and endnote axis in fractions of the figure height. The default space is 1% of the figure height. If endnote_height=0, then the endnote_space is set to zero.

  • grid_height (float, default 0.715) – The height of the joint grid area in fractions of the figure height. The default is the grid height is 70% of the figure height.

  • title_space (float, default 0.01) – The space between the joint grid and title axis in fractions of the figure height. The default space is 1% of the figure height. If title_height=0, then the title_space is set to zero.

  • title_height (float, default 0.15) – The height of the title axis in fractions of the figure height. The default is the title axis is 15% of the figure height. If title_height=0, then the title axes is not plotted.

  • space (float, default 0.01) – The total amount of the grid height reserved for spacing between axes. Expressed as a fraction of the grid height. The default is 0.01% of the grid height. Note if space is zero, it will still look like there is space if the pitch has padding, e.g. pad_top=15.

  • marginal (float, default 0.1) – The total amount of the grid height reserved for the marginal axes. Expressed as a fraction of the grid height. The default is 10% of the grid height.

  • ax_left, ax_top, ax_right (bool, default True) – Whether to include a Matplotlib Axes on the left/top/right side of the pitch.

  • ax_bottom (bool, default False) – Whether to include a Matplotlib Axes on the bottom side of the pitch.

  • axis (bool, default True) – Whether the endnote, title, and the marginal axes are ‘on’.

Returns:

  • fig (matplotlib.figure.Figure)

  • axs (dict[label, Axes]) – A dictionary mapping the labels to the Axes objects. The possible keys are ‘left’, ‘right’, ‘bottom’, ‘top’ for the marginal axes, ‘pitch’, ‘title’ and ‘endnote’.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> import seaborn as sns
>>> pitch = Pitch()
>>> fig, axs = pitch.jointgrid(ax_left=False, ax_right=False,
...                            ax_bottom=False, ax_top=True)
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> sns.kdeplot(x=x, ax=axs['top'], fill=True)
kdeplot(x, y, ax=None, **kwargs)

Utility wrapper around seaborn.kdeplot, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to seaborn.kdeplot.)

Returns:

contour

Return type:

matplotlib.contour.ContourSet

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> pitch.kdeplot(x, y, cmap='Reds', fill=True, levels=100, ax=ax)
label_heatmap(stats, str_format=None, exclude_zeros=False, exclude_nan=False, xoffset=0, yoffset=0, ax=None, **kwargs)

Labels the heatmap(s) and automatically flips the coordinates if the pitch is vertical.

Parameters:
  • stats (A dictionary or list of dictionaries.) – This should be calculated via bin_statistic_positional() or bin_statistic().

  • str_format (str) – A format string passed to str_format.format() to format the labels.

  • exclude_zeros (bool) – Whether to exclude zeros when labelling the heatmap.

  • xoffset, yoffset (float, default 0) – The amount in data coordinates to offset the labels from the center of the grid cell.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.annotate.)

Returns:

annotations

Return type:

A list of matplotlib.text.Annotation.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> import matplotlib.patheffects as path_effects
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
>>> stats['statistic'] = stats['statistic'].astype(int)
>>> path_eff = [path_effects.Stroke(linewidth=0.5, foreground='#22312b')]
>>> text = pitch.label_heatmap(stats, color='white', ax=ax, fontsize=20, ha='center',
...                            va='center', path_effects=path_eff)
lines(xstart, ystart, xend, yend, color=None, n_segments=100, comet=False, transparent=False, alpha_start=0.01, alpha_end=1, cmap=None, ax=None, **kwargs)

Plots lines using matplotlib.collections.LineCollection. This is a fast way to plot multiple lines without loops. Also enables lines that increase in width or opacity by splitting the line into n_segments of increasing width or opacity as the line progresses.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates of the lines.

  • color (A matplotlib color or sequence of colors, defaults to None.) – Defaults to None. In that case the marker color is determined by the value rcParams[‘lines.color’]

  • n_segments (int, default 100) – If comet=True or transparent=True this is used to split the line into n_segments of increasing width/opacity.

  • comet (bool default False) – Whether to plot the lines increasing in width.

  • transparent (bool, default False) – Whether to plot the lines increasing in opacity.

  • linewidth or lw (array-like or scalar, default 5.) – Multiple linewidths not supported for the comet or transparent lines.

  • alpha_start (float, default 0.01) – The starting alpha value for transparent lines, between 0 (transparent) and 1 (opaque). If transparent = True the line will be drawn to linearly increase in opacity between alpha_start and alpha_end.

  • alpha_end (float, default 1) – The ending alpha value for transparent lines, between 0 (transparent) and 1 (opaque). If transparent = True the line will be drawn to linearly increase in opacity between alpha_start and alpha_end.

  • cmap (str, default None) – A matplotlib cmap (colormap) name

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • reverse_cmap (bool, default False) – Whether to reverse the cmap colors. If the pitch is horizontal and the y-axis is inverted then set this to True.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.collections.LineCollection.)

Returns:

LineCollection

Return type:

matplotlib.collections.LineCollection

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.lines(20, 20, 45, 80, comet=True, transparent=True, ax=ax)
>>> from mplsoccer.linecollection import lines
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> lines([0.1, 0.4], [0.1, 0.5], [0.9, 0.4], [0.8, 0.8], ax=ax)
plot(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.plot, which automatically flips the x and y coordinates if the pitch is vertical.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.plot.)

Returns:

lines

Return type:

A list of Line2D objects representing the plotted data.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.plot([30, 35, 20], [30, 19, 40], ax=ax)
polygon(verts, ax=None, **kwargs)

Plot polygons. Automatically flips the x and y vertices if the pitch is vertical.

Parameters:
  • verts (verts is a sequence of (verts0, verts1, …)) – where verts_i is a numpy array of shape (number of vertices, 2).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to) – matplotlib.patches.Polygon

Return type:

list of matplotlib.patches.Polygon

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(label=True, axis=True)
>>> fig, ax = pitch.draw()
>>> shape1 = np.array([[50, 2], [80, 30], [40, 30], [40, 20]])
>>> shape2 = np.array([[70, 70], [60, 50], [40, 40]])
>>> verts = [shape1, shape2]
>>> pitch.polygon(verts, color='red', alpha=0.3, ax=ax)
scatter(x, y, rotation_degrees=None, marker=None, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.scatter, which automatically flips the x and y coordinates if the pitch is vertical. You can optionally use a football marker with marker=’football’ and rotate markers with rotation_degrees.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • rotation_degrees (array-like or scalar, default None.) – Rotates the marker in degrees, clockwise. 0 degrees is facing the direction of play. In a horizontal pitch, 0 degrees is this way →, in a vertical pitch, 0 degrees is this way ↑

  • marker (MarkerStyle, optional) – The marker style. marker can be either an instance of the class or the text shorthand for a particular marker. Defaults to None, in which case it takes the value of rcParams[“scatter.marker”] (default: ‘o’) = ‘o’. If marker=’football’ plots a football shape with the pentagons the color of the edgecolors and hexagons the color of the ‘c’ argument; ‘linewidths’ also sets the linewidth of the football marker.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.scatter.)

Returns:

paths – or a tuple of (paths, paths) if marker=’football’

Return type:

matplotlib.collections.PathCollection

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, ax=ax)
>>> from mplsoccer import Pitch
>>> from mplsoccer import arrowhead_marker
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, rotation_degrees=45, marker=arrowhead_marker, ax=ax)
>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, marker='football', ax=ax)
text(x, y, s, ax=None, **kwargs)

Utility wrapper around ax.text which automatically flips the x/y coordinates if the pitch is vertical.

See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.text.html

Parameters:
  • x, y (float) – The position to place the text

  • s (str) – The text

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.text.)

Returns:

annotation

Return type:

matplotlib.text.Text

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.text(60, 40, 'Center of the pitch', va='center', ha='center', ax=ax)
triplot(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.triplot

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.triplot.)

voronoi(x, y, teams)

Get Voronoi vertices for a set of coordinates. Uses a trick by Dan Nichol (@D4N__ on Twitter) where points are reflected in the pitch lines before calculating the Voronoi. This means that the Voronoi extends to the edges of the pitch. See: https://github.com/ProformAnalytics/tutorial_nbs/blob/master/notebooks/Voronoi%20Reflection%20Trick.ipynb

Players outside the pitch dimensions are assumed to be standing on the pitch edge. This means that their coordinates are clipped to the pitch edges before calculating the Voronoi.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

  • teams (array-like or scalar.) – This splits the results into the Voronoi vertices for each team. This can either have integer (1/0) values or boolean (True/False) values. team1 is where team==1 or team==True team2 is where team==0 or team==False

Returns:

  • team1 (a 1d numpy array (length number of players in team 1) of 2d arrays) – Where the individual 2d arrays are coordinates of the Voronoi vertices.

  • team2 (a 1d numpy array (length number of players in team 2) of 2d arrays) – Where the individual 2d arrays are coordinates of the Voronoi vertices.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=22)
>>> y = np.random.uniform(low=0, high=80, size=22)
>>> teams = np.array([0] * 11 + [1] * 11)
>>> pitch.scatter(x[teams == 0], y[teams == 0], color='red', ax=ax)
>>> pitch.scatter(x[teams == 1], y[teams == 1], color='blue', ax=ax)
>>> team1, team2 = pitch.voronoi(x, y, teams)
>>> team1_poly = pitch.polygon(team1, ax=ax, color='blue', alpha=0.3)
>>> team2_poly = pitch.polygon(team2, ax=ax, color='red', alpha=0.3)
class mplsoccer.pitch.VerticalPitch(pitch_type='statsbomb', half=False, pitch_color=None, line_color=None, line_alpha=1, linewidth=2, linestyle=None, line_zorder=0.9, spot_scale=0.002, spot_type='circle', stripe=False, stripe_color='#c2d59d', stripe_zorder=0.6, pad_left=None, pad_right=None, pad_bottom=None, pad_top=None, positional=False, positional_zorder=0.8, positional_linewidth=None, positional_linestyle=None, positional_color='#eadddd', positional_alpha=1, shade_middle=False, shade_color='#f2f2f2', shade_alpha=1, shade_zorder=0.7, pitch_length=None, pitch_width=None, goal_type='line', goal_alpha=1, goal_linestyle=None, axis=False, label=False, tick=False, corner_arcs=False)[source]

Bases: BasePitchPlot

Attributes:
formations

Return a list of valid mplsoccer formations.

formations_dataframe

Return a dataframe of mplsoccer formations, positions and coordinates.

Methods

annotate(text, xy[, xytext, ax])

Utility wrapper around ax.annotate which automatically flips the xy and xytext coordinates if the pitch is vertical.

arrows(xstart, ystart, xend, yend, *args[, ax])

Utility wrapper around matplotlib.axes.Axes.quiver.

bin_statistic(x, y[, values, statistic, ...])

Calculates binned statistics using scipy.stats.binned_statistic_2d.

bin_statistic_positional(x, y[, values, ...])

Calculates binned statistics for the Juego de posición (position game) concept.

calculate_angle_and_distance(xstart, ystart, ...)

Calculates the angle in radians counter-clockwise and the distance between a start and end location.

convexhull(x, y)

Get lines of Convex Hull for a set of coordinates

draw([ax, figsize, nrows, ncols, ...])

Draws the specified soccer/ football pitch(es).

flip_side(x, y, flip)

A method to flip the coordinates to the other side of the pitch.

flow(xstart, ystart, xend, yend[, bins, ...])

Create a flow map by binning the data into cells and calculating the average angles and distances.

formation(formation[, positions, kind, ...])

A method to plot formations

get_formation(formation)

Get a formation.

get_positions([line, second_striker])

Get the player positions.

goal_angle(x, y[, ax, goal])

Plot a polygon with the angle to the goal using matplotlib.patches.Polygon.

grid([figheight, nrows, ncols, grid_height, ...])

A helper to create a grid of pitches in a specified location

grid_dimensions(figwidth, figheight, nrows, ...)

A helper method to propose a grid_width and grid_height for grid based on the inputs.

heatmap(stats[, ax])

Utility wrapper around matplotlib.axes.Axes.pcolormesh which automatically flips the x_grid and y_grid coordinates if the pitch is vertical.

heatmap_positional(stats[, ax])

Plots several heatmaps for the different Juegos de posición areas.

hexbin(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.hexbin, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

inset_axes(x, y[, width, height, aspect, ...])

A function to create an inset axes.

inset_image(x, y, image[, width, height, ax])

Adds an image as an inset_axes

jointgrid([figheight, left, grid_width, ...])

Create a grid with a pitch at the center and (marginal) axes at the sides of the pitch.

kdeplot(x, y[, ax])

Utility wrapper around seaborn.kdeplot, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

label_heatmap(stats[, str_format, ...])

Labels the heatmap(s) and automatically flips the coordinates if the pitch is vertical.

lines(xstart, ystart, xend, yend[, color, ...])

Plots lines using matplotlib.collections.LineCollection.

plot(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.plot, which automatically flips the x and y coordinates if the pitch is vertical.

polygon(verts[, ax])

Plot polygons.

scatter(x, y[, rotation_degrees, marker, ax])

Utility wrapper around matplotlib.axes.Axes.scatter, which automatically flips the x and y coordinates if the pitch is vertical.

text(x, y, s[, ax])

Utility wrapper around ax.text which automatically flips the x/y coordinates if the pitch is vertical.

triplot(x, y[, ax])

Utility wrapper around matplotlib.axes.Axes.triplot

voronoi(x, y, teams)

Get Voronoi vertices for a set of coordinates.

annotate(text, xy, xytext=None, ax=None, **kwargs)

Utility wrapper around ax.annotate which automatically flips the xy and xytext coordinates if the pitch is vertical.

Annotate the point xy with text. See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.annotate.html

Parameters:
  • text (str) – The text of the annotation.

  • xy ((float, float)) – The point (x, y) to annotate.

  • xytext ((float, float), optional) – The position (x, y) to place the text at. If None, defaults to xy.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.annotate.)

Returns:

annotation

Return type:

matplotlib.text.Annotation

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.annotate(text='center', xytext=(50, 50), xy=(60, 40), ha='center', va='center',
...                ax=ax, arrowprops=dict(facecolor='black'))
arrows(xstart, ystart, xend, yend, *args, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.quiver. Quiver uses locations and direction vectors usually. Here these are instead calculated automatically from the start and endpoints of the arrow. The function also automatically flips the x and y coordinates if the pitch is vertical.

Plot a 2D field of arrows. See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.quiver.html

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates of the lines.

  • C (1D or 2D array-like, optional) – Numeric data that defines the arrow colors by colormapping via norm and cmap. This does not support explicit colors. If you want to set colors directly, use color instead. The size of C must match the number of arrow locations.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • width (float, default 4) – Arrow shaft width in points.

  • headwidth (float, default 3) – Head width as a multiple of the arrow shaft width.

  • headlength (float, default 5) – Head length as a multiple of the arrow shaft width.

  • headaxislength (float, default: 4.5) – Head length at the shaft intersection. If this is equal to the headlength then the arrow will be a triangular shape. If greater than the headlength then the arrow will be wedge shaped. If less than the headlength the arrow will be swept back.

  • color (color or color sequence, optional) – Explicit color(s) for the arrows. If C has been set, color has no effect.

  • linewidth or linewidths or lw (float or sequence of floats) – Edgewidth of arrow.

  • edgecolor or ec or edgecolors (color or sequence of colors or ‘face’)

  • alpha (float or None) – Transparency of arrows.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.quiver.)

Returns:

PolyCollection

Return type:

matplotlib.quiver.Quiver

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.arrows(20, 20, 45, 80, ax=ax)
>>> from mplsoccer.quiver import arrows
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> arrows([0.1, 0.4], [0.1, 0.5], [0.9, 0.4], [0.8, 0.8], ax=ax)
>>> ax.set_xlim(0, 1)
>>> ax.set_ylim(0, 1)
bin_statistic(x, y, values=None, statistic='count', bins=(5, 4), normalize=False, standardized=False)

Calculates binned statistics using scipy.stats.binned_statistic_2d.

This method automatically sets the range, changes the scipy defaults, and outputs the grids and centers for plotting.

The default statistic has been changed to count instead of mean. The default bins have been set to (5,4).

Parameters:
  • x, y, values (array-like or scalar.) – Commonly, these parameters are 1D arrays. If the statistic is ‘count’ then values are ignored.

  • dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class

  • statistic (string or callable, optional) – The statistic to compute (default is ‘count’). The following statistics are available: ‘count’ (default), ‘mean’, ‘std’, ‘median’, ‘sum’, ‘min’, ‘max’, ‘circmean’ or a user-defined function. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic_2d.html

  • bins (int or [int, int] or array_like or [array, array], optional) –

    The bin specification.
    • the number of bins for the two dimensions (nx = ny = bins),

    • the number of bins in each dimension (nx, ny = bins),

    • the bin edges for the two dimensions (x_edge = y_edge = bins),

    • the bin edges in each dimension (x_edge, y_edge = bins). If the bin edges are specified, the number of bins will be, (nx = len(x_edge)-1, ny = len(y_edge)-1).

  • normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.

  • standardized (bool, default False) – Whether the x, y values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)

Returns:

bin_statistic – The keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), cx and cy (the bin centers) and ‘binnumber’ (the bin indices each point belongs to). ‘binnumber’ is a (2, N) array that represents the bin in which the observation falls if the observations falls outside the pitch the value is -1 for the dimension. The binnumber are zero indexed and start from the top and left handside of the pitch.

Return type:

dict.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
bin_statistic_positional(x, y, values=None, positional='full', statistic='count', normalize=False)

Calculates binned statistics for the Juego de posición (position game) concept. It uses scipy.stats.binned_statistic_2d.

Parameters:
  • x, y, values (array-like or scalar.) – Commonly, these parameters are 1D arrays. If the statistic is ‘count’ then values are ignored.

  • dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class

  • positional (str) – One of ‘full’, ‘horizontal’ or ‘vertical’ for the respective heatmaps.

  • statistic (string or callable, optional) – The statistic to compute (default is ‘count’). The following statistics are available: ‘count’ (default), ‘mean’, ‘std’, ‘median’, ‘sum’, ‘min’, ‘max’, or a user-defined function. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic_2d.html.

  • normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.

Returns:

bin_statistic – The dictionary keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

Return type:

A list of dictionaries.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic_positional(x, y)
>>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
calculate_angle_and_distance(xstart, ystart, xend, yend, standardized=False, degrees=False)

Calculates the angle in radians counter-clockwise and the distance between a start and end location. Where the angle 0 is this way → (the straight line from left to right) in a horizontally orientated pitch and this way ↑ in a vertically orientated pitch. The angle goes from 0 to 2pi. To convert the angle to degrees clockwise use degrees=True.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates to calculate the angle between.

  • standardized (bool, default False) – Whether the x, y values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)

  • degrees (bool, default False) – If False, the angle is returned in radians counter-clockwise in the range [0, 2pi] If True, the angle is returned in degrees clockwise in the range [0, 360].

Returns:

  • angle (ndarray) – The default is an array of angles in radians counter-clockwise in the range [0, 2pi]. Where 0 is the straight line left to right in a horizontally orientated pitch and the straight line bottom to top in a vertically orientated pitch. If degrees = True, then the angle is returned in degrees clockwise in the range [0, 360]

  • distance (ndarray) – Array of distances.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> pitch.calculate_angle_and_distance(0, 40, 30, 20, degrees=True)
(array([326.30993247]), array([36.05551275]))
convexhull(x, y)

Get lines of Convex Hull for a set of coordinates

Parameters:

x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

Returns:

hull_vertices

Return type:

a numpy array of vertoces [1, num_vertices, [x, y]] of the Convex Hull.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=11)
>>> y = np.random.uniform(low=0, high=80, size=11)
>>> hull = pitch.convexhull(x, y)
>>> poly = pitch.polygon(hull, ax=ax, facecolor='cornflowerblue', alpha=0.3)
draw(ax=None, figsize=None, nrows=1, ncols=1, tight_layout=True, constrained_layout=False)

Draws the specified soccer/ football pitch(es). If an ax is specified the pitch is drawn on an existing axis.

Parameters:
  • ax (matplotlib axis, default None) – A matplotlib.axes.Axes to draw the pitch on. If None is specified the pitch is plotted on a new figure.

  • figsize (tuple of float, default Matplotlib figure size) – The figure size in inches by default uses rcParams[“figure.figsize”].

  • nrows, ncols (int, default 1) – Number of rows/columns of the subplot grid.

  • tight_layout (bool, default True) – Whether to use Matplotlib’s tight layout.

  • constrained_layout (bool, default False) – Whether to use Matplotlib’s constrained layout.

Returns:

  • If ax=None returns a matplotlib Figure and Axes.

  • Else plotted on an existing axis and returns None.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> from mplsoccer import Pitch
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> pitch = Pitch()
>>> pitch.draw(ax=ax)
flip_side(x, y, flip)

A method to flip the coordinates to the other side of the pitch.

Parameters:
  • x, y (float) – The x, y coordinates that you want to flip.

  • flip (array-like of boolean or boolean) – Whether to flip each individual coordinate.

Return type:

x, y

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> new_x, new_y = pitch.flip_side(20, 20, True)
flow(xstart, ystart, xend, yend, bins=(5, 4), arrow_type='same', arrow_length=5, color=None, ax=None, **kwargs)

Create a flow map by binning the data into cells and calculating the average angles and distances.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates to calculate the angle between.

  • bins (int or [int, int] or array_like or [array, array], optional) –

    The bin specification for binning the data to calculate the angles/ distances.
    • the number of bins for the two dimensions (nx = ny = bins),

    • the number of bins in each dimension (nx, ny = bins),

    • the bin edges for the two dimensions (x_edge = y_edge = bins),

    • the bin edges in each dimension (x_edge, y_edge = bins). If the bin edges are specified, the number of bins will be, (nx = len(x_edge)-1, ny = len(y_edge)-1).

  • arrow_type (str, default ‘same’) – The supported arrow types are: ‘same’, ‘scale’, and ‘average’. ‘same’ makes the arrows the same size (arrow_length). ‘scale’ scales the arrow length by the average distance in the cell (up to a max of arrow_length). ‘average’ makes the arrow size the average distance in the cell.

  • arrow_length (float, default 5) – The arrow_length for the flow map. If the arrow_type=’same’, all the arrows will be arrow_length. If the arrow_type=’scale’, the arrows will be scaled by the average distance. If the arrow_type=’average’, the arrows_length is ignored This is automatically multipled by 100 if using a ‘tracab’ pitch (i.e. the default is 500).

  • color (A matplotlib color, defaults to None.) – Defaults to None. In that case the marker color is determined by the cmap (default ‘viridis’). and the counts of the starting positions in each bin.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.quiver.)

Returns:

PolyCollection

Return type:

matplotlib.quiver.Quiver

Examples

>>> from mplsoccer import Pitch, Sbopen
>>> parser = Sbopen()
>>> df, related, freeze, tactics = parser.event(7478)
>>> team1, team2 = df.team_name.unique()
>>> mask_team1 = (df.type_name == 'Pass') & (df.team_name == team1)
>>> df = df[mask_team1].copy()
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> bs_heatmap = pitch.bin_statistic(df.x, df.y, statistic='count', bins=(6, 4))
>>> hm = pitch.heatmap(bs_heatmap, ax=ax, cmap='Blues')
>>> fm = pitch.flow(df.x, df.y, df.end_x, df.end_y, color='black', arrow_type='same',
...                 arrow_length=6, bins=(6, 4), headwidth=2, headlength=2,
...                 headaxislength=2, ax=ax)
formation(formation, positions=None, kind='scatter', text=None, image=None, flip=False, half=False, height=None, width=None, aspect=None, polar=False, xoffset=None, yoffset=None, ax=None, **kwargs)

A method to plot formations

Parameters:
  • formation (str) – The formation to plot. For valid formations see the attribute formations For example, pitch = Pitch(); print(pitch.formations)

  • positions (Collection) – A collection of position identifiers to map the xoffset, yoffset, image and text arguments to mplsoccer positions. Only necessary for pitch_type=’statsbomb’, kind=’image’, kind=’text’ or where one of the xoffset/yoffset is not None

    For StatsBomb pitches, the position identifiers are between 1 and 25. For Opta pitches, the position identifiers are between 1 and 11. For Wyscout pitches, the position identifiers are: ‘gk’, ‘rwb’, ‘rb5’, ‘rb’, ‘rcb3’, ‘rcb’, ‘cb’, ‘lcb’, ‘lcb3’, ‘lb’, ‘lb5’, ‘lwb’, ‘rdmf’, ‘dmf’, ‘ldmf’, ‘rcmf3’, ‘rcmf’, ‘lcmf’, ‘lcmf3’, ‘rw’, ‘ramf’, ‘amf’, ‘lamf’, ‘lw’, ‘ss’, ‘cf’. For other pitches, the position identifiers are: ‘GK’, ‘RB’, ‘RCB’, ‘CB’, ‘LCB’, ‘LB’, ‘RWB’, ‘LWB’, ‘RDM’, ‘CDM’, ‘LDM’, ‘RM’, ‘RCM’, ‘CM’, ‘LCM’, ‘LM’, ‘RW’, ‘RAM’, ‘CAM’, ‘LAM’, ‘LW’, ‘RCF’, ‘ST’, ‘LCF’, ‘SS’.

  • kind (string, default ‘scatter’) – The kind of plot to produce: ‘scatter’, ‘text’, ‘image’, ‘pitch’, or ‘axes’.

  • text (Collection[string], default None) – The text data to plot if kind = ‘text’.

  • image (Collection[array-like or PIL image], default None) – The image data to plot if kind = ‘image’.

  • flip (bool, default False) – Whether to flip the positions horizontally so the direction of attack is right to left.

  • half (bool, default False) – Whether to fit the positions in one half of the pitch rather than the full pitch.

  • height, width (float, default None) – The height/width of the inset axes, inset pitch, or inset image in the x/y data coordinates.

  • aspect (float, default None) – The aspect ratio of the inset axes or inset image. You can specify a combination of height and aspect or width and aspect. This will make the axes visually have the given aspect ratio (length/width). For example, if you want an inset axes to appear square set aspect = 1. For polar plots, this is defaulted to 1.

  • polar (bool, default False) – Whether the inset axes if a polar projection for kind=’axes’.

  • xoffset, yoffset (Collection[float] or float, default None) – Offsets for the positions for plotting the positions off-center.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to:) –

    • Axes.scatter for kind=’scatter’

    • Axes.text for kind=’text’

    • Axes.imshow for kind=’image’

    • Temporarily amends the pitch attributes (e.g. line_color) for kind=’pitch’

    • Axes.inset_axes for kind=’axes’

Returns:

positions

  • A dictionary of player positions (e.g. GK) and matplotlib axes for kind=’image’, kind=’pitch’ or kind=’axes’. If the formation is a valid formation used by the data provider (pitch_type),

the dictionary keys will be the data provider’s position identifiers. - matplotlib.PathCollection for kind=’scatter’. - A list of matplotlib.Text for kind=’text’.

Return type:

dict[str, axes], matplotlib.PathCollection or list[matplotlib.Text]

Examples

>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_text = pitch.formation('442',
...                                 positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                 text=['GK', 'RB', 'RCB', 'LCB', 'LB', 'RDM', 'LDM',
...                                 'RM', 'LM', 'RCF', 'LCF'],
...                                 ax=ax,
...                                 kind='text')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_scatter = pitch.formation('442',
...                                    positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                    ax=ax,
...                                    kind='scatter')
>>> from mplsoccer import VerticalPitch
>>> from urllib.request import urlopen
>>> from PIL import Image
>>> image = Image.open(urlopen('https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg'))
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  image=[image] * 11,
...                                  height=15,
...                                  ax=ax,
...                                  kind='image')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  height=15,
...                                  ax=ax,
...                                  linewidth=1,
...                                  kind='pitch')
>>> from mplsoccer import VerticalPitch
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw(figsize=(6.875, 10))
>>> position_image = pitch.formation('442',
...                                  positions=[1, 2, 3, 5, 6, 9, 11, 12, 16, 22, 24],
...                                  height=15,
...                                  aspect=1,
...                                  ax=ax,
...                                  kind='axes')
property formations: List[str]

Return a list of valid mplsoccer formations.

property formations_dataframe: DataFrame

Return a dataframe of mplsoccer formations, positions and coordinates.

get_formation(formation)

Get a formation.

Parameters:

formation (str) – The formation. For valid formations see the attribute formations For example, pitch = Pitch() print(pitch.formations)

Returns:

formation – A list of the mplsoccer dataclass for holding the positions and coordinates

Return type:

list[mplsoccer.formations.Position]

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> formation = pitch.get_formation('442')
get_positions(line=5, second_striker=True) DataFrame

Get the player positions.

Parameters:
  • line (int, default 5) – Whether to have either five or four positions per line

  • second_striker (bool, default True) – Whether to have a separate line for the second striker. If False, the attacking players are more evenly spaced.

Returns:

positions

Return type:

pd.DataFrame

goal_angle(x, y, ax=None, goal='right', **kwargs)

Plot a polygon with the angle to the goal using matplotlib.patches.Polygon. See: https://matplotlib.org/stable/api/collections_api.html. Valid Collection keyword arguments: edgecolors, facecolors, linewidths, antialiaseds, transOffset, norm, cmap

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

  • goal (str default ‘right’.) – The goal to plot, either ‘left’ or ‘right’.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to) – matplotlib.collections.PathCollection.

Returns:

Polygon

Return type:

matplotlib.patches.Polygon

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.goal_angle(100, 30, alpha=0.5, color='red', ax=ax)
grid(figheight=9, nrows=1, ncols=1, grid_height=0.715, grid_width=0.95, space=0.05, left=None, bottom=None, endnote_height=0.065, endnote_space=0.01, title_height=0.15, title_space=0.01, axis=True)

A helper to create a grid of pitches in a specified location

Parameters:
  • figheight (float, default 9) – The figure height in inches.

  • nrows, ncols (int, default 1) – Number of rows/columns of pitches in the grid.

  • grid_height (float, default 0.715) – The height of the pitch grid in fractions of the figure height. The default is the grid height is 71.5% of the figure height.

  • grid_width (float, default 0.95) – The width of the pitch grid in fractions of the figure width. The default is the grid is 95% of the figure width.

  • space (float, default 0.05) – The total amount of the grid height reserved for spacing between the pitch axes. Expressed as a fraction of the grid_height. The default is 5% of the grid height. The spacing across the grid width is automatically calculated to maintain even spacing.

  • left (float, default None) – The location of the left-hand side of the axes in fractions of the figure width. The default of None places the axes in the middle of the figure.

  • bottom (float, default None) – The location of the bottom endnote axes in fractions of the figure height. The default of None places the axes in the middle of the figure. If the endnote_height=0 then the pitch grid is located at the bottom coordinate instead.

  • endnote_height (float, default 0.065) – The height of the endnote axes in fractions of the figure height. The default is the endnote is 6.5% of the figure height. If endnote_height=0, then the endnote axes is not plotted.

  • endnote_space (float, default 0.01) – The space between the pitch grid and endnote axis in fractions of the figure height. The default space is 1% of the figure height. If endnote_height=0, then the endnote_space is set to zero.

  • title_height (float, default 0.15) – The height of the title axis in fractions of the figure height. The default is the title axis is 15% of the figure height. If title_height=0, then the title axes is not plotted.

  • title_space (float, default 0.01) – The space between the pitch grid and title axis in fractions of the figure height. The default space is 1% of the figure height. If title_height=0, then the title_space is set to zero.

  • axis (bool, default True) – Whether the endnote and title axes are ‘on’.

Returns:

  • fig (matplotlib.figure.Figure)

  • axs (dict[label, Axes]) – A dictionary mapping the labels to the Axes objects. The possible keys are ‘pitch’, ‘title’, and ‘endnote’.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, axs = pitch.grid(nrows=3, ncols=3, grid_height=0.7, figheight=14)
grid_dimensions(figwidth, figheight, nrows, ncols, max_grid, space)

A helper method to propose a grid_width and grid_height for grid based on the inputs.

Parameters:
  • figwidth, figheight (float) – The figure width/height in inches.

  • nrows, ncols (int) – Number of rows/columns of pitches in the grid.

  • max_grid (float) – The longest side of the grid in fractions of the figure width / height. Should be between zero and one.

  • space (float) – The total amount of the grid height reserved for spacing between the pitch axes. Expressed as a fraction of the grid_height.

Returns:

grid_width, grid_height

Return type:

the suggested grid_width and grid_height

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> grid_width, grid_height = pitch.grid_dimensions(figwidth=16, figheight=9,
...                                                 nrows=1, ncols=1,
...                                                 max_grid=1,  space=0)
heatmap(stats, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.pcolormesh which automatically flips the x_grid and y_grid coordinates if the pitch is vertical.

See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.pcolormesh.html

Parameters:
  • stats (dict.) – This should be calculated via bin_statistic(). The keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.pcolormesh.)

Returns:

mesh

Return type:

matplotlib.collections.QuadMesh

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
heatmap_positional(stats, ax=None, **kwargs)

Plots several heatmaps for the different Juegos de posición areas.

Parameters:
  • stats (A list of dictionaries.) – This should be calculated via bin_statistic_positional(). The dictionary keys are ‘statistic’ (the calculated statistic), ‘x_grid’ and ‘y_grid (the bin’s edges), and cx and cy (the bin centers).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.pcolormesh.)

Returns:

mesh

Return type:

matplotlib.collections.QuadMesh

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic_positional(x, y)
>>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
hexbin(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.hexbin, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • mincnt (int > 0, default: 1) – If not None, only display cells with more than mincnt number of points in the cell.

  • gridsize (int or (int, int), default: (17, 8) for Pitch/ (17, 17) for VerticalPitch) – If a single int, the number of hexagons in the x-direction. The number of hexagons in the y-direction is chosen such that the hexagons are approximately regular. Alternatively, if a tuple (nx, ny), the number of hexagons in the x-direction and the y-direction.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.hexbin.)

Returns:

polycollection

Return type:

matplotlib.collections.PolyCollection

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> pitch.hexbin(x, y, edgecolors='black', gridsize=(11, 5), cmap='Reds', ax=ax)
inset_axes(x, y, width=None, height=None, aspect=None, polar=False, ax=None, **kwargs)

A function to create an inset axes. This method produces the same axes with VerticalPitch and Pitch when the arguments are the same.

Parameters:
  • x, y (float) – The x/y coordinate of the center of the inset axes.

  • width, height (float, default None) – The width/height of the inset axes in the x/y data coordinates.

  • aspect (float, default None) – You can specify a combination of height and aspect or width and aspect. This will make the axes visually have the given aspect ratio (length/width). For example, if you want an inset axes to appear square set aspect = 1. For polar plots, this is defaulted to 1.

  • polar (bool, default False) – Whether the inset axes if a polar projection.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to the inset_axes.)

Returns:

ax

Return type:

matplotlib.axes.Axes

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> inset_axes = pitch.inset_axes(60, 40, width=20, aspect=1, ax=ax)
inset_image(x, y, image, width=None, height=None, ax=None, **kwargs)

Adds an image as an inset_axes

Parameters:
  • x, y (float)

  • image (array-like or PIL image) – The image data.

  • width, height (float, default None) – The width, height of the inset_axes for plotting the image. By default, in the data coordinates.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.imshow.)

Return type:

matplotlib.axes.Axes

Examples

>>> from mplsoccer import VerticalPitch
>>> from urllib.request import urlopen
>>> from PIL import Image
>>> pitch = VerticalPitch()
>>> fig, ax = pitch.draw()
>>> image_url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg'
>>> image = urlopen(image_url)
>>> image = Image.open(image)
>>> ax_image = pitch.inset_image(60, 40, image, width=30, ax=ax)
jointgrid(figheight=9, left=None, grid_width=0.95, bottom=None, endnote_height=0.065, endnote_space=0.01, grid_height=0.715, title_space=0.01, title_height=0.15, space=0, marginal=0.1, ax_left=True, ax_top=True, ax_right=True, ax_bottom=False, axis=True)

Create a grid with a pitch at the center and (marginal) axes at the sides of the pitch.

Parameters:
  • figheight (float, default 9) – The figure height in inches.

  • left (float, default None) – The location of the left-hand side of the grid in fractions of the figure width. The default of None places the axes in the middle of the figure.

  • grid_width (float, default 0.95) – The width of the grid area in fractions of the figure width. The default is the grid is 80% of the figure width.

  • bottom (float, default None) – The location of the bottom endnote axes in fractions of the figure height. The default of None places the axes in the middle of the figure. If the endnote_height=0 then the joint grid is located at the bottom coordinate instead.

  • endnote_height (float, default 0.065) – The height of the endnote axes in fractions of the figure height. The default is the endnote is 6.5% of the figure height. If endnote_height=0, then the endnote axes is not plotted.

  • endnote_space (float, default 0.01) – The space between the joint grid and endnote axis in fractions of the figure height. The default space is 1% of the figure height. If endnote_height=0, then the endnote_space is set to zero.

  • grid_height (float, default 0.715) – The height of the joint grid area in fractions of the figure height. The default is the grid height is 70% of the figure height.

  • title_space (float, default 0.01) – The space between the joint grid and title axis in fractions of the figure height. The default space is 1% of the figure height. If title_height=0, then the title_space is set to zero.

  • title_height (float, default 0.15) – The height of the title axis in fractions of the figure height. The default is the title axis is 15% of the figure height. If title_height=0, then the title axes is not plotted.

  • space (float, default 0.01) – The total amount of the grid height reserved for spacing between axes. Expressed as a fraction of the grid height. The default is 0.01% of the grid height. Note if space is zero, it will still look like there is space if the pitch has padding, e.g. pad_top=15.

  • marginal (float, default 0.1) – The total amount of the grid height reserved for the marginal axes. Expressed as a fraction of the grid height. The default is 10% of the grid height.

  • ax_left, ax_top, ax_right (bool, default True) – Whether to include a Matplotlib Axes on the left/top/right side of the pitch.

  • ax_bottom (bool, default False) – Whether to include a Matplotlib Axes on the bottom side of the pitch.

  • axis (bool, default True) – Whether the endnote, title, and the marginal axes are ‘on’.

Returns:

  • fig (matplotlib.figure.Figure)

  • axs (dict[label, Axes]) – A dictionary mapping the labels to the Axes objects. The possible keys are ‘left’, ‘right’, ‘bottom’, ‘top’ for the marginal axes, ‘pitch’, ‘title’ and ‘endnote’.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> import seaborn as sns
>>> pitch = Pitch()
>>> fig, axs = pitch.jointgrid(ax_left=False, ax_right=False,
...                            ax_bottom=False, ax_top=True)
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> sns.kdeplot(x=x, ax=axs['top'], fill=True)
kdeplot(x, y, ax=None, **kwargs)

Utility wrapper around seaborn.kdeplot, which automatically flips the x and y coordinates if the pitch is vertical and clips to the pitch boundaries.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to seaborn.kdeplot.)

Returns:

contour

Return type:

matplotlib.contour.ContourSet

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(line_zorder=2)
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> pitch.kdeplot(x, y, cmap='Reds', fill=True, levels=100, ax=ax)
label_heatmap(stats, str_format=None, exclude_zeros=False, exclude_nan=False, xoffset=0, yoffset=0, ax=None, **kwargs)

Labels the heatmap(s) and automatically flips the coordinates if the pitch is vertical.

Parameters:
  • stats (A dictionary or list of dictionaries.) – This should be calculated via bin_statistic_positional() or bin_statistic().

  • str_format (str) – A format string passed to str_format.format() to format the labels.

  • exclude_zeros (bool) – Whether to exclude zeros when labelling the heatmap.

  • xoffset, yoffset (float, default 0) – The amount in data coordinates to offset the labels from the center of the grid cell.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.annotate.)

Returns:

annotations

Return type:

A list of matplotlib.text.Annotation.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> import matplotlib.patheffects as path_effects
>>> pitch = Pitch(line_zorder=2, pitch_color='black')
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=100)
>>> y = np.random.uniform(low=0, high=80, size=100)
>>> stats = pitch.bin_statistic(x, y)
>>> pitch.heatmap(stats, edgecolors='black', cmap='hot', ax=ax)
>>> stats['statistic'] = stats['statistic'].astype(int)
>>> path_eff = [path_effects.Stroke(linewidth=0.5, foreground='#22312b')]
>>> text = pitch.label_heatmap(stats, color='white', ax=ax, fontsize=20, ha='center',
...                            va='center', path_effects=path_eff)
lines(xstart, ystart, xend, yend, color=None, n_segments=100, comet=False, transparent=False, alpha_start=0.01, alpha_end=1, cmap=None, ax=None, **kwargs)

Plots lines using matplotlib.collections.LineCollection. This is a fast way to plot multiple lines without loops. Also enables lines that increase in width or opacity by splitting the line into n_segments of increasing width or opacity as the line progresses.

Parameters:
  • xstart, ystart, xend, yend (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the start and end coordinates of the lines.

  • color (A matplotlib color or sequence of colors, defaults to None.) – Defaults to None. In that case the marker color is determined by the value rcParams[‘lines.color’]

  • n_segments (int, default 100) – If comet=True or transparent=True this is used to split the line into n_segments of increasing width/opacity.

  • comet (bool default False) – Whether to plot the lines increasing in width.

  • transparent (bool, default False) – Whether to plot the lines increasing in opacity.

  • linewidth or lw (array-like or scalar, default 5.) – Multiple linewidths not supported for the comet or transparent lines.

  • alpha_start (float, default 0.01) – The starting alpha value for transparent lines, between 0 (transparent) and 1 (opaque). If transparent = True the line will be drawn to linearly increase in opacity between alpha_start and alpha_end.

  • alpha_end (float, default 1) – The ending alpha value for transparent lines, between 0 (transparent) and 1 (opaque). If transparent = True the line will be drawn to linearly increase in opacity between alpha_start and alpha_end.

  • cmap (str, default None) – A matplotlib cmap (colormap) name

  • vertical (bool, default False) – If the orientation is vertical (True), then the code switches the x and y coordinates.

  • reverse_cmap (bool, default False) – Whether to reverse the cmap colors. If the pitch is horizontal and the y-axis is inverted then set this to True.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.collections.LineCollection.)

Returns:

LineCollection

Return type:

matplotlib.collections.LineCollection

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.lines(20, 20, 45, 80, comet=True, transparent=True, ax=ax)
>>> from mplsoccer.linecollection import lines
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> lines([0.1, 0.4], [0.1, 0.5], [0.9, 0.4], [0.8, 0.8], ax=ax)
plot(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.plot, which automatically flips the x and y coordinates if the pitch is vertical.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.plot.)

Returns:

lines

Return type:

A list of Line2D objects representing the plotted data.

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.plot([30, 35, 20], [30, 19, 40], ax=ax)
polygon(verts, ax=None, **kwargs)

Plot polygons. Automatically flips the x and y vertices if the pitch is vertical.

Parameters:
  • verts (verts is a sequence of (verts0, verts1, …)) – where verts_i is a numpy array of shape (number of vertices, 2).

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to) – matplotlib.patches.Polygon

Return type:

list of matplotlib.patches.Polygon

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch(label=True, axis=True)
>>> fig, ax = pitch.draw()
>>> shape1 = np.array([[50, 2], [80, 30], [40, 30], [40, 20]])
>>> shape2 = np.array([[70, 70], [60, 50], [40, 40]])
>>> verts = [shape1, shape2]
>>> pitch.polygon(verts, color='red', alpha=0.3, ax=ax)
scatter(x, y, rotation_degrees=None, marker=None, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.scatter, which automatically flips the x and y coordinates if the pitch is vertical. You can optionally use a football marker with marker=’football’ and rotate markers with rotation_degrees.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • rotation_degrees (array-like or scalar, default None.) – Rotates the marker in degrees, clockwise. 0 degrees is facing the direction of play. In a horizontal pitch, 0 degrees is this way →, in a vertical pitch, 0 degrees is this way ↑

  • marker (MarkerStyle, optional) – The marker style. marker can be either an instance of the class or the text shorthand for a particular marker. Defaults to None, in which case it takes the value of rcParams[“scatter.marker”] (default: ‘o’) = ‘o’. If marker=’football’ plots a football shape with the pentagons the color of the edgecolors and hexagons the color of the ‘c’ argument; ‘linewidths’ also sets the linewidth of the football marker.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.scatter.)

Returns:

paths – or a tuple of (paths, paths) if marker=’football’

Return type:

matplotlib.collections.PathCollection

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, ax=ax)
>>> from mplsoccer import Pitch
>>> from mplsoccer import arrowhead_marker
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, rotation_degrees=45, marker=arrowhead_marker, ax=ax)
>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.scatter(30, 30, marker='football', ax=ax)
text(x, y, s, ax=None, **kwargs)

Utility wrapper around ax.text which automatically flips the x/y coordinates if the pitch is vertical.

See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.text.html

Parameters:
  • x, y (float) – The position to place the text

  • s (str) – The text

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.text.)

Returns:

annotation

Return type:

matplotlib.text.Text

Examples

>>> from mplsoccer import Pitch
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> pitch.text(60, 40, 'Center of the pitch', va='center', ha='center', ax=ax)
triplot(x, y, ax=None, **kwargs)

Utility wrapper around matplotlib.axes.Axes.triplot

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.

  • ax (matplotlib.axes.Axes, default None) – The axis to plot on.

  • **kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.triplot.)

voronoi(x, y, teams)

Get Voronoi vertices for a set of coordinates. Uses a trick by Dan Nichol (@D4N__ on Twitter) where points are reflected in the pitch lines before calculating the Voronoi. This means that the Voronoi extends to the edges of the pitch. See: https://github.com/ProformAnalytics/tutorial_nbs/blob/master/notebooks/Voronoi%20Reflection%20Trick.ipynb

Players outside the pitch dimensions are assumed to be standing on the pitch edge. This means that their coordinates are clipped to the pitch edges before calculating the Voronoi.

Parameters:
  • x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays. These should be the coordinates on the pitch.

  • teams (array-like or scalar.) – This splits the results into the Voronoi vertices for each team. This can either have integer (1/0) values or boolean (True/False) values. team1 is where team==1 or team==True team2 is where team==0 or team==False

Returns:

  • team1 (a 1d numpy array (length number of players in team 1) of 2d arrays) – Where the individual 2d arrays are coordinates of the Voronoi vertices.

  • team2 (a 1d numpy array (length number of players in team 2) of 2d arrays) – Where the individual 2d arrays are coordinates of the Voronoi vertices.

Examples

>>> from mplsoccer import Pitch
>>> import numpy as np
>>> pitch = Pitch()
>>> fig, ax = pitch.draw()
>>> x = np.random.uniform(low=0, high=120, size=22)
>>> y = np.random.uniform(low=0, high=80, size=22)
>>> teams = np.array([0] * 11 + [1] * 11)
>>> pitch.scatter(x[teams == 0], y[teams == 0], color='red', ax=ax)
>>> pitch.scatter(x[teams == 1], y[teams == 1], color='blue', ax=ax)
>>> team1, team2 = pitch.voronoi(x, y, teams)
>>> team1_poly = pitch.polygon(team1, ax=ax, color='blue', alpha=0.3)
>>> team2_poly = pitch.polygon(team2, ax=ax, color='red', alpha=0.3)