Ejemplo n.º 1
0
df_pass = df.loc[mask_team1, ['x', 'y', 'end_x', 'end_y', 'outcome_name']]
mask_complete = df_pass.outcome_name.isnull()

##############################################################################
# Setup the pitch and number of bins
pitch = Pitch(pitch_type='statsbomb',
              line_zorder=2,
              line_color='#c7d5cc',
              pitch_color='#22312b')
bins = (6, 4)

##############################################################################
# Plotting using a single color and length
fig, ax = pitch.draw(figsize=(16, 11),
                     constrained_layout=True,
                     tight_layout=False)
fig.set_facecolor('#22312b')
# plot the heatmap - darker colors = more passes originating from that square
bs_heatmap = pitch.bin_statistic(df_pass.x,
                                 df_pass.y,
                                 statistic='count',
                                 bins=bins)
hm = pitch.heatmap(bs_heatmap, ax=ax, cmap='Blues')
# plot the pass flow map with a single color ('black') and length of the arrow (5)
fm = pitch.flow(df_pass.x,
                df_pass.y,
                df_pass.end_x,
                df_pass.end_y,
                color='black',
                arrow_type='same',
Ejemplo n.º 2
0
# Filter the dataframes to only include Messi's events and the starting positions

df_false9 = df_false9.loc[df_false9.player_id == 5503, ['x', 'y']]
df_before_false9 = df_before_false9.loc[df_before_false9.player_id == 5503,
                                        ['x', 'y']]

##############################################################################
# View a dataframe

df_false9.head()

##############################################################################
# Plotting Messi's first game as a False-9

pitch = Pitch(pitch_type='statsbomb', pitch_color='grass', stripe=True)
fig, ax = pitch.draw(figsize=(16, 11))

# plotting
ax.set_title('The first Game Messi played in the false 9 role',
             fontsize=30,
             pad=20)

# plot the kernel density estimation
pitch.kdeplot(df_false9.x, df_false9.y, ax=ax, cmap='plasma', linewidths=3)

# annotate
pitch.annotate('6-2 thrashing \nof Real Madrid', (25, 10),
               color='white',
               fontsize=25,
               ha='center',
               va='center',
Ejemplo n.º 3
0
df_away.head()

##############################################################################
# Show the home data
df_home.head()

##############################################################################
# Show the ball data
df_ball.head()

##############################################################################
# Plot the animation

# First set up the figure, the axis
pitch = Pitch(pitch_type='metricasports', goal_type='line', pitch_width=68, pitch_length=105)
fig, ax = pitch.draw(figsize=(16, 10.4))

# then setup the pitch plot markers we want to animate
marker_kwargs = {'marker': 'o', 'markeredgecolor': 'black', 'linestyle': 'None'}
ball, = ax.plot([], [], ms=6, markerfacecolor='w', zorder=3, **marker_kwargs)
away, = ax.plot([], [], ms=10, markerfacecolor='#b94b75', **marker_kwargs)  # red/maroon
home, = ax.plot([], [], ms=10, markerfacecolor='#7f63b8', **marker_kwargs)  # purple


# animation function
def animate(i):
    """ Function to animate the data. Each frame it sets the data for the players and the ball."""
    # set the ball data with the x and y positions for the ith frame
    ball.set_data(df_ball.iloc[i, 3], df_ball.iloc[i, 4])
    # get the frame id for the ith frame
    frame = df_ball.iloc[i, 1]
Ejemplo n.º 4
0
# ######################

# load the image
IMAGE_URL = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg'
image = Image.open(urlopen(IMAGE_URL))

##############################################################################
# Plotting an image over a pitch
# ##############################
#
# To plot images you use ``Axes.imshow()`` in matplotlib.
# We are going to draw a pitch and then overlay ontop an image of Messi on a new axis.

# draw the pitch
pitch = Pitch(line_zorder=2)
fig, ax = pitch.draw(figsize=(16, 9), tight_layout=False)

# add an image
ax_image = add_image(image, fig, left=0.55, bottom=0.2, width=0.2,
                     alpha=0.9, interpolation='hanning')

##############################################################################
# Photo from: https://en.wikipedia.org/wiki/Lionel_Messi#/media/File:Messi_vs_Nigeria_2018.jpg;
# License: https://creativecommons.org/licenses/by-sa/3.0/;
# Creator: Кирилл Венедиктов

##############################################################################
# More control over the images and axis
# #####################################
#
# For more control over where the images are placed,
Ejemplo n.º 5
0
                   path_effects=text_effects,
                   ha='right',
                   color=LINE_COLOR,
                   fontsize=30,
                   fontproperties=fm.prop)

# plotting the glow effect. it is essentially a loop that plots the line with
# a low alpha (transparency) value and gradually increases the linewidth.
# This way the center will have more color than the outer area.
# you could break this up into two loops if you wanted the pitch lines to have wider glow
for i in range(1, NUM_GLOW_LINES + 1):
    pitch = Pitch(line_color=LINE_COLOR,
                  pitch_color=BACKGROUND_COLOR,
                  linewidth=LINEWIDTH + (DIFF_LINEWIDTH * i),
                  line_alpha=ALPHA_PITCH_LINE / NUM_GLOW_LINES,
                  goal_alpha=ALPHA_PITCH_LINE / NUM_GLOW_LINES,
                  goal_type='box')
    pitch.draw(
        ax=ax['pitch'])  # we plot on-top of our previous axis from pitch.grid
    pitch.lines(
        df_pass.x,
        df_pass.y,
        df_pass.end_x,
        df_pass.end_y,
        linewidth=LINEWIDTH + (DIFF_LINEWIDTH * i),
        capstyle='round',  # capstyle round so the glow extends past the line
        alpha=ALPHA_PASS_LINE / NUM_GLOW_LINES,
        color=PASS_COLOR,
        comet=True,
        ax=ax['pitch'])
Ejemplo n.º 6
0
============

First we import the Pitch classes and matplotlib
"""
import matplotlib.pyplot as plt

from mplsoccer import Pitch, VerticalPitch

##############################################################################
# Draw a pitch on a new axis
# --------------------------
# Let's plot on a new axis first.

pitch = Pitch()
# specifying figure size (width, height)
fig, ax = pitch.draw(figsize=(8, 4))

##############################################################################
# Draw on an existing axis
# ------------------------
# mplsoccer also plays nicely with other matplotlib figures. To draw a pitch on an
# existing matplotlib axis specify an ``ax`` in the ``draw`` method.

fig, axs = plt.subplots(nrows=1, ncols=2)
pitch = Pitch()
pie = axs[0].pie(x=[5, 15])
pitch.draw(ax=axs[1])

##############################################################################
# Supported data providers
# ------------------------
Ejemplo n.º 7
0
##############################################################################
# Plot the percentages

# setup a mplsoccer pitch
pitch = Pitch(line_zorder=2, line_color='black')

# mplsoccer calculates the binned statistics usually from raw locations, such as pressure events
# for this example we will create a binned statistic dividing
# the pitch into thirds for one point (0, 0)
# we will fill this in a loop later with each team's statistics from the dataframe
bin_statistic = pitch.bin_statistic([0], [0], statistic='count', bins=(3, 1))

# Plot
fig, axes = pitch.draw(figsize=(16, 9),
                       ncols=5,
                       nrows=4,
                       tight_layout=False,
                       constrained_layout=True)
axes = axes.ravel()
teams = df['Squad'].values
vmin = df[pressure_cols].min().min(
)  # we normalise the heatmaps with the min / max values
vmax = df[pressure_cols].max().max()
for i, ax in enumerate(axes[:len(teams)]):
    ax.set_title(teams[i], fontsize=20)
    # fill in the bin statistics from df and plot the heatmap
    bin_statistic['statistic'] = df.loc[df.Squad == teams[i],
                                        pressure_cols].values
    heatmap = pitch.heatmap(bin_statistic,
                            ax=ax,
                            cmap='coolwarm',
Ejemplo n.º 8
0
"""
===========
Quick start
===========
"""
from mplsoccer import Pitch
pitch = Pitch(pitch_color='grass', line_color='white', stripe=True)
fig, ax = pitch.draw()
Ejemplo n.º 9
0
kwargs = {
    'related_event_df': False,
    'shot_freeze_frame_df': False,
    'tactics_lineup_df': False,
    'warn': False
}
df_false9 = read_event(f'{EVENT_SLUG}/69249.json', **kwargs)['event']
df_before_false9 = read_event(f'{EVENT_SLUG}/69251.json', **kwargs)['event']
# filter messi's actions (starting positions)
df_false9 = df_false9.loc[df_false9.player_id == 5503, ['x', 'y']]
df_before_false9 = df_before_false9.loc[df_before_false9.player_id == 5503,
                                        ['x', 'y']]

##############################################################################
# plotting
pitch = Pitch(pitch_type='statsbomb',
              pitch_color='#22312b',
              stripe=False,
              line_zorder=2)
fig, ax = pitch.draw(
    figsize=(16, 9),
    nrows=1,
    ncols=2,
)
pitch.hexbin(df_before_false9.x, df_before_false9.y, ax=ax[0], cmap='Blues')
pitch.hexbin(df_false9.x, df_false9.y, ax=ax[1], cmap='Blues')
TITLE_STR1 = 'Messi in the game directly before \n playing in the false 9 role'
TITLE_STR2 = 'The first Game Messi \nplayed in the false 9 role'
title1 = ax[0].set_title(TITLE_STR1, fontsize=25, pad=20)
title2 = ax[1].set_title(TITLE_STR2, fontsize=25, pad=20)
Ejemplo n.º 10
0
    'related_event_df': False,
    'shot_freeze_frame_df': False,
    'tactics_lineup_df': False,
    'warn': False
}
df = pd.concat([
    read_event(f'{EVENT_SLUG}/{file}', **kwargs)['event']
    for file in match_files
])
# filter chelsea pressure events
mask_chelsea_pressure = (df.team_name == 'Chelsea FCW') & (df.type_name
                                                           == 'Pressure')
df = df.loc[mask_chelsea_pressure, ['x', 'y']]

##############################################################################
# Plot the heatmaps

# setup pitch
pitch = Pitch(pitch_type='statsbomb', line_zorder=2, line_color='white')
# draw
fig, ax = pitch.draw(figsize=(16, 9))
bin_statistic = pitch.bin_statistic(df.x,
                                    df.y,
                                    statistic='count',
                                    bins=(25, 25))
bin_statistic['statistic'] = gaussian_filter(bin_statistic['statistic'], 1)
pcm = pitch.heatmap(bin_statistic, ax=ax, cmap='hot', edgecolors='#22312b')
cbar = fig.colorbar(pcm, ax=ax)
TITLE_STR = 'Location of pressure events - 3 home games for Chelsea FC Women'
title = fig.suptitle(TITLE_STR, x=0.4, y=0.98, fontsize=23)
height6 = BOTTOM_WIDTH / pitch6.ax_aspect * FIG_ASPECT

# calculate pitch offsets from center / title locations
vertical_axes_space = (1 - (height1 + height4 + TITLE_HEIGHT + TITLE_HEIGHT)) / 5
bottom_offset = ((1 - height4) / 2) - vertical_axes_space
title1_bottom = 1 - vertical_axes_space - TITLE_HEIGHT
title2_bottom = 1 - (vertical_axes_space * 3) - (TITLE_HEIGHT * 2) - height1
top_offset = (1 - title1_bottom - title2_bottom - TITLE_HEIGHT) / 2

# draw pitches

# top left
LEFT1 = TOP_SPACE
bottom1 = (1 - height1) / 2 - top_offset
ax1 = fig.add_axes((LEFT1, bottom1, TOP_WIDTH, height1))
pitch1.draw(ax=ax1)

# top middle
left2 = (TOP_SPACE * 2) + TOP_WIDTH
bottom2 = (1 - height2) / 2 - top_offset
ax2 = fig.add_axes((left2, bottom2, TOP_WIDTH, height2))
pitch2.draw(ax=ax2)

# top right
left3 = (TOP_SPACE * 3) + (TOP_WIDTH * 2)
bottom3 = (1 - height3) / 2 - top_offset
ax3 = fig.add_axes((left3, bottom3, TOP_WIDTH, height3))
pitch3.draw(ax=ax3)

# bottom left
LEFT4 = BOTTOM_SPACE
Ejemplo n.º 12
0
import matplotlib.pyplot as plt

# read data
df = read_event(f'{EVENT_SLUG}/7478.json',
                related_event_df=False,
                shot_freeze_frame_df=False,
                tactics_lineup_df=False)['event']

##############################################################################
# Filter passes by Jodie Taylor
df = df[(df.player_name == 'Jodie Taylor') & (df.type_name == 'Pass')].copy()

##############################################################################
# Plotting

pitch = Pitch()
fig, ax = pitch.draw(figsize=(8, 6))
hull = pitch.convexhull(df.x, df.y)
poly = pitch.polygon(hull,
                     ax=ax,
                     edgecolor='cornflowerblue',
                     facecolor='cornflowerblue',
                     alpha=0.3)
scatter = pitch.scatter(df.x,
                        df.y,
                        ax=ax,
                        edgecolor='black',
                        facecolor='cornflowerblue')
plt.show(
)  # if you are not using a Jupyter notebook this is necessary to show the plot
Ejemplo n.º 13
0
    'ha': 'center',
    'va': 'bottom',
    'fontweight': 'bold',
    'fontstyle': 'italic',
    'c': FONTCOLOR
}

for idx, pt in enumerate(pitch_types):
    if pt in ['tracab', 'metricasports', 'custom', 'skillcorner']:
        pitch = Pitch(pitch_type=pt,
                      pitch_length=105,
                      pitch_width=68,
                      **pitch_kwargs)
    else:
        pitch = Pitch(pitch_type=pt, **pitch_kwargs)
    pitch.draw(axes[idx])
    xmin, xmax, ymin, ymax = pitch.extent
    if pitch.dim.aspect != 1:
        TEXT = 'data coordinates \n are square (1:1) \n scale up to a real-pitch size'
        axes[idx].annotate(TEXT,
                           xy=(xmin, ymin),
                           xytext=(0 + (xmax - xmin) / 2, ymin),
                           **font_kwargs)
    axes[idx].xaxis.set_ticks([xmin, xmax])
    axes[idx].yaxis.set_ticks([ymin, ymax])
    axes[idx].tick_params(labelsize=15)
    if pt == 'skillcorner':
        axes[idx].set_title('skillcorner / secondspectrum',
                            fontsize=20,
                            c='#9749b9',
                            pad=15)