mplsoccer.soccer.pitch module
Module containing: Pitch and VerticalPitch, which are used to plot pitches in mplsoccer
- class mplsoccer.soccer.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.024, 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:
BasePitchSoccer- Attributes:
formationsReturn a list of valid mplsoccer formations.
formations_dataframeReturn 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 (positional play) zones.
bin_statistic_sonar(x, y, angle[, values, ...])Calculates binned statistics using scipy.stats.binned_statistic_dd. 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, 10). :Parameters: * x, y, angle, values (array-like or scalar.) -- Commonly, these parameters are 1D arrays. If the statistic is 'count' then values are ignored. The angle is in radians between 0 and 2*pi. * 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, int] or array_like or [array, array, array], optional) --.
bin_statistic_sonar_zones(x, y, angle, zones)Calculates sonar statistics (angle segments per zone) for zones.
bin_statistic_zones(x, y, zones[, values, ...])Calculates statistics for zones: any tiling of the pitch by rectangles.
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).
draw_zones(zones[, names, facecolor, ...])Draw a zone layout to help build custom heatmap zones iteratively.
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 the Juego de Posición zones as a single matplotlib.collections.PatchCollection.
heatmap_zones(stats[, ax])Plots zone statistics as a single matplotlib.collections.PatchCollection.
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.
mirror_zones(zones[, names, axis, suffixes])Complete a zone layout by reflecting it about the middle of the pitch.
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.
positional_zones([positional])The Juego de Posición (positional play) zone layout and names.
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.
sonar(stats_length[, xindex, yindex, ...])Plot a polar bar chart on an existing Polar axes.
sonar_grid(stats_length[, stats_color, ...])Plot a grid of polar bar charts on an existing axes.
sonar_zones(stats_length[, stats_color, ...])Plot a polar bar chart (sonar) at the center of each zone.
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.
zone_sonar_from_binnumber(binnumber, angle)Calculates sonar statistics (zone by angle segment) from per-point zone identifiers.
zone_statistic_from_binnumber(binnumber[, ...])Calculates zone statistics from per-point zone identifiers.
- 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 (positional play) zones.
- 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 layouts.
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.html
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
- Returns:
zone_statistic – The same dictionary as bin_statistic_zones: the keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’ (the zone areas) and ‘names’ (the zone names).
- 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_positional(x, y) >>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
- bin_statistic_sonar(x, y, angle, values=None, statistic='count', bins=(5, 4, 10), normalize=False, standardized=False, center=True)
Calculates binned statistics using scipy.stats.binned_statistic_dd. 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, 10). :Parameters: * x, y, angle, values (array-like or scalar.) – Commonly, these parameters are 1D arrays.
If the statistic is ‘count’ then values are ignored. The angle is in radians between 0 and 2*pi.
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, int] or array_like or [array, array, array], optional) –
- The bin specification.
A sequence of arrays describing the bin edges along each dimension.
The number of bins for each dimension (nx, ny, nangle = bins).
The number of bins for all dimensions (nx = ny = nangle … = bins).
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)
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
bin_statistic – The keys are ‘statistic’ (the calculated statistic), ‘x_grid’, ‘y_grid’ and ‘angle_grid’ (the bin’s edges), ‘angle_widths’ (the angle bin widths), ‘cx’ and ‘cy’ (the bin centers), ‘binnumber’ (the bin indices each point belongs to) and ‘inside’ (whether the point is inside the pitch). ‘binnumber’ is a (3, N) array (x, y and angle) that represents the bin in which the observation falls, and is -1 for a dimension if the observation falls outside the pitch/ angle range. 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) >>> angle = np.random.uniform(low=0, high=2*np.pi, size=100) >>> stats = pitch.bin_statistic_sonar(x, y, angle)
- bin_statistic_sonar_zones(x, y, angle, zones, values=None, statistic='count', angle_bins=10, normalize=False, standardized=False, names=None, edge_tol=None, center=True)
Calculates sonar statistics (angle segments per zone) for zones.
Each point is assigned to a zone and the angles are binned within each zone.
- Parameters:
x, y, angle (array-like or scalar.) – Commonly, these parameters are 1D arrays. The angle is in radians between 0 and 2*pi.
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1) that together exactly tile the pitch.
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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
angle_bins (int or array_like, default 10) – The number of angle segments, or the segment edges in radians between 0 and 2*pi.
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
standardized (bool, default False) – Whether the x, y and zone values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)
names (list of str, default None) – An optional name for each zone (in the same order as zones).
edge_tol (float, default None) – The absolute tolerance for merging zone edges that differ only by floating point noise into one shared edge. The default None uses a scale-aware tolerance of max(abs(pitch extent)) * 1e-9.
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
zone_sonar – The keys are ‘statistic’ (the calculated statistic with one row per zone and one column per angle segment), ‘count’ (the total number of points in each zone), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’, ‘names’, ‘angle_grid’ (the segment start angles) and ‘angle_widths’ (the segment widths).
- Return type:
dict.
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> zones, names = pitch.positional_zones('full') >>> bs = pitch.bin_statistic_sonar_zones(df.x, df.y, angle, zones, ... angle_bins=4) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_zones(bs, width=10, fc='cornflowerblue', ec='black', ax=ax)
- bin_statistic_zones(x, y, zones, values=None, statistic='count', normalize=False, standardized=False, names=None, edge_tol=None)
Calculates statistics for zones: any tiling of the pitch by rectangles.
Unlike bin_statistic, the zones do not have to form a regular grid: rectangles can span multiple rows/ columns of other rectangles (e.g. the Juego de Posición layout) as long as together they exactly tile the pitch with no gaps or overlaps. The results are flat arrays with one value per zone. Zone k always corresponds to zones[k]/ names[k] as supplied; the zones are never reordered, so you can safely join the results back to a dataframe, e.g. df[‘zone’] = stats[‘binnumber’].
- Parameters:
x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1) that together exactly tile the pitch.
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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. The statistic is computed on the points in each zone, so mean and median are exact for merged zones. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic.html
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
standardized (bool, default False) – Whether the x, y and zone values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)
names (list of str, default None) – An optional name for each zone (in the same order as zones).
edge_tol (float, default None) – The absolute tolerance for merging zone edges that differ only by floating point noise into one shared edge. The default None uses a scale-aware tolerance of max(abs(pitch extent)) * 1e-9.
- Returns:
zone_statistic – The keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone, always populated), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’ (the zone areas) and ‘names’ (the zone names).
- Return type:
dict.
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) >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40), (60, 120, 40, 80)] >>> stats = pitch.bin_statistic_zones(x, y, zones) >>> pc = pitch.heatmap_zones(stats, edgecolors='black', cmap='hot', ax=ax)
- calculate_angle_and_distance(xstart, ystart, xend, yend, 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.
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)
- draw_zones(zones, names=None, facecolor=None, edgecolor=None, alpha=0.5, zorder=3, label=True, ax=None, **kwargs)
Draw a zone layout to help build custom heatmap zones iteratively.
The default settings show overlapping zones in darker colors and gaps show the pitch color. You can validate the zones with bin_statistic_zones.
- Parameters:
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates.
names (list of str, default None) – An optional name for each zone (in the same order as zones).
facecolor (any Matplotlib color or a sequence of colors, default None) – If None, defaults to the first color of rcParams[‘axes.prop_cycle’].
edgecolor (any Matplotlib color, default None) – The zone edge color. If None, defaults to rcParams[‘patch.edgecolor’].
alpha (float, default 0.5) – The transparency of the zones.
zorder (float, default 3) – The zorder for the zones and labels.
label (bool, default True) – Whether to label each zone with its index, or ‘index: name’ when names are given.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to) – matplotlib.collections.PatchCollection.
- Returns:
collection (matplotlib.collections.PatchCollection)
annotations (list of matplotlib.text.Text)
Examples
>>> from mplsoccer import Pitch >>> pitch = Pitch() >>> fig, ax = pitch.draw() >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40)] # gap at (60, 120, 40, 80) >>> collection, annotations = pitch.draw_zones(zones, 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. Positions outside the axes limits (e.g. a full-pitch formation on a half pitch) are not drawn and their value is None, as inset axes are not clipped by their parent axes. - 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 >>> url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg' >>> image = Image.open(urlopen(url)) >>> 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 the Juego de Posición zones as a single matplotlib.collections.PatchCollection.
The same as heatmap_zones.
- Parameters:
stats (dict.) – This should be calculated via bin_statistic_positional().
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.collections.PatchCollection, except vmin/ vmax which set the color limits of the collection.
- Returns:
collection
- Return type:
matplotlib.collections.PatchCollection
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)
- heatmap_zones(stats, ax=None, **kwargs)
Plots zone statistics as a single matplotlib.collections.PatchCollection.
- Parameters:
stats (dict.) – This should be calculated via bin_statistic_zones() or zone_statistic_from_binnumber(). The ‘patches’ (one patch per zone in pitch coordinates) and ‘statistic’ (a flat array of values per zone) keys are used for plotting.
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.collections.PatchCollection, except vmin/ vmax which set the color limits of the collection.
- Returns:
collection
- Return type:
matplotlib.collections.PatchCollection
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) >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40), (60, 120, 40, 80)] >>> stats = pitch.bin_statistic_zones(x, y, zones) >>> pc = pitch.heatmap_zones(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() >>> url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg' >>> image = urlopen(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.
The labels are clipped to the axes, so labels for hidden parts of the pitch (e.g. with negative pads or a half pitch) are not drawn. Pass clip_on=False to draw labels outside the axes.
- 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, default False) – Whether to exclude zeros when labelling the heatmap.
exclude_nan (bool, default False) – Whether to exclude numpy.nan 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.text.Text.)
- Returns:
text
- Return type:
A list of matplotlib.text.Text.
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) >>> 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, str_format='{:.0f}')
- 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)
- mirror_zones(zones, names=None, axis='x', suffixes=None)
Complete a zone layout by reflecting it about the middle of the pitch.
Zone layouts are often symmetric, so you can define the zones for one half (or one quarter) of the pitch and mirror them to cover the whole pitch. Zones that straddle a mirror line symmetrically (e.g. a middle third) are only reflected about the other axis (or kept once), rather than duplicated on top of themselves. Zones that straddle a mirror line asymmetrically raise a ValueError as their reflection would overlap them.
- Parameters:
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1).
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
names (list of str, default None) – An optional name for each zone (in the same order as zones).
axis (str, default ‘x’) – The reflection axis. ‘x’ reflects about the halfway line, ‘y’ reflects about the y midline running from goal to goal and ‘both’ reflects about both (e.g. to complete a quarter-pitch layout).
suffixes (tuple of str, default None) – The suffixes added to the zone names, one per copy of the layout: (supplied, mirrored) for axis=’x’/’y’, or (supplied, x-mirrored, y-mirrored, xy-mirrored) for axis=’both’. The default None uses (‘’, ‘-mirror’) and (‘’, ‘-mirror-x’, ‘-mirror-y’, ‘-mirror-xy’) respectively. Zones that produce no reflections because they straddle the mirror line(s) symmetrically are not given a suffix.
- Returns:
zones (list of tuple) – The supplied (x0, x1, y0, y1) rectangles followed by the reflected rectangles.
names (list of str or None) – A name for each zone, or None if names was None.
Examples
>>> from mplsoccer import Pitch >>> pitch = Pitch() # statsbomb dimensions: the halfway line is x=60 >>> zones = [(80, 120, 0, 80), (40, 80, 0, 80)] >>> names = ['final-third', 'middle-third'] >>> zones, names = pitch.mirror_zones(zones, names, suffixes=('-att', '-def')) >>> names # the middle third straddles halfway symmetrically so is kept once ['final-third-att', 'middle-third', 'final-third-def']
- 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)
- positional_zones(positional='full')
The Juego de Posición (positional play) zone layout and names.
- Parameters:
dim (mplsoccer pitch dimensions)
positional (str, default ‘full’) – One of ‘full’, ‘horizontal’ or ‘vertical’ for the respective layouts.
- Returns:
zones (list of tuple) – A list of (x0, x1, y0, y1) rectangles in pitch coordinates that tile the pitch.
names (list of str) – A name for each zone in the same order as the zones.
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) >>> zones, names = pitch.positional_zones() >>> stats = pitch.bin_statistic_zones(x, y, zones, names=names) >>> pc = pitch.heatmap_zones(stats, cmap='hot', edgecolors='black', 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)
- static sonar(stats_length, xindex=0, yindex=0, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', axis=False, label=False, ax=None, **kwargs)
Plot a polar bar chart on an existing Polar axes.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar(). It controls the length of the bars.
xindex, yindex (int, default 0) – Which grid cell of the binned statistics to plot. The default plots grid cell x = 0, y = 0.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
ax (matplotlib.axes.Axes, default None) – The axis to plot on. This should be an instance of matplotlib.projections.polar.PolarAxes
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull()) & ... (df.player_id == 5503)].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> bs = pitch.bin_statistic_sonar(df.x, df.y, angle, ... bins=(1, 1, 4), center=True) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> ax_inset = pitch.inset_axes(x=60, y=40, width=40, polar=True, ax=ax) >>> bars = pitch.sonar(bs, fc='cornflowerblue', ec='black', ax=ax_inset)
- sonar_grid(stats_length, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', sonar_zorder=5, axis=False, label=False, width=None, height=None, exclude_zeros=True, exclude_nan=True, exclude_outside=True, ax=None, **kwargs)
Plot a grid of polar bar charts on an existing axes.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar(). It controls the length of the bars.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
sonar_zorder (float, default 5) – The zorder of the sonar axes (matplotlib’s default for inset axes is 5).
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
width, height (float, default None) – The width, height of the inset Polar axes in the x/y data coordinates. You should only provide one of the width or height arguments since the Polar axes are square and the other values is set dynamically.
exclude_zeros (bool, default True) – Whether to draw the Polar axes where all the values are zero for the grid cell.
exclude_nan (bool, default True) – Whether to draw the Polar axes where all the values are numpy.nan for the grid cell.
exclude_outside (bool, default True) – Whether to exclude the Polar axes where the grid cell center falls outside the axes limits.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> bs = pitch.bin_statistic_sonar(df.x, df.y, angle, ... bins=(6, 4, 4), center=True) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_grid(bs, width=10, fc='cornflowerblue', ... ec='black', ax=ax)
- sonar_zones(stats_length, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', sonar_zorder=5, axis=False, label=False, width=None, height=None, exclude_zeros=True, exclude_nan=True, exclude_outside=True, ax=None, **kwargs)
Plot a polar bar chart (sonar) at the center of each zone.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar_zones() or zone_sonar_from_binnumber(). It controls the length of the bars.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar_zones() or zone_sonar_from_binnumber(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
sonar_zorder (float, default 5) – The zorder of the sonar axes (matplotlib’s default for inset axes is 5).
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
width, height (float, default None) – The width, height of the inset Polar axes in the x/y data coordinates. You should only provide one of the width or height arguments since the Polar axes are square and the other values is set dynamically.
exclude_zeros (bool, default True) – Whether to draw the Polar axes where all the values are zero for the zone.
exclude_nan (bool, default True) – Whether to draw the Polar axes where all the values are numpy.nan for the zone.
exclude_outside (bool, default True) – Whether to exclude the Polar axes where the zone center falls outside the axes limits.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
- Returns:
axs – One inset axes per zone in the zone order (None where the zone is excluded).
- Return type:
numpy.ndarray of matplotlib.projections.polar.PolarAxes
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> zones, names = pitch.positional_zones('full') >>> bs = pitch.bin_statistic_sonar_zones(df.x, df.y, angle, zones, ... angle_bins=4) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_zones(bs, width=10, fc='cornflowerblue', ... ec='black', 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:
text
- 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)
- static zone_sonar_from_binnumber(binnumber, angle, values=None, statistic='count', angle_bins=10, patches=None, cx=None, cy=None, names=None, area=None, normalize=False, center=True)
Calculates sonar statistics (zone by angle segment) from per-point zone identifiers.
- Parameters:
binnumber (array-like of int) – The zone identifier for each point. Use -1 for points outside the zones. Zone identifiers are zero indexed and correspond to the order of the patches/ names.
angle (array-like or scalar.) – The angle for each point in radians between 0 and 2*pi.
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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
angle_bins (int or array_like, default 10) – The number of angle segments, or the segment edges in radians between 0 and 2*pi.
patches (list of matplotlib.patches.Patch, default None) – One patch per zone in pitch coordinates for plotting with heatmap_zones. If None, the number of zones is inferred from binnumber.max() + 1.
cx, cy (array-like, default None) – The centres for each zone in pitch coordinates where the sonars are placed by sonar_zones. If None, they fall back to a best-effort centroid of the patch path vertices.
names (list of str, default None) – An optional name for each zone.
area (array-like, default None) – An optional area for each zone.
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
zone_sonar – The keys are ‘statistic’ (the calculated statistic with one row per zone and one column per angle segment), ‘count’ (the total number of points in each zone), ‘patches’, ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the zones), ‘inside’ (whether each point is inside the zones), ‘area’, ‘names’, ‘angle_grid’ (the segment start angles) and ‘angle_widths’ (the segment widths).
- Return type:
dict.
Examples
>>> import numpy as np >>> from mplsoccer import Pitch >>> pitch = Pitch() >>> x = np.random.uniform(low=0, high=120, size=100) >>> angle = np.random.uniform(low=0, high=2 * np.pi, size=100) >>> binnumber = (x > 60).astype(int) # two zones: own half (0) and opposition half (1) >>> stats = pitch.zone_sonar_from_binnumber(binnumber, angle, angle_bins=4)
- static zone_statistic_from_binnumber(binnumber, values=None, statistic='count', patches=None, cx=None, cy=None, names=None, area=None, normalize=False)
Calculates zone statistics from per-point zone identifiers.
This is the second half of bin_statistic_zones exposed publicly: you supply the zone each point belongs to (the binnumber), computed however you like (e.g. polar wedges via numpy.arctan2/ numpy.digitize), and it computes the statistic and count per zone and assembles the zone statistics dictionary for plotting with heatmap_zones.
- Parameters:
binnumber (array-like of int) – The zone identifier for each point. Use -1 for points outside the zones. Zone identifiers are zero indexed and correspond to the order of the patches/ names.
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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.html
patches (list of matplotlib.patches.Patch, default None) – One patch per zone in pitch coordinates for plotting with heatmap_zones. If None, the number of zones is inferred from binnumber.max() + 1.
cx, cy (array-like, default None) – The centre of each zone in pitch coordinates, used to place labels (label_heatmap). Supply them for curved patches: the fallback is the centroid of the patch vertices, which can sit outside a Wedge.
names (list of str, default None) – An optional name for each zone.
area (array-like, default None) – An optional area for each zone (e.g. for normalising by area).
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
- Returns:
zone_statistic – The keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone, always populated), ‘patches’ (one matplotlib patch per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the zones), ‘inside’ (whether each point is inside the zones), ‘area’ (the zone areas) and ‘names’ (the zone names).
- Return type:
dict.
Examples
>>> import numpy as np >>> from mplsoccer import Pitch >>> pitch = Pitch() >>> x = np.random.uniform(low=0, high=120, size=100) >>> y = np.random.uniform(low=0, high=80, size=100) >>> binnumber = (x > 60).astype(int) # two zones: own half (0) and opposition half (1) >>> stats = pitch.zone_statistic_from_binnumber(binnumber)
- class mplsoccer.soccer.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.024, 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:
BasePitchSoccer- Attributes:
formationsReturn a list of valid mplsoccer formations.
formations_dataframeReturn 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 (positional play) zones.
bin_statistic_sonar(x, y, angle[, values, ...])Calculates binned statistics using scipy.stats.binned_statistic_dd. 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, 10). :Parameters: * x, y, angle, values (array-like or scalar.) -- Commonly, these parameters are 1D arrays. If the statistic is 'count' then values are ignored. The angle is in radians between 0 and 2*pi. * 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, int] or array_like or [array, array, array], optional) --.
bin_statistic_sonar_zones(x, y, angle, zones)Calculates sonar statistics (angle segments per zone) for zones.
bin_statistic_zones(x, y, zones[, values, ...])Calculates statistics for zones: any tiling of the pitch by rectangles.
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).
draw_zones(zones[, names, facecolor, ...])Draw a zone layout to help build custom heatmap zones iteratively.
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 the Juego de Posición zones as a single matplotlib.collections.PatchCollection.
heatmap_zones(stats[, ax])Plots zone statistics as a single matplotlib.collections.PatchCollection.
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.
mirror_zones(zones[, names, axis, suffixes])Complete a zone layout by reflecting it about the middle of the pitch.
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.
positional_zones([positional])The Juego de Posición (positional play) zone layout and names.
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.
sonar(stats_length[, xindex, yindex, ...])Plot a polar bar chart on an existing Polar axes.
sonar_grid(stats_length[, stats_color, ...])Plot a grid of polar bar charts on an existing axes.
sonar_zones(stats_length[, stats_color, ...])Plot a polar bar chart (sonar) at the center of each zone.
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.
zone_sonar_from_binnumber(binnumber, angle)Calculates sonar statistics (zone by angle segment) from per-point zone identifiers.
zone_statistic_from_binnumber(binnumber[, ...])Calculates zone statistics from per-point zone identifiers.
- 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 (positional play) zones.
- 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 layouts.
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.html
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
- Returns:
zone_statistic – The same dictionary as bin_statistic_zones: the keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’ (the zone areas) and ‘names’ (the zone names).
- 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_positional(x, y) >>> pitch.heatmap_positional(stats, edgecolors='black', cmap='hot', ax=ax)
- bin_statistic_sonar(x, y, angle, values=None, statistic='count', bins=(5, 4, 10), normalize=False, standardized=False, center=True)
Calculates binned statistics using scipy.stats.binned_statistic_dd. 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, 10). :Parameters: * x, y, angle, values (array-like or scalar.) – Commonly, these parameters are 1D arrays.
If the statistic is ‘count’ then values are ignored. The angle is in radians between 0 and 2*pi.
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, int] or array_like or [array, array, array], optional) –
- The bin specification.
A sequence of arrays describing the bin edges along each dimension.
The number of bins for each dimension (nx, ny, nangle = bins).
The number of bins for all dimensions (nx = ny = nangle … = bins).
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)
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
bin_statistic – The keys are ‘statistic’ (the calculated statistic), ‘x_grid’, ‘y_grid’ and ‘angle_grid’ (the bin’s edges), ‘angle_widths’ (the angle bin widths), ‘cx’ and ‘cy’ (the bin centers), ‘binnumber’ (the bin indices each point belongs to) and ‘inside’ (whether the point is inside the pitch). ‘binnumber’ is a (3, N) array (x, y and angle) that represents the bin in which the observation falls, and is -1 for a dimension if the observation falls outside the pitch/ angle range. 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) >>> angle = np.random.uniform(low=0, high=2*np.pi, size=100) >>> stats = pitch.bin_statistic_sonar(x, y, angle)
- bin_statistic_sonar_zones(x, y, angle, zones, values=None, statistic='count', angle_bins=10, normalize=False, standardized=False, names=None, edge_tol=None, center=True)
Calculates sonar statistics (angle segments per zone) for zones.
Each point is assigned to a zone and the angles are binned within each zone.
- Parameters:
x, y, angle (array-like or scalar.) – Commonly, these parameters are 1D arrays. The angle is in radians between 0 and 2*pi.
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1) that together exactly tile the pitch.
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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
angle_bins (int or array_like, default 10) – The number of angle segments, or the segment edges in radians between 0 and 2*pi.
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
standardized (bool, default False) – Whether the x, y and zone values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)
names (list of str, default None) – An optional name for each zone (in the same order as zones).
edge_tol (float, default None) – The absolute tolerance for merging zone edges that differ only by floating point noise into one shared edge. The default None uses a scale-aware tolerance of max(abs(pitch extent)) * 1e-9.
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
zone_sonar – The keys are ‘statistic’ (the calculated statistic with one row per zone and one column per angle segment), ‘count’ (the total number of points in each zone), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’, ‘names’, ‘angle_grid’ (the segment start angles) and ‘angle_widths’ (the segment widths).
- Return type:
dict.
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> zones, names = pitch.positional_zones('full') >>> bs = pitch.bin_statistic_sonar_zones(df.x, df.y, angle, zones, ... angle_bins=4) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_zones(bs, width=10, fc='cornflowerblue', ec='black', ax=ax)
- bin_statistic_zones(x, y, zones, values=None, statistic='count', normalize=False, standardized=False, names=None, edge_tol=None)
Calculates statistics for zones: any tiling of the pitch by rectangles.
Unlike bin_statistic, the zones do not have to form a regular grid: rectangles can span multiple rows/ columns of other rectangles (e.g. the Juego de Posición layout) as long as together they exactly tile the pitch with no gaps or overlaps. The results are flat arrays with one value per zone. Zone k always corresponds to zones[k]/ names[k] as supplied; the zones are never reordered, so you can safely join the results back to a dataframe, e.g. df[‘zone’] = stats[‘binnumber’].
- Parameters:
x, y (array-like or scalar.) – Commonly, these parameters are 1D arrays.
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1) that together exactly tile the pitch.
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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. The statistic is computed on the points in each zone, so mean and median are exact for merged zones. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic.html
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
standardized (bool, default False) – Whether the x, y and zone values have been standardized to the ‘uefa’ pitch coordinates (105m x 68m)
names (list of str, default None) – An optional name for each zone (in the same order as zones).
edge_tol (float, default None) – The absolute tolerance for merging zone edges that differ only by floating point noise into one shared edge. The default None uses a scale-aware tolerance of max(abs(pitch extent)) * 1e-9.
- Returns:
zone_statistic – The keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone, always populated), ‘patches’ (one matplotlib.patches.Rectangle per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the pitch), ‘inside’ (whether each point is inside the pitch), ‘area’ (the zone areas) and ‘names’ (the zone names).
- Return type:
dict.
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) >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40), (60, 120, 40, 80)] >>> stats = pitch.bin_statistic_zones(x, y, zones) >>> pc = pitch.heatmap_zones(stats, edgecolors='black', cmap='hot', ax=ax)
- calculate_angle_and_distance(xstart, ystart, xend, yend, 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.
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)
- draw_zones(zones, names=None, facecolor=None, edgecolor=None, alpha=0.5, zorder=3, label=True, ax=None, **kwargs)
Draw a zone layout to help build custom heatmap zones iteratively.
The default settings show overlapping zones in darker colors and gaps show the pitch color. You can validate the zones with bin_statistic_zones.
- Parameters:
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates.
names (list of str, default None) – An optional name for each zone (in the same order as zones).
facecolor (any Matplotlib color or a sequence of colors, default None) – If None, defaults to the first color of rcParams[‘axes.prop_cycle’].
edgecolor (any Matplotlib color, default None) – The zone edge color. If None, defaults to rcParams[‘patch.edgecolor’].
alpha (float, default 0.5) – The transparency of the zones.
zorder (float, default 3) – The zorder for the zones and labels.
label (bool, default True) – Whether to label each zone with its index, or ‘index: name’ when names are given.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to) – matplotlib.collections.PatchCollection.
- Returns:
collection (matplotlib.collections.PatchCollection)
annotations (list of matplotlib.text.Text)
Examples
>>> from mplsoccer import Pitch >>> pitch = Pitch() >>> fig, ax = pitch.draw() >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40)] # gap at (60, 120, 40, 80) >>> collection, annotations = pitch.draw_zones(zones, 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. Positions outside the axes limits (e.g. a full-pitch formation on a half pitch) are not drawn and their value is None, as inset axes are not clipped by their parent axes. - 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 >>> url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg' >>> image = Image.open(urlopen(url)) >>> 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 the Juego de Posición zones as a single matplotlib.collections.PatchCollection.
The same as heatmap_zones.
- Parameters:
stats (dict.) – This should be calculated via bin_statistic_positional().
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.collections.PatchCollection, except vmin/ vmax which set the color limits of the collection.
- Returns:
collection
- Return type:
matplotlib.collections.PatchCollection
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)
- heatmap_zones(stats, ax=None, **kwargs)
Plots zone statistics as a single matplotlib.collections.PatchCollection.
- Parameters:
stats (dict.) – This should be calculated via bin_statistic_zones() or zone_statistic_from_binnumber(). The ‘patches’ (one patch per zone in pitch coordinates) and ‘statistic’ (a flat array of values per zone) keys are used for plotting.
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.collections.PatchCollection, except vmin/ vmax which set the color limits of the collection.
- Returns:
collection
- Return type:
matplotlib.collections.PatchCollection
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) >>> zones = [(0, 60, 0, 80), (60, 120, 0, 40), (60, 120, 40, 80)] >>> stats = pitch.bin_statistic_zones(x, y, zones) >>> pc = pitch.heatmap_zones(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() >>> url = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg' >>> image = urlopen(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.
The labels are clipped to the axes, so labels for hidden parts of the pitch (e.g. with negative pads or a half pitch) are not drawn. Pass clip_on=False to draw labels outside the axes.
- 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, default False) – Whether to exclude zeros when labelling the heatmap.
exclude_nan (bool, default False) – Whether to exclude numpy.nan 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.text.Text.)
- Returns:
text
- Return type:
A list of matplotlib.text.Text.
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) >>> 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, str_format='{:.0f}')
- 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)
- mirror_zones(zones, names=None, axis='x', suffixes=None)
Complete a zone layout by reflecting it about the middle of the pitch.
Zone layouts are often symmetric, so you can define the zones for one half (or one quarter) of the pitch and mirror them to cover the whole pitch. Zones that straddle a mirror line symmetrically (e.g. a middle third) are only reflected about the other axis (or kept once), rather than duplicated on top of themselves. Zones that straddle a mirror line asymmetrically raise a ValueError as their reflection would overlap them.
- Parameters:
zones (array-like of shape (num_zones, 4)) – A sequence of (x0, x1, y0, y1) rectangles in pitch coordinates (x0 < x1 and y0 < y1).
dim (mplsoccer pitch dimensions) – One of FixedDims, MetricasportsDims, VariableCenterDims, or CustomDims. Automatically populated when using Pitch/ VerticalPitch class
names (list of str, default None) – An optional name for each zone (in the same order as zones).
axis (str, default ‘x’) – The reflection axis. ‘x’ reflects about the halfway line, ‘y’ reflects about the y midline running from goal to goal and ‘both’ reflects about both (e.g. to complete a quarter-pitch layout).
suffixes (tuple of str, default None) – The suffixes added to the zone names, one per copy of the layout: (supplied, mirrored) for axis=’x’/’y’, or (supplied, x-mirrored, y-mirrored, xy-mirrored) for axis=’both’. The default None uses (‘’, ‘-mirror’) and (‘’, ‘-mirror-x’, ‘-mirror-y’, ‘-mirror-xy’) respectively. Zones that produce no reflections because they straddle the mirror line(s) symmetrically are not given a suffix.
- Returns:
zones (list of tuple) – The supplied (x0, x1, y0, y1) rectangles followed by the reflected rectangles.
names (list of str or None) – A name for each zone, or None if names was None.
Examples
>>> from mplsoccer import Pitch >>> pitch = Pitch() # statsbomb dimensions: the halfway line is x=60 >>> zones = [(80, 120, 0, 80), (40, 80, 0, 80)] >>> names = ['final-third', 'middle-third'] >>> zones, names = pitch.mirror_zones(zones, names, suffixes=('-att', '-def')) >>> names # the middle third straddles halfway symmetrically so is kept once ['final-third-att', 'middle-third', 'final-third-def']
- 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)
- positional_zones(positional='full')
The Juego de Posición (positional play) zone layout and names.
- Parameters:
dim (mplsoccer pitch dimensions)
positional (str, default ‘full’) – One of ‘full’, ‘horizontal’ or ‘vertical’ for the respective layouts.
- Returns:
zones (list of tuple) – A list of (x0, x1, y0, y1) rectangles in pitch coordinates that tile the pitch.
names (list of str) – A name for each zone in the same order as the zones.
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) >>> zones, names = pitch.positional_zones() >>> stats = pitch.bin_statistic_zones(x, y, zones, names=names) >>> pc = pitch.heatmap_zones(stats, cmap='hot', edgecolors='black', 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)
- static sonar(stats_length, xindex=0, yindex=0, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', axis=False, label=False, ax=None, **kwargs)
Plot a polar bar chart on an existing Polar axes.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar(). It controls the length of the bars.
xindex, yindex (int, default 0) – Which grid cell of the binned statistics to plot. The default plots grid cell x = 0, y = 0.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
ax (matplotlib.axes.Axes, default None) – The axis to plot on. This should be an instance of matplotlib.projections.polar.PolarAxes
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull()) & ... (df.player_id == 5503)].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> bs = pitch.bin_statistic_sonar(df.x, df.y, angle, ... bins=(1, 1, 4), center=True) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> ax_inset = pitch.inset_axes(x=60, y=40, width=40, polar=True, ax=ax) >>> bars = pitch.sonar(bs, fc='cornflowerblue', ec='black', ax=ax_inset)
- sonar_grid(stats_length, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', sonar_zorder=5, axis=False, label=False, width=None, height=None, exclude_zeros=True, exclude_nan=True, exclude_outside=True, ax=None, **kwargs)
Plot a grid of polar bar charts on an existing axes.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar(). It controls the length of the bars.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
sonar_zorder (float, default 5) – The zorder of the sonar axes (matplotlib’s default for inset axes is 5).
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
width, height (float, default None) – The width, height of the inset Polar axes in the x/y data coordinates. You should only provide one of the width or height arguments since the Polar axes are square and the other values is set dynamically.
exclude_zeros (bool, default True) – Whether to draw the Polar axes where all the values are zero for the grid cell.
exclude_nan (bool, default True) – Whether to draw the Polar axes where all the values are numpy.nan for the grid cell.
exclude_outside (bool, default True) – Whether to exclude the Polar axes where the grid cell center falls outside the axes limits.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> bs = pitch.bin_statistic_sonar(df.x, df.y, angle, ... bins=(6, 4, 4), center=True) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_grid(bs, width=10, fc='cornflowerblue', ... ec='black', ax=ax)
- sonar_zones(stats_length, stats_color=None, cmap=None, vmin=None, vmax=None, rmin=0, rmax=None, sonar_alpha=1, sonar_facecolor='None', sonar_zorder=5, axis=False, label=False, width=None, height=None, exclude_zeros=True, exclude_nan=True, exclude_outside=True, ax=None, **kwargs)
Plot a polar bar chart (sonar) at the center of each zone.
- Parameters:
stats_length (dict) – This should be calculated via bin_statistic_sonar_zones() or zone_sonar_from_binnumber(). It controls the length of the bars.
stats_color (dict, default None) – This should be calculated via bin_statistic_sonar_zones() or zone_sonar_from_binnumber(). It controls the color of the bars via a cmap. The vmin/vmax arguments will set the boundaries for the cmap. If stats_color is None then the color of the bars is controlled by ‘color’, ‘fc’, or ‘facecolor’ arguments.
cmap (str or matplotlib.colors.Colormap, default None) – Controls the color of the bars via stats_color.
vmin, vmax (float, default None) – The cmap is mapped linearly to the range vmin to vmax, so that values equal to or less than vmin are given the first color in the cmap and values equal to or greater than vmax are given the last color in the cmap. The default of None sets the values to the minimum value of stats_color[‘statistic’] and the maximum value of stats_color[‘statistic’].
rmin, rmax (float, default 0 and None) – The radial axis limits. The default rmax of None sets the values to the maximum of stats_length[‘statistic’].
sonar_alpha (float, default 1) – The alpha/ transparency of the sonar axes patch.
sonar_facecolor (any Matplotlib color, default ‘None’) – The facecolor of the sonar axes. The default ‘None’ makes the axes transparent.
sonar_zorder (float, default 5) – The zorder of the sonar axes (matplotlib’s default for inset axes is 5).
axis (bool, default False) – Whether to set the axis spines to visible.
label (bool, default False) – Whether to include the axis labels.
width, height (float, default None) – The width, height of the inset Polar axes in the x/y data coordinates. You should only provide one of the width or height arguments since the Polar axes are square and the other values is set dynamically.
exclude_zeros (bool, default True) – Whether to draw the Polar axes where all the values are zero for the zone.
exclude_nan (bool, default True) – Whether to draw the Polar axes where all the values are numpy.nan for the zone.
exclude_outside (bool, default True) – Whether to exclude the Polar axes where the zone center falls outside the axes limits.
ax (matplotlib.axes.Axes, default None) – The axis to plot on.
**kwargs (All other keyword arguments are passed on to matplotlib.axes.Axes.bar.)
- Returns:
axs – One inset axes per zone in the zone order (None where the zone is excluded).
- Return type:
numpy.ndarray of matplotlib.projections.polar.PolarAxes
Examples
>>> from mplsoccer import Pitch, Sbopen >>> parser = Sbopen() >>> df = parser.event(69251)[0] >>> df = df[(df.type_name == 'Pass') & ... (df.outcome_name.isnull())].copy() >>> pitch = Pitch() >>> angle, distance = pitch.calculate_angle_and_distance(df.x, df.y, ... df.end_x, df.end_y) >>> zones, names = pitch.positional_zones('full') >>> bs = pitch.bin_statistic_sonar_zones(df.x, df.y, angle, zones, ... angle_bins=4) >>> fig, ax = pitch.draw(figsize=(8, 5.5)) >>> axs = pitch.sonar_zones(bs, width=10, fc='cornflowerblue', ... ec='black', 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:
text
- 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)
- static zone_sonar_from_binnumber(binnumber, angle, values=None, statistic='count', angle_bins=10, patches=None, cx=None, cy=None, names=None, area=None, normalize=False, center=True)
Calculates sonar statistics (zone by angle segment) from per-point zone identifiers.
- Parameters:
binnumber (array-like of int) – The zone identifier for each point. Use -1 for points outside the zones. Zone identifiers are zero indexed and correspond to the order of the patches/ names.
angle (array-like or scalar.) – The angle for each point in radians between 0 and 2*pi.
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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
angle_bins (int or array_like, default 10) – The number of angle segments, or the segment edges in radians between 0 and 2*pi.
patches (list of matplotlib.patches.Patch, default None) – One patch per zone in pitch coordinates for plotting with heatmap_zones. If None, the number of zones is inferred from binnumber.max() + 1.
cx, cy (array-like, default None) – The centres for each zone in pitch coordinates where the sonars are placed by sonar_zones. If None, they fall back to a best-effort centroid of the patch path vertices.
names (list of str, default None) – An optional name for each zone.
area (array-like, default None) – An optional area for each zone.
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
center (bool, default True) – Whether to center the sonars so the first segment is centered around zero (True) or starts at zero (False). Centering shifts the angles by half the width of the first segment.
- Returns:
zone_sonar – The keys are ‘statistic’ (the calculated statistic with one row per zone and one column per angle segment), ‘count’ (the total number of points in each zone), ‘patches’, ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the zones), ‘inside’ (whether each point is inside the zones), ‘area’, ‘names’, ‘angle_grid’ (the segment start angles) and ‘angle_widths’ (the segment widths).
- Return type:
dict.
Examples
>>> import numpy as np >>> from mplsoccer import Pitch >>> pitch = Pitch() >>> x = np.random.uniform(low=0, high=120, size=100) >>> angle = np.random.uniform(low=0, high=2 * np.pi, size=100) >>> binnumber = (x > 60).astype(int) # two zones: own half (0) and opposition half (1) >>> stats = pitch.zone_sonar_from_binnumber(binnumber, angle, angle_bins=4)
- static zone_statistic_from_binnumber(binnumber, values=None, statistic='count', patches=None, cx=None, cy=None, names=None, area=None, normalize=False)
Calculates zone statistics from per-point zone identifiers.
This is the second half of bin_statistic_zones exposed publicly: you supply the zone each point belongs to (the binnumber), computed however you like (e.g. polar wedges via numpy.arctan2/ numpy.digitize), and it computes the statistic and count per zone and assembles the zone statistics dictionary for plotting with heatmap_zones.
- Parameters:
binnumber (array-like of int) – The zone identifier for each point. Use -1 for points outside the zones. Zone identifiers are zero indexed and correspond to the order of the patches/ names.
values (array-like or scalar, default None) – The values on which to calculate the statistic. If the statistic is ‘count’ then values are ignored.
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.html
patches (list of matplotlib.patches.Patch, default None) – One patch per zone in pitch coordinates for plotting with heatmap_zones. If None, the number of zones is inferred from binnumber.max() + 1.
cx, cy (array-like, default None) – The centre of each zone in pitch coordinates, used to place labels (label_heatmap). Supply them for curved patches: the fallback is the centroid of the patch vertices, which can sit outside a Wedge.
names (list of str, default None) – An optional name for each zone.
area (array-like, default None) – An optional area for each zone (e.g. for normalising by area).
normalize (bool, default False) – Whether to normalize the statistic by dividing by the total.
- Returns:
zone_statistic – The keys are ‘statistic’ (a flat array of the calculated statistic per zone), ‘count’ (the number of points in each zone, always populated), ‘patches’ (one matplotlib patch per zone), ‘cx’ and ‘cy’ (the zone centres), ‘binnumber’ (the zone identifier per point, -1 if outside the zones), ‘inside’ (whether each point is inside the zones), ‘area’ (the zone areas) and ‘names’ (the zone names).
- Return type:
dict.
Examples
>>> import numpy as np >>> from mplsoccer import Pitch >>> pitch = Pitch() >>> x = np.random.uniform(low=0, high=120, size=100) >>> y = np.random.uniform(low=0, high=80, size=100) >>> binnumber = (x > 60).astype(int) # two zones: own half (0) and opposition half (1) >>> stats = pitch.zone_statistic_from_binnumber(binnumber)