コード例 #1
0
def keypasses(Df,hometeam,homeid,awayteam,awayid):
    df = Df.copy()
    pitch = Pitch(pitch_type='statsbomb', figsize=(10,5), line_zorder=2, layout=(1,2),
                  line_color='k', orientation='horizontal',constrained_layout=True, tight_layout=False)
    fig, ax = pitch.draw()
    
    homedef = df.query("(teamId==@homeid)&(KP == 1)&(endX!=0)&(endY!=0)")
    awaydef = df.query("(teamId==@awayid)&(KP == 1)&(endX!=0)&(endY!=0)")
    # homemask = homedef.outcomeType_displayName == 'Successful'
    # awaymask = awaydef.outcomeType_displayName == 'Successful'

    pitch.arrows(homedef.x,80-homedef.y,homedef.endX,80-homedef.endY,headwidth=5, headlength=5,
                zorder=5,color='#fee090',width=1,ax=ax[0])
    # pitch.lines(homedef[~homemask].x,80-homedef[~homemask].y,homedef[~homemask].endX,80-homedef[~homemask].endY,
    #             zorder=5,color='tab:red',linewidth=2,comet=True,ax=ax[0])
    
    pitch.arrows(awaydef.x,80-awaydef.y,awaydef.endX,80-awaydef.endY,headwidth=5, headlength=5,
                zorder=5,color='#fee090',width=1,ax=ax[1])
    # pitch.lines(awaydef[~awaymask].x,80-awaydef[~awaymask].y,awaydef[~awaymask].endX,80-awaydef[~awaymask].endY,
    #             zorder=5,color='tab:red',linewidth=2,comet=True,ax=ax[1])

    ax[0].set_title(hometeam+'\n'+'Key Passes',fontsize=30)        
    ax[1].set_title(awayteam+'\n'+'Key Passes',fontsize=30)
    fig.text(0.0, 0.0, "Created by Soumyajit Bose / @Soumyaj15209314",fontstyle="italic",fontsize=15,color='#edece9')
    # add_image(bu_alt, fig, left=0.9, bottom=0.01, width=0.07)
    return fig
コード例 #2
0
def badpasses(Df,hometeam,homeid):
    df = Df.copy()
    pitch = Pitch(pitch_type='statsbomb', figsize=(10,4.5), line_zorder=2, layout=(1,2),
                  line_color='k', orientation='horizontal',constrained_layout=True, tight_layout=False)
    fig, ax = pitch.draw()
    
    def3rd = df.query("(teamId==@homeid)&(type_displayName == 'Pass')&(x<40)")
    mid3rd = df.query("(teamId==@homeid)&(type_displayName == 'Pass')&(x>=40)&(x<80)")
    defmask = def3rd.outcomeType_displayName == 'Successful'
    midmask = mid3rd.outcomeType_displayName == 'Successful'
    # awaymask = awaydef.outcomeType_displayName == 'Successful'

    pitch.arrows(def3rd[~defmask].x,80-def3rd[~defmask].y,def3rd[~defmask].endX,80-def3rd[~defmask].endY,
        headwidth=5, headlength=5,zorder=5,color='tab:red',width=1,ax=ax[0])
    # pitch.lines(homedef[~homemask].x,80-homedef[~homemask].y,homedef[~homemask].endX,80-homedef[~homemask].endY,
    #             zorder=5,color='tab:red',linewidth=2,comet=True,ax=ax[0])
    
    pitch.arrows(mid3rd[~midmask].x,80-mid3rd[~midmask].y,mid3rd[~midmask].endX,80-mid3rd[~midmask].endY,
        headwidth=5, headlength=5,zorder=5,color='tab:red',width=1,ax=ax[1])
    # pitch.lines(awaydef[~awaymask].x,80-awaydef[~awaymask].y,awaydef[~awaymask].endX,80-awaydef[~awaymask].endY,
    #             zorder=5,color='tab:red',linewidth=2,comet=True,ax=ax[1])

    ax[0].set_title(hometeam+' Unsuccessful Passes'+'\n'+'from defensive 3rd',fontsize=20)        
    ax[1].set_title(hometeam+' Unsuccessful Passes'+'\n'+'from middle 3rd',fontsize=20)
    # fig.text(0.0, 0.05, "All unsuccessful passes originating from defensive third of the pitch",fontstyle="italic",fontsize=15,color='#edece9')
    fig.text(0.0, 0.0, "Created by Soumyajit Bose / @Soumyaj15209314",fontstyle="italic",fontsize=15,color='#edece9')
    # add_image(bu_alt, fig, left=0.9, bottom=0.0, width=0.07)
    return fig
                  constrained_layout=True,
                  tight_layout=False)
    fig, ax = pitch.draw()
    fig.set_facecolor('#22312b')

