【问题标题】:Problem with Friends of Tracking Code NOOB [PYTHON]跟踪代码 NOOB 之友的问题 [PYTHON]
【发布时间】:2020-05-26 19:04:51
【问题描述】:

我正在学习 Python 代码,但遇到了一些问题:

https://github.com/Slothfulwave612/Football-Analytics-Using-Python/blob/master/03.%20Analyzing%20Event%20Data/pass_map.py

我的配音真的很简单:

我想申请一个 for 表达式,以便将密码应用于多场足球比赛。

将 matplotlib.pyplot 导入为 plt 导入json 从 pandas.io.json 导入 json_normalize 从 FCPython 导入 createPitch
pitch_length_X = 120
pitch_width_Y = 80

(fig,ax) = createPitch(pitch_length_X, pitch_width_Y,'yards','gray')

## the code integrated in order to analyze multiple matches
P1TMP = [16205, 16131, 16265]
for i in P1TMP:

  ## match id for our El Clasico
  match_id = int(i)

  home_team = 'Barcelona'
  player_name = 'Lionel Andrés Messi Cuccittini'

  ## this is the name of our event data file for
  ## our required El Clasico
  file_name = str(match_id) + '.json'

  ## loading the required event data file
  my_data = json.load(open('/content/drive/My Drive/20200515 CHIRINGUITO/events/' + file_name, 'r', encoding='utf-8'))

  ## get the nested structure into a dataframe 
  ## store the dataframe in a dictionary with the match id as key
  df = json_normalize(my_data, sep='_').assign(match_id = file_name[:-5])


  ## making the list of all column names
  column = list(df.columns)

  ## all the type names we have in our dataframe
  all_type_name = list(df['type_name'].unique())

  ## creating a data frame for pass
  ## and then removing the null values
  ## only listing the player_name in the dataframe
  pass_df = df.loc[df['type_name'] == 'Pass', :].copy()
  pass_df.dropna(inplace=True, axis=1)
  pass_df = pass_df.loc[pass_df['player_name'] == player_name, :]
  ## creating a data frame for ball receipt
  ## removing all the null values
  ## and only listing Barcelona players in the dataframe
  breceipt_df = df.loc[df['type_name'] == 'Ball Receipt*', :].copy()
  breceipt_df.dropna(inplace=True, axis=1)
  breceipt_df = breceipt_df.loc[breceipt_df['team_name'] == 'Barcelona', :]
  pass_comp, pass_no = 0, 0
  ## pass_comp: completed pass
  ## pass_no: unsuccessful pass



  ## iterating through the pass dataframe
  for row_num, passed in pass_df.iterrows():   
      if passed['player_name'] == player_name:  
        ## for away side
        x_loc = passed['location'][0]
        y_loc = passed['location'][1]

        pass_id = passed['id']
        summed_result = sum(breceipt_df.iloc[:, 14].apply(lambda x: pass_id in x))
        if summed_result > 0:
        ## if pass made was successful
           color = 'blue'
           label = 'Successful'
           pass_comp += 1
        else:
          ## if pass made was unsuccessful
          color = 'green'
          label = 'Unsuccessful'
          pass_no += 1

        ## plotting circle at the player's position
        shot_circle = plt.Circle((pitch_length_X - x_loc, y_loc), radius=2, color=color, label=label)
        shot_circle.set_alpha(alpha=0.2)
        ax.add_patch(shot_circle)

        ## parameters for making the arrow
        pass_x = 120 - passed['pass_end_location'][0]
        pass_y = passed['pass_end_location'][1] 
        dx = ((pitch_length_X - x_loc) - pass_x)
        dy = y_loc - pass_y

        ## making an arrow to display the pass
        pass_arrow = plt.Arrow(pitch_length_X - x_loc, y_loc, -dx, -dy, width=1, color=color)

        ## adding arrow to the plot
        ax.add_patch(pass_arrow)

## 计算通过准确率 pass_acc = (pass_comp / (pass_comp + pass_no)) * 100 pass_acc = str(round(pass_acc, 2)) ## 在绘图中添加文本 plt.text(20, 85, '{} 传球图 vs 皇马'.format(player_name), fontsize=15) plt.text(20, 82, '通过准确度: {}'.format(pass_acc), fontsize=15) ## 处理标签 句柄,标签 = plt.gca().get_legend_handles_labels() by_label = dict(zip(标签,句柄)) plt.legend(by_label.values(), by_label.keys(), loc='best', bbox_to_anchor=(0.9, 1, 0, 0),fontsize=12) ## 编辑图形大小并保存 fig.set_size_inches(12, 8) fig.savefig('{} passmap.png'.format(match_id), dpi=200) ## 显示情节 plt.show()

我只是编辑了代码,以便使用 for 表达式分析多个匹配项。

P1TMP = [16205, 16131, 16265] 在 P1TMP 中为 i:

结果:

在第一张图片中,结果几乎是完美的,但是通过类型的过滤器不起作用。

enter image description here

在第二张图片中,传球是第一场比赛和第二场比赛的传球的混合。我只想要第二场比赛的传球。

enter image description here

第三个是 nº1 +nº2 + n3º 的混合。我需要第三个的通行证: enter image description here

提前感谢您的支持。

