import pandas as pd
import matplotlib.pyplot as plt
from mplsoccer.pitch import Pitch
import seaborn as sns
#Read in the data
df = pd.read_csv('messibetis.csv')
#convert the data to match the mplsoccer statsbomb pitch
#to see how to create the pitch, watch the video here: https://www.youtube.com/watch?v=55k1mCRyd2k
df['x'] = df['x']*1.2
df['y'] = df['y']*.8
df['endX'] = df['endX']*1.2
df['endY'] = df['endY']*.8
df
player | minute | second | x | y | type | outcome | endX | endY | |
---|---|---|---|---|---|---|---|---|---|
0 | messi | 45 | 0 | 60.0 | 40.0 | Pass | Successful | 48.0 | 34.4 |
1 | messi | 45 | 25 | 75.6 | 38.4 | Pass | Successful | 90.0 | 66.4 |
2 | messi | 46 | 4 | 88.8 | 46.4 | Pass | Successful | 85.2 | 52.0 |
3 | messi | 46 | 7 | 91.2 | 54.4 | Pass | Successful | 114.0 | 62.4 |
4 | messi | 46 | 55 | 120.0 | 0.8 | Pass | Unsuccessful | 115.2 | 30.4 |
5 | messi | 47 | 42 | 87.6 | 20.0 | Pass | Successful | 84.0 | 43.2 |
6 | messi | 49 | 47 | 90.0 | 34.4 | Pass | Unsuccessful | 98.4 | 30.4 |
7 | messi | 50 | 10 | 94.8 | 24.8 | Pass | Successful | 104.4 | 19.2 |
8 | messi | 50 | 17 | 98.4 | 41.6 | Pass | Successful | 111.6 | 54.4 |
9 | messi | 50 | 24 | 117.6 | 49.6 | Pass | Unsuccessful | 117.6 | 48.8 |
10 | messi | 55 | 22 | 36.0 | 9.6 | Pass | Successful | 26.4 | 19.2 |
11 | messi | 56 | 24 | 45.6 | 33.6 | Pass | Successful | 44.4 | 40.8 |
12 | messi | 56 | 36 | 63.6 | 35.2 | Pass | Successful | 51.6 | 49.6 |
13 | messi | 56 | 43 | 73.2 | 50.4 | Pass | Successful | 76.8 | 50.4 |
14 | messi | 57 | 2 | 115.2 | 26.4 | Pass | Successful | 109.2 | 27.2 |
15 | messi | 62 | 25 | 55.2 | 36.0 | Pass | Successful | 45.6 | 34.4 |
16 | messi | 62 | 31 | 58.8 | 53.6 | Pass | Successful | 73.2 | 76.8 |
17 | messi | 63 | 36 | 76.8 | 17.6 | Pass | Successful | 75.6 | 8.0 |
18 | messi | 63 | 40 | 88.8 | 5.6 | Pass | Successful | 79.2 | 7.2 |
19 | messi | 63 | 42 | 84.0 | 4.8 | Pass | Successful | 75.6 | 7.2 |
20 | messi | 63 | 43 | 80.4 | 3.2 | Pass | Successful | 74.4 | 7.2 |
21 | messi | 63 | 48 | 82.8 | 3.2 | Pass | Successful | 74.4 | 7.2 |
22 | messi | 66 | 27 | 78.0 | 28.8 | Pass | Successful | 85.2 | 40.8 |
23 | messi | 67 | 40 | 87.6 | 46.4 | Pass | Unsuccessful | 104.4 | 32.8 |
24 | messi | 68 | 19 | 79.2 | 53.6 | Pass | Successful | 72.0 | 55.2 |
25 | messi | 69 | 25 | 85.2 | 63.2 | Pass | Successful | 75.6 | 57.6 |
26 | messi | 71 | 29 | 76.8 | 24.0 | Pass | Successful | 82.8 | 48.0 |
27 | messi | 71 | 46 | 97.2 | 45.6 | Pass | Successful | 115.2 | 56.8 |
28 | messi | 73 | 44 | 60.0 | 40.0 | Pass | Successful | 56.4 | 41.6 |
29 | messi | 76 | 11 | 80.4 | 34.4 | Pass | Successful | 90.0 | 32.8 |
30 | messi | 76 | 25 | 92.4 | 32.8 | Pass | Unsuccessful | 100.8 | 29.6 |
31 | messi | 77 | 59 | 120.0 | 80.0 | Pass | Successful | 110.4 | 76.8 |
32 | messi | 78 | 3 | 105.6 | 76.8 | Pass | Successful | 82.8 | 65.6 |
33 | messi | 78 | 9 | 99.6 | 76.8 | Pass | Successful | 97.2 | 66.4 |
34 | messi | 78 | 58 | 76.8 | 40.8 | Pass | Successful | 82.8 | 66.4 |
35 | messi | 79 | 5 | 80.4 | 53.6 | Pass | Successful | 79.2 | 43.2 |
36 | messi | 79 | 19 | 84.0 | 44.8 | Pass | Successful | 102.0 | 69.6 |
37 | messi | 79 | 31 | 91.2 | 67.2 | Pass | Successful | 78.0 | 58.4 |
38 | messi | 80 | 26 | 120.0 | 0.8 | Pass | Successful | 110.4 | 4.0 |
39 | messi | 80 | 30 | 98.4 | 2.4 | Pass | Successful | 91.2 | 13.6 |
40 | messi | 81 | 14 | 70.8 | 3.2 | Pass | Successful | 82.8 | 3.2 |
41 | messi | 81 | 20 | 96.0 | 4.8 | Pass | Successful | 97.2 | 15.2 |
42 | messi | 83 | 14 | 85.2 | 32.0 | Pass | Unsuccessful | 105.6 | 44.0 |
43 | messi | 87 | 24 | 69.6 | 33.6 | Pass | Successful | 79.2 | 59.2 |
44 | messi | 88 | 22 | 120.0 | 0.8 | Pass | Successful | 87.6 | 20.8 |
45 | messi | 90 | 18 | 85.2 | 20.0 | Pass | Unsuccessful | 109.2 | 41.6 |
46 | messi | 91 | 18 | 79.2 | 24.8 | Pass | Successful | 91.2 | 16.0 |
47 | messi | 91 | 46 | 88.8 | 30.4 | Pass | Unsuccessful | 91.2 | 28.8 |
48 | messi | 94 | 7 | 68.4 | 29.6 | Pass | Unsuccessful | 108.0 | 43.2 |
fig ,ax = plt.subplots(figsize=(13.5,8))
fig.set_facecolor('#22312b')
ax.patch.set_facecolor('#22312b')
#this is how we create the pitch
pitch = Pitch(pitch_type='statsbomb', orientation='horizontal',
pitch_color='#22312b', line_color='#c7d5cc', figsize=(13, 8),
constrained_layout=False, tight_layout=True)
#Draw the pitch on the ax figure as well as invert the axis for this specific pitch
pitch.draw(ax=ax)
plt.gca().invert_yaxis()
#Create the heatmap
kde = sns.kdeplot(
df['x'],
df['y'],
shade = True,
shade_lowest=False,
alpha=.5,
n_levels=10,
cmap = 'magma'
)
#use a for loop to plot each pass
for x in range(len(df['x'])):
if df['outcome'][x] == 'Successful':
plt.plot((df['x'][x],df['endX'][x]),(df['y'][x],df['endY'][x]),color='green')
plt.scatter(df['x'][x],df['y'][x],color='green')
if df['outcome'][x] == 'Unsuccessful':
plt.plot((df['x'][x],df['endX'][x]),(df['y'][x],df['endY'][x]),color='red')
plt.scatter(df['x'][x],df['y'][x],color='red')
plt.xlim(0,120)
plt.ylim(0,80)
plt.title('Messi Pass Map vs Real Betis',color='white',size=20)
Text(0.5, 1.0, 'Messi Pass Map vs Real Betis')