for i, pas in Passes.iterrows():
    x = pas['location'][0]
    y = pas['location'][1]
    endx = pas['pass_end_location'][0]
    endy = pas['pass_end_location'][1]
    name = pas['player_name'] == 'Virgil van Dijk'
    if name:
        pitch.scatter(x,
                      y,
                      ax=ax,
                      s=100,
                      edgecolor='black',
                      facecolor='cornflowerblue')
        pitch.arrows(x,
                     y,
                     endx,
                     endy,
                     width=2,
                     headwidth=10,
                     headlength=10,
                     color='#ad993c',
                     ax=ax,
                     label='completed passes')

ax.set_title('VVD vs Spurs', color='#dee6ea', fontsize=25)
コード例 #4
0
ファイル: plot_arrows.py プロジェクト: oruburos/mplsoccer
# Setup the pitch
pitch = Pitch(pitch_type='statsbomb',
              orientation='horizontal',
              pitch_color='#22312b',
              line_color='#c7d5cc',
              figsize=(16, 11),
              constrained_layout=False,
              tight_layout=True)
fig, ax = pitch.draw()

# Plot the completed passes
pitch.arrows(df_pass[mask_complete].x,
             df_pass[mask_complete].y,
             df_pass[mask_complete].pass_end_x,
             df_pass[mask_complete].pass_end_y,
             width=2,
             headwidth=10,
             headlength=10,
             color='#ad993c',
             ax=ax,
             label='completed passes')