最好的问候

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    所以它将所有匹配项合并到 1 上,因为该图形是在前一个图形之上“绘制”的。您还需要更改其他一些内容。

    1. 客队并不总是皇马,所以要保持活力
    2. 调整图形文本中的文本,使其不总是“vs. Real Madrid"
    3. 将文件另存为动态文件,以免被覆盖
    4. 使用plt.title()plt.suptitle(),而不是使用plt.text 来添加标题(如果您想在特定的x,y 坐标处进行注释,这很好)。它将居中并使其成为更好的文本布局
    5. 您使用 i,因为您在迭代时匹配 id 变量,但您不会在循环中更改/包含它
    6. 这是主要问题:(fig,ax) = createPitch(pitch_length_X, pitch_width_Y,'yards','gray') 是创建“空白画布”以进行绘图的原因。所以这需要在每个情节之前调用。这就像抓一张新的白纸在上面画画。如果您只使用第一张初始工作表,那么所有内容都将在该一张工作表上进行。所以把它移到你的 for 循环中

    代码

    import matplotlib.pyplot as plt
    import json
    from pandas.io.json import json_normalize
    from FCPython import createPitch
    
    ## Note Statsbomb data uses yards for their pitch dimensions
    pitch_length_X = 120
    pitch_width_Y = 80
    
    
    
    ## match id for our El Clasico
    match_list = [16205, 16131, 16265]
    teamA = 'Barcelona'  #<--- adjusted here
    
    for match_id in match_list:
        ## calling the function to create a pitch map
        ## yards is the unit for measurement and
        ## gray will be the line color of the pitch map
        (fig,ax) = createPitch(pitch_length_X, pitch_width_Y,'yards','gray') #< moved into for loop
    
        player_name = 'Lionel Andrés Messi Cuccittini'
    
        ## this is the name of our event data file for
        ## our required El Clasico
        file_name = str(match_id) + '.json'
    
        ## loading the required event data file
        my_data = json.load(open('Statsbomb/data/events/' + file_name, 'r', encoding='utf-8'))
    
    
        ## get the nested structure into a dataframe 
        ## store the dataframe in a dictionary with the match id as key
        df = json_normalize(my_data, sep='_').assign(match_id = file_name[:-5])
        teamB = [x for x in list(df['team_name'].unique()) if x != teamA ][0] #<--- get other team name
    
        ## making the list of all column names
        column = list(df.columns)
    
        ## all the type names we have in our dataframe
        all_type_name = list(df['type_name'].unique())
    
        ## creating a data frame for pass
        ## and then removing the null values
        ## only listing the player_name in the dataframe
        pass_df = df.loc[df['type_name'] == 'Pass', :].copy()
        pass_df.dropna(inplace=True, axis=1)
        pass_df = pass_df.loc[pass_df['player_name'] == player_name, :]
    
        ## creating a data frame for ball receipt
        ## removing all the null values
        ## and only listing Barcelona players in the dataframe
        breceipt_df = df.loc[df['type_name'] == 'Ball Receipt*', :].copy()
        breceipt_df.dropna(inplace=True, axis=1)
        breceipt_df = breceipt_df.loc[breceipt_df['team_name'] == 'Barcelona', :]
    
        pass_comp, pass_no = 0, 0
        ## pass_comp: completed pass
        ## pass_no: unsuccessful pass
    
        ## iterating through the pass dataframe
        for row_num, passed in pass_df.iterrows():   
    
            if passed['player_name'] == player_name:
                ## for away side
                x_loc = passed['location'][0]
                y_loc = passed['location'][1]
    
                pass_id = passed['id']
                summed_result = sum(breceipt_df.iloc[:, 14].apply(lambda x: pass_id in x))
    
                if summed_result > 0:
                    ## if pass made was successful
                    color = 'blue'
                    label = 'Successful'
                    pass_comp += 1
                else:
                    ## if pass made was unsuccessful
                    color = 'red'
                    label = 'Unsuccessful'
                    pass_no += 1
    
                ## plotting circle at the player's position
                shot_circle = plt.Circle((pitch_length_X - x_loc, y_loc), radius=2, color=color, label=label)
                shot_circle.set_alpha(alpha=0.2)
                ax.add_patch(shot_circle)
    
                ## parameters for making the arrow
                pass_x = 120 - passed['pass_end_location'][0]
                pass_y = passed['pass_end_location'][1] 
                dx = ((pitch_length_X - x_loc) - pass_x)
                dy = y_loc - pass_y
    
                ## making an arrow to display the pass
                pass_arrow = plt.Arrow(pitch_length_X - x_loc, y_loc, -dx, -dy, width=1, color=color)
    
                ## adding arrow to the plot
                ax.add_patch(pass_arrow)
    
        ## computing pass accuracy
        pass_acc = (pass_comp / (pass_comp + pass_no)) * 100
        pass_acc = str(round(pass_acc, 2))
    
        ## adding text to the plot
        plt.suptitle('{} pass map vs {}'.format(player_name, teamB), fontsize=15) #<-- make dynamic and change to suptitle
        plt.title('Pass Accuracy: {}'.format(pass_acc), fontsize=15) #<-- change to title
    
        ## handling labels
        handles, labels = plt.gca().get_legend_handles_labels()
        by_label = dict(zip(labels, handles))
        plt.legend(by_label.values(), by_label.keys(), loc='best', bbox_to_anchor=(0.9, 1, 0, 0), fontsize=12)
    
        ## editing the figure size and saving it
        fig.set_size_inches(12, 8)
        fig.savefig('{} passmap.png'.format(match_id), dpi=200)  #<-- dynamic file name
    
        ## showing the plot
        plt.show()
    

    【讨论】:

    • 不能给你积分,因为我是0级。但我真的很感谢你的支持。我在这里有另一个问题: summed_result = sum(breceipt_df.iloc[:, 14].apply(lambda x: pass_id in x)) 在代码中它不起作用,至少在协作中。
    • 您好,非常感谢您的努力和帮助。请在附上投票的问题:感谢您的反馈!声望低于 15 人的投票将被记录,但不会更改公开显示的帖子得分。如果我改进了,我会回来投票给你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 2016-11-07
    • 1970-01-01
    • 2012-03-29
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多