{"cells":[{"metadata":{"trusted":true,"_uuid":"834bb5fef407ff177804f5e617a40e705df1f3ad"},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport matplotlib.cm as cm\nimport matplotlib.animation as animation\nfrom shapely.geometry import LineString\n\nvideo_review = pd.read_csv('..//input//video_review.csv')\n\nfor col in ['Player_Activity_Derived', 'Turnover_Related', 'Primary_Impact_Type', 'Primary_Partner_Activity_Derived', 'Friendly_Fire']:\n    video_review[col]=video_review[col].astype('category')\n\nvideo_review['Primary_Partner_GSISID'] = pd.to_numeric(video_review['Primary_Partner_GSISID'],\n                                                       errors = 'coerce', \n                                                       downcast='integer')\n    \n#video_review.describe(include='all')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b12e63027780815230e771683655d218cd686480"},"cell_type":"code","source":"def label_ngs (row):\n    year = str(row['Season_Year'])\n    stype = row['Season_Type']\n    week = row['Week']\n    if stype != 'Reg':\n        return '-'.join(['NGS', year, stype.lower()])\n    elif week < 7 :\n        return '-'.join(['NGS', year, stype.lower(),'wk1-6'])\n    elif week < 13 :\n        return '-'.join(['NGS', year, stype.lower(),'wk7-12'])\n    else:\n        return '-'.join(['NGS', year, stype.lower(),'wk13-17'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1a55ff89eb562d881fae5654527f6d7ae1a50286"},"cell_type":"code","source":"game_data = pd.read_csv('..//input//game_data.csv')\nreview_game_data = pd.merge(video_review[['GameKey']],game_data, on='GameKey')\nreview_game_data['NGS_File'] = review_game_data.apply(label_ngs, axis=1)\n\nngs_file_list = list(review_game_data['NGS_File'].unique())\n#review_game_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"729ddff0ddce5e32f71f4275d06cd8451b71b846"},"cell_type":"code","source":"play_information = pd.read_csv('..//input//play_information.csv')\nvideo_footage_control = pd.read_csv('..//input//video_footage-control.csv')\nvideo_footage_injury = pd.read_csv('..//input//video_footage-injury.csv')\nplay_player_role = pd.read_csv('..//input//play_player_role_data.csv')\nplayer_punt_data = pd.read_csv('..//input//player_punt_data.csv')\n\nplayer_punt_data = player_punt_data.groupby('GSISID').agg({'Number':lambda x: list(x), 'Position': 'last'})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"df9f0d71b4eb60de45417b2bb02a4df17639840d"},"cell_type":"code","source":"#PPL in punt coverage?\npunt_coverage = ['GL','PLW','PLT','PLG','PLS','PRG','PRT','PRW','PC','PPR','P','GR','GRo','GRi','GLo','GLi','PPRo',\n                 'PPRi','PPL', 'PPLi', 'PPLo']\n#PDM in punt return?\npunt_return = ['VL','PDL1','PDL2','PDL3','PDR3','PDR2','PDR1','VR','VR','PLL','PLM','PLR','PFB','PR','PLM1','PDR4',\n               'PDR5','PDR6','VRi','VRo','VLo','VLi','PDL4','PDL5','PDL6','PLR1','PLR2','PLR3','PLL3','PLL2','PLL1','PDM']\n\nplay_player_role['Role'].unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e96bab0b53cd93e4d670d9b40c4f654dfde2e95"},"cell_type":"code","source":"GameKey_list = list(video_review['GameKey'].unique())\nPlayID_list = list(video_review['PlayID'].unique())\nplay_player_role_final = play_player_role[(play_player_role['GameKey'].isin(GameKey_list)) & \n                                          (play_player_role['PlayID'].isin(PlayID_list))].copy()\n#Designate based on which side of play each player is on, 'Punt' or 'Return' Team\ndef action_me(row):\n    if row.Role in punt_coverage:\n        return 'Punt'\n    elif row.Role in punt_return:\n        return 'Return'\n    else:\n        return 'np.nan'\n\nplay_player_role_final.loc[:,'Team_Action'] = play_player_role_final.apply(action_me, axis=1)\ntemp_players = list(video_review['GSISID'].unique())\ninjured_players = pd.merge(pd.merge(play_player_role_final, video_review, on = ['Season_Year','GameKey','PlayID','GSISID']),\n                           player_punt_data, on = 'GSISID')\n\naction_count = injured_players.groupby('Team_Action').count().sort_values('Season_Year', ascending=False).iloc[:,0]\nactivity_count = injured_players.groupby('Player_Activity_Derived').count().sort_values('Season_Year', ascending=False).iloc[:,0]\nrole_count = injured_players.groupby('Role').count().sort_values('Season_Year', ascending=False).iloc[:,0]\nimpact_count = injured_players.groupby('Primary_Impact_Type').count().sort_values('Season_Year', ascending=False).iloc[:,0]\nposition_count = injured_players.groupby('Position').count().sort_values('Season_Year', ascending=False).iloc[:,0]\nposition_count2 = injured_players.groupby(['Role','Position']).count().iloc[:,0].unstack()\n\nfig, axes = plt.subplots(3, 2, figsize = (14,10))\nfig.tight_layout()\n\naction_count.plot.bar(rot=0,ax = axes[0][0])\nactivity_count.plot.bar(rot=0,ax = axes[0][1])\nrole_count.plot.bar(rot=90,ax = axes[1][0])\nimpact_count.plot.bar(rot=0,ax = axes[1][1])\nposition_count.plot.bar(rot=0,ax = axes[2][0])\n\naxes[2][1].imshow(position_count2.transpose().values, cmap=cm.gray)\n\nplt.setp(axes[2][1], xticklabels=position_count2.index.tolist(),\n         yticklabels=position_count2.columns.tolist(),\n         xticks=list(range(position_count2.shape[0])), \n         yticks=list(range(position_count2.shape[1])))\nplt.setp(axes[2][1].get_xticklabels(), rotation=90)\n\nplt.subplots_adjust(hspace=0.3)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e784cf807c39ada0e6d5e9251699571437a3ded6"},"cell_type":"code","source":"action_activity_count = injured_players.groupby(['Team_Action','Player_Activity_Derived'], sort=False).count().iloc[:,0].unstack()\naction_impact_count = injured_players.groupby(['Team_Action','Primary_Impact_Type'], sort=False).count().iloc[:,0].unstack()\nactivity_impact_count = injured_players.groupby(['Player_Activity_Derived','Primary_Impact_Type'], sort=False).count().iloc[:,0].unstack()\nrole_impact_count = injured_players.groupby(['Role','Primary_Impact_Type'], sort=True).count().iloc[:,0].unstack()\nrole_action_count = injured_players.groupby(['Role','Team_Action'], sort=True).count().iloc[:,0].unstack()\nrole_activity_count = injured_players.groupby(['Role','Player_Activity_Derived'], sort=True).count().iloc[:,0].unstack()\n\nfig2, axes2 = plt.subplots(3, 2, figsize = (12,8))\nfig2.tight_layout()\nplt.subplots_adjust(wspace=0.5, hspace=0.3)\n\naction_activity_count.plot.bar(rot=0,ax = axes2[0][0], stacked=True)\naction_impact_count.plot.bar(rot=0,ax = axes2[0][1], stacked=True)\nactivity_impact_count.plot.bar(rot=0,ax = axes2[1][0], stacked=True)\nrole_action_count.plot.bar(rot=0,ax = axes2[1][1], stacked=True)\nrole_impact_count.plot.bar(rot=0,ax = axes2[2][1], stacked=True)\nrole_activity_count.plot.bar(rot=0,ax = axes2[2][0], stacked=True)\n\nplt.setp(axes2[2][1].get_xticklabels(), rotation=90)\nplt.setp(axes2[1][1].get_xticklabels(), rotation=90)\nplt.setp(axes2[2][0].get_xticklabels(), rotation=90)\naxes2[0][0].legend(loc='center left',bbox_to_anchor=(1, 0.5))\naxes2[0][1].legend(loc='center left',bbox_to_anchor=(1, 0.5))\naxes2[1][0].legend(loc='center left',bbox_to_anchor=(1, 0.5))\naxes2[1][1].legend(loc='center left',bbox_to_anchor=(1, 0.5))\naxes2[2][0].legend(loc='center left',bbox_to_anchor=(1, 0.5))\naxes2[2][1].legend(loc='center left',bbox_to_anchor=(1, 0.5))\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e6ff1f819cbb5b6035c35acef922ad1e842e8fe"},"cell_type":"code","source":"ngs_file = {}\ndef dataprep(game_info=None, filename=None):\n    myGameKey, myPlayID, GSISID1, GSISID2 = game_info\n    if (filename not in ngs_file.keys()): \n        ngs_file[filename] =  pd.read_csv('..//input//' + filename + '.csv')\n        ngs_file[filename].loc[:,'Speed'] = ngs_file[filename]['dis']/0.1 *3600/1760\n\n    ngs_file[filename]['Time'] = pd.to_datetime(ngs_file[filename]['Time'])\n    temp_pd = ngs_file[filename].sort_values('Time').copy()\n    temp_pd = temp_pd[(temp_pd.GameKey == myGameKey) & (temp_pd.PlayID == myPlayID)]\n    if pd.isnull(GSISID2):\n        other_player_df = temp_pd[~(temp_pd.GSISID == GSISID1)].copy()\n    else:\n        other_player_df = temp_pd[~((temp_pd.GSISID == GSISID1) | (temp_pd.GSISID == GSISID2))].copy()\n\n    #speed should be the distance(will be in yards) divided by time (which is 0.1 sec intervals) corrected to MPH\n    p1_speed = temp_pd[temp_pd.GSISID == GSISID1]\n#    Alternative method to calculate speed\n#    p1_speed[['time_diff','x_diff', 'y_diff']] = p1_speed[['Time','x','y']].diff().fillna(0.)\n#    p1_speed['Speed']= np.sqrt(p1_speed.x_diff**2+ p1_speed.y_diff**2)/0.1 *3600/1760\n#    p1_speed = p1_speed.drop(['time_diff','x_diff', 'y_diff'], 1)\n    \n    #if GSISID is \"Unclear\" i.e. player fell on his own\n    if pd.isnull(GSISID2):\n        p1_speed.rename(columns={'x': 'x1', 'y': 'y1', 'Speed': 'Speed1'}, inplace=True)\n        return p1_speed, other_player_df\n    \n    p2_speed = temp_pd[temp_pd.GSISID == GSISID2]\n#    p2_speed[['time_diff','x_diff', 'y_diff']] = p2_speed[['Time','x','y']].diff().fillna(0.)\n#    p2_speed['Speed']= np.sqrt(p2_speed.x_diff**2 + p2_speed.y_diff**2)/0.1 *3600/17603\n#    p2_speed = p2_speed.drop(['time_diff','x_diff', 'y_diff'], axis=1)\n\n    relev_cols = ['Time','GSISID', 'x', 'y', 'dis','o', 'dir', 'Speed']\n    player_speed = pd.merge(p1_speed, p2_speed.loc[:,relev_cols], on='Time', validate='one_to_one',suffixes = ['1','2'])\n    return player_speed, other_player_df\n\ndef speed_plots(vr_row=None, gd_row=None, filename=None):\n    #%matplotlib notebook\n    \n    if vr_row is None:\n        print(\"Provide a pandas row from video_review.csv dataframe\")\n        return None\n    if gd_row is None:\n        print(\"Provide a pandas row from game_data.csv dataframe\")\n        return None\n    if filename is None:\n        print('Specify a Filename to save final mp4')\n        return None    \n    \n    tempGameKey, tempPlayID, tempGSISID1, tempGSISID2 =list(vr_row[['GameKey', 'PlayID', 'GSISID', 'Primary_Partner_GSISID']])\n    player1_team = play_player_role_final[((play_player_role_final.GameKey == tempGameKey) & \n                                           (play_player_role_final.PlayID == tempPlayID) & \n                                           (play_player_role_final.GSISID == tempGSISID1))].iloc[-1,-1]\n    player2_team = play_player_role_final[((play_player_role_final.GameKey == tempGameKey) & \n                                           (play_player_role_final.PlayID == tempPlayID) & \n                                           (play_player_role_final.GSISID == tempGSISID2))].iloc[-1,-1] if not pd.isnull(tempGSISID2) else ''\n    \n    player_speed_final, other_players_final = dataprep([tempGameKey, tempPlayID, tempGSISID1, tempGSISID2],gd_row[-1])\n    \n    text_col = ['HomeTeamCode','VisitTeamCode','Season_Year','Season_Type','StadiumType','Turf','GameWeather','Temperature']\n    game_text = review_game_data[review_game_data.GameKey == vr_row['GameKey']][text_col].iloc[0].tolist()\n    \n    \n    fig, (ax1,ax2) = plt.subplots(2, 1, figsize=(14,8))\n    ax1.set_xlabel('Time',fontsize=10)\n    ax1.set_ylabel('Speed (MPH)',fontsize=10)\n    ax1.set_title('Players\\' Speed',fontsize=20, y=1.1)\n    ax1.set_xlim(np.min(player_speed_final['Time']), np.max(player_speed_final['Time'] + np.timedelta64(2, 's')))\n    ax1.set_ylim(0,40)\n    \n    ax3 = ax1.twinx()  # instantiate a second axes that shares the same x-axis\n    ax3.set_ylabel('Combine Speed', color='red')  # we already handled the x-label with ax1\n    ax3.tick_params(axis='y', labelcolor='red')\n    ax3.set_ylim(0,55)\n    ax3.set_xlim(np.min(player_speed_final['Time']), np.max(player_speed_final['Time'] + np.timedelta64(2, 's')))\n\n    \n    ax2.grid(which='major', axis='x', linestyle='--')\n    ax2.set_xlim(0, 120)\n    ax2.set_ylim(0,53.3)\n    ax2.set_title('Players\\' Route - '+ vr_row['Primary_Impact_Type'],fontsize=20)\n    ax2.set_xlabel(' - '.join([' vs. '.join(game_text[:2])]+\n                              [str(x) for x in game_text[2:-1]] +\n                              [str(game_text[-1])+' Degree F']),fontsize=10)\n    plt.setp(ax2, xticks=range(10,120,10), xticklabels=['Goal', 10, 20, 30, 40, 50, 40, 30, 20, 10, 'Goal'],yticks=[])\n\n    sc1 = ax2.scatter([], [], c = 'g', marker = 'o')\n    sc2 = ax2.scatter([], [], c = 'm', marker = 'x')\n    \n    plt.subplots_adjust(hspace=0.3)\n    \n    def animate(i):\n        new_df = player_speed_final.iloc[:int(i+1)]\n        game_time = new_df.Time.iloc[-1]\n        test = (player_speed_final.shape[1] > 12)\n        graphs = []\n        temp = ax1.plot(new_df['Time'], new_df['Speed1'], color = 'blue')\n        graphs.append(temp[0])\n        if test:\n            temp = ax1.plot(new_df['Time'], new_df['Speed2'], color = 'orange')\n            temp2 = ax3.plot(new_df['Time'],(new_df['Speed1'] + new_df['Speed2']), color = 'red')\n            graphs = graphs + [temp[0], temp2[0]]\n        ax2.plot(new_df['x1'], new_df['y1'], color = 'blue')\n        if test:\n            ax2.plot(new_df['x2'], new_df['y2'], color = 'orange')\n        event = new_df.Event.iloc[-1]\n        if not(pd.isnull(event)):\n            ax1.annotate(event, xy=(new_df.Time.iloc[-1], new_df.Speed1.iloc[-1]),\n                   xycoords='data', xytext=(0, 70), textcoords='offset points',\n                   arrowprops=dict(arrowstyle=\"->\"))\n        \n        legend_text = ['Player1 - '+ vr_row['Player_Activity_Derived'] + ' - ' + player1_team]\n        if test:\n            legend_text = legend_text + [('Player2 - '+ vr_row['Primary_Partner_Activity_Derived'] + ' - ' + player2_team), \n                                         'Combined Speed']\n            \n        plt.legend([sc1, sc2] + graphs, ['Punting Team', 'Return Team'] + legend_text, \n                   loc='lower center', bbox_to_anchor=(0.5, 0.98), fancybox=True, ncol=len(legend_text)+2)\n        \n        #position of other players\n        other_player_pos = other_players_final[other_players_final.Time == game_time]\n        other_player_pos = pd.merge(play_player_role_final, other_player_pos, on = ['Season_Year','GameKey','PlayID','GSISID'])\n        \n        new_array1 = other_player_pos.loc[other_player_pos['Team_Action'] == 'Punt'].loc[:,['x','y']].as_matrix()\n        new_array2 = other_player_pos.loc[other_player_pos['Team_Action'] == 'Return'].loc[:,['x','y']].as_matrix()\n        n = other_player_pos['GSISID'].tolist()\n        \n        sc1.set_offsets(new_array1)\n        sc2.set_offsets(new_array2)\n        return([sc1, sc2] + graphs)\n        \n    ani = animation.FuncAnimation(fig, animate, frames=len(player_speed_final), repeat=True, interval=1, blit=True)\n    ani.save((filename + '.gif'), writer='imagemagick', fps=10)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e361013b7a7ddb454bcbac380644afe84456596c"},"cell_type":"code","source":"for x in range(len(review_game_data)):\n    speed_plots(video_review.iloc[x,:],review_game_data.iloc[x,:],'Play'+str(x))\n    print('Plot ' + str(x) + ' done')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}