# Plot the other passes
pitch.arrows(df_pass[~mask_complete].x,
             df_pass[~mask_complete].y,
             df_pass[~mask_complete].pass_end_x,
             df_pass[~mask_complete].pass_end_y,
             width=2,
             headwidth=6,
             headlength=5,
             headaxislength=12,
             color='#ba4f45',
コード例 #5
0
def getTeamTotalPasses(events_df, teamId, team, opponent, pitch_color):
    """
    

    Parameters
    ----------
    events_df : DataFrame of all events.
    
    teamId : ID of the team, the passes of which are required.
    
    team : Name of the team, the passes of which are required.
    
    opponent : Name of opponent team.
    
    pitch_color : color of the pitch.


    Returns
    -------
    Pitch Plot.
    """

    # Get Total Passes
    passes_df = events_df.loc[events_df['type'] == 'Pass'].reset_index(
        drop=True)

    # Get Team Passes
    team_passes = passes_df.loc[passes_df['teamId'] == teamId]

    successful_passes = team_passes.loc[team_passes['outcomeType'] ==
                                        'Successful'].reset_index(drop=True)
    unsuccessful_passes = team_passes.loc[
        team_passes['outcomeType'] == 'Unsuccessful'].reset_index(drop=True)

    # Setup the pitch
    pitch = Pitch(pitch_type='statsbomb',
                  pitch_color=pitch_color,
                  line_color='#c7d5cc',
                  figsize=(16, 11))
    fig, ax = pitch.draw(constrained_layout=True, tight_layout=False)

    # Plot the completed passes
    pitch.arrows(successful_passes.x / 100 * 120,
                 80 - successful_passes.y / 100 * 80,
                 successful_passes.endX / 100 * 120,
                 80 - successful_passes.endY / 100 * 80,
                 width=1,
                 headwidth=10,
                 headlength=10,
                 color='#ad993c',
                 ax=ax,
                 label='Completed')

    # Plot the other passes
    pitch.arrows(unsuccessful_passes.x / 100 * 120,
                 80 - unsuccessful_passes.y / 100 * 80,
                 unsuccessful_passes.endX / 100 * 120,
                 80 - unsuccessful_passes.endY / 100 * 80,
                 width=1,
                 headwidth=6,
                 headlength=5,
                 headaxislength=12,
                 color='#ba4f45',
                 ax=ax,
                 label='Blocked')

    # setup the legend
    ax.legend(facecolor=pitch_color,
              handlelength=5,
              edgecolor='None',
              fontsize=8,
              loc='upper left',
              shadow=True)

    # Set the title
    fig.suptitle(f'{team} Passes vs {opponent}', y=1, fontsize=15)

    # Set the subtitle
    ax.set_title('Data : Whoscored/Opta',
                 fontsize=8,
                 loc='right',
                 fontstyle='italic',
                 fontweight='bold')

    # Set the figure facecolor

    fig.set_facecolor(pitch_color)
コード例 #6
0
def passmap(Df, teamid, teamname, min1, max1):
    pitch = Pitch(pitch_type='statsbomb',
                  orientation='vertical',
                  pitch_color='#000000',
                  line_color='#a9a9a9',
                  constrained_layout=True,
                  tight_layout=False,
                  linewidth=0.5)

    fig, ax = pitch.draw()
    df = Df.copy()
    df = df[(df.expandedMinute >= min1) & (df.expandedMinute <= max1)]
    allplayers = df[(df.teamId == teamid) & (df.name.notna())].name.tolist()
    playersubbedoff = df[(df.type_displayName == 'SubstitutionOff')
                         & (df.teamId == teamid)]['name'].tolist()
    timeoff = df[(df.type_displayName == 'SubstitutionOff')
                 & (df.teamId == teamid)]['expandedMinute'].tolist()
    playersubbedon = df[(df.type_displayName == 'SubstitutionOn')
                        & (df.teamId == teamid)]['name'].tolist()
    timeon = df[(df.type_displayName == 'SubstitutionOn')
                & (df.teamId == teamid)]['expandedMinute'].tolist()
    majoritylist = []
    minoritylist = []
    for i in range(len(timeon)):
        if ((timeon[i] >= min1) & (timeon[i] <= max1)):
            player1min = timeon[i] - min1
            player2min = max1 - timeon[i]
            if (player1min >= player2min):
                majoritylist.append(playersubbedoff[i])
                minoritylist.append(playersubbedon[i])
            else:
                majoritylist.append(playersubbedon[i])
                minoritylist.append(playersubbedoff[i])
    players = list(set(allplayers) - set(minoritylist))
    #return players

    shirtNo = []
    for p in players:
        shirtNo.append(int(df[df.name == p]['shirtNo'].values[0]))
    passes_df = df.query(
        "(type_displayName=='Pass')&(name in @players)&(receiver in @players)&\
						 (outcomeType_displayName == 'Successful')&(teamId==@teamid)")
    #passes_df.insert(29, column='passRecipientName', value=passes_df['name'].shift(-1))
    passes_df.dropna(subset=["receiver"], inplace=True)

    #passes_df['passer'] = passes_df['playerId']
    #passes_df['recipient'] = passes_df['passer'].shift(-1)
    passes_df = passes_df[passes_df.columns[~passes_df.isnull().all()]]
    passes_df['playerKitNumber'] = passes_df['shirtNo'].fillna(0).astype(
        np.int)
    passes_df['playerKitNumberReceipt'] = passes_df['shirtNo'].shift(
        -1).fillna(0).astype(np.int)

    passer_avg = passes_df.groupby('playerKitNumber').agg({
        'x': ['median'],
        'y': ['median', 'count'],
        'epv_value': ['sum']
    })

    passer_avg.columns = ['x', 'y', 'count', 'epv']
    passer_avg.index = passer_avg.index.astype(int)
    passes_formation = passes_df[[
        'id', 'playerKitNumber', 'playerKitNumberReceipt'
    ]].copy()

    passes_formation['kitNo_max'] = passes_formation[[
        'playerKitNumber', 'playerKitNumberReceipt'
    ]].max(axis='columns')
    passes_formation['kitNo_min'] = passes_formation[[
        'playerKitNumber', 'playerKitNumberReceipt'
    ]].min(axis='columns')

    passes_between = passes_formation.groupby(['kitNo_max', 'kitNo_min'
                                               ]).id.count().reset_index()
    passes_between.rename({'id': 'pass_count'}, axis='columns', inplace=True)

    # add on the location of each player so we have the start and end positions of the lines
    passes_between = passes_between.merge(passer_avg,
                                          left_on='kitNo_min',
                                          right_index=True)
    passes_between = passes_between.merge(passer_avg,
                                          left_on='kitNo_max',
                                          right_index=True,
                                          suffixes=['', '_end'])
    '''
	#Between Passer and Recipient
	passes_between = passes_df.groupby(['passer', 'recipient']).id.count().reset_index()
	passes_between.rename({'id': 'pass_count'}, axis='columns', inplace=True)
	
	passes_between = passes_between.merge(passer_avg, left_on='passer', right_index=True)
	passes_between = passes_between.merge(passer_avg, left_on='recipient', right_index=True,
										  suffixes=['', '_end'])
	'''
    #Minimum No. of Passes
    passes_between = passes_between.loc[(passes_between['pass_count'] >= 3)]

    #Scaling for StatsBomb
    passes_between['x'] = passes_between['x'] * 1.2
    passes_between['y'] = passes_between['y'] * 0.8
    passer_avg['x'] = passer_avg['x'] * 1.2
    passer_avg['y'] = passer_avg['y'] * 0.8
    passes_between['x_end'] = passes_between['x_end'] * 1.2
    passes_between['y_end'] = passes_between['y_end'] * 0.8

    #Width Variable
    yo = passes_between.pass_count / passes_between.pass_count.max()
    b = 1
    min_transparency = 0.3
    color = np.array(to_rgba('#00bfff'))
    color = np.tile(color, (len(passes_between), 1))
    c_transparency = passes_between.pass_count / passes_between.pass_count.max(
    )
    c_transparency = (c_transparency *
                      (1 - min_transparency)) + min_transparency
    color[:, 3] = c_transparency
    a = plt.scatter(passer_avg.y,
                    passer_avg.x,
                    s=100,
                    c="#111111",
                    facecolor='none',
                    lw=1,
                    cmap="winter",
                    alpha=1,
                    zorder=2,
                    vmin=0,
                    vmax=0.6,
                    marker='h')
    c = plt.scatter(passer_avg.y,
                    passer_avg.x,
                    s=60,
                    c='#FF0000',
                    alpha=1,
                    zorder=3,
                    marker='h')
    pitch.arrows(passes_between.x,
                 passes_between.y,
                 passes_between.x_end,
                 passes_between.y_end,
                 color=color,
                 ax=ax,
                 zorder=1,
                 width=1.5)
    cbar = plt.colorbar(a,
                        orientation="horizontal",
                        shrink=0.3,
                        pad=0,
                        ticks=[0, 0.2, 0.4, 0.6])
    cbar.set_label('Expected Possession Value (EPV)', color='#a9a9a9', size=6)
    cbar.outline.set_edgecolor('#a9a9a9')
    cbar.ax.xaxis.set_tick_params(color='#a9a9a9')
    cbar.ax.xaxis.set_tick_params(labelcolor='#a9a9a9')
    cbar.ax.tick_params(labelsize=5)
    plt.gca().invert_xaxis()

    for index, row in passer_avg.iterrows():
        pitch.annotate(row.name,
                       xy=(row.x, row.y),
                       c='#a9a9a9',
                       va='center',
                       ha='center',
                       size=5,
                       ax=ax)
    plt.text(
        79,
        2,
        "Positions = Median Location of Successful Passes\nArrows = Pass Direction\nTransparency = Frequency of Combination\nMinimum of 3 Passes ",
        color='#a9a9a9',
        fontsize=5,
        alpha=0.5,
        zorder=1)
    plt.text(80, 122, "Minutes 45-90", color='#a9a9a9', fontsize=5)
    plt.text(18, 122, "@nikhilrajesh231", color='#a9a9a9', fontsize=5)
    ax.set_title("Barcelona PV Pass Network\n5-2 vs Getafe (H)",
                 fontsize=8,
                 color="#a9a9a9",
                 fontweight='bold',
                 y=1.01)
    fig = plt.savefig('pn2.png',
                      bbox_inches="tight",
                      facecolor="#000000",
                      dpi=600)
    return fig