{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<h1><center>NFL Big Data Bowl Basic EDA for beginner</center></h1>\n\n<center><img src=\"https://deadline.com/wp-content/uploads/2021/01/NFL-ball.jpg?crop=0px%2C33px%2C1226px%2C687px&resize=681%2C383\"></center>","metadata":{}},{"cell_type":"markdown","source":"### This is very simple EDA notebook. I have lots of things to analyze so that I'll keep updating.","metadata":{}},{"cell_type":"markdown","source":"# Upvote is Free 🤗\n### PLEASE UPVOTE if you like this notebook. It will keep me motivated to update my notebook.","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\n\nplt.style.use('fivethirtyeight')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"_kg_hide-output":false,"execution":{"iopub.status.busy":"2021-10-09T15:34:42.172776Z","iopub.execute_input":"2021-10-09T15:34:42.173140Z","iopub.status.idle":"2021-10-09T15:34:43.063755Z","shell.execute_reply.started":"2021-10-09T15:34:42.173110Z","shell.execute_reply":"2021-10-09T15:34:43.062606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n<h2 style='background:transparent; color:black'><center>1. Game Data<center><h2>","metadata":{}},{"cell_type":"markdown","source":"### **Game data:** The games.csv contains the teams playing in each game. The key variable is gameId.\n\n* **gameId:** Game identifier, unique (numeric)\n\n* **gameDate:** Game Date (time, mm/dd/yyyy)\n\n* **gameTimeEastern:** Start time of game (time, HH:MM:SS, EST)\n\n* **homeTeamAbbr:** Home team three-letter code (text)\n\n* **visitorTeamAbbr:** Visiting team three-letter code (text)\n\n* **week:** Week of game (numeric)","metadata":{}},{"cell_type":"code","source":"games = pd.read_csv('../input/nfl-big-data-bowl-2022/games.csv')\ngames","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2021-10-09T15:34:43.065960Z","iopub.execute_input":"2021-10-09T15:34:43.066372Z","iopub.status.idle":"2021-10-09T15:34:43.116050Z","shell.execute_reply.started":"2021-10-09T15:34:43.066329Z","shell.execute_reply":"2021-10-09T15:34:43.114951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Function for Downcast","metadata":{}},{"cell_type":"markdown","source":"Downcast is a great skill to compress data size which helps to save memory.","metadata":{}},{"cell_type":"code","source":"def downcast(df, verbose=True):\n    start_mem = df.memory_usage().sum() / 1024**2\n    for col in df.columns:\n        dtype_name = df[col].dtype.name\n        if dtype_name == 'object':\n            pass\n        elif dtype_name == 'bool':\n            df[col] = df[col].astype('int8')\n        elif dtype_name.startswith('int') or (df[col].round() == df[col]).all():\n            df[col] = pd.to_numeric(df[col], downcast='integer')\n        else:\n            df[col] = pd.to_numeric(df[col], downcast='float')\n    end_mem = df.memory_usage().sum() / 1024**2\n    if verbose:\n        print('{:.1f}% Compressed'.format(100 * (start_mem - end_mem) / start_mem))\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.118067Z","iopub.execute_input":"2021-10-09T15:34:43.118405Z","iopub.status.idle":"2021-10-09T15:34:43.130361Z","shell.execute_reply.started":"2021-10-09T15:34:43.118374Z","shell.execute_reply":"2021-10-09T15:34:43.129408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"games = downcast(games)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.131569Z","iopub.execute_input":"2021-10-09T15:34:43.131869Z","iopub.status.idle":"2021-10-09T15:34:43.150877Z","shell.execute_reply.started":"2021-10-09T15:34:43.131840Z","shell.execute_reply":"2021-10-09T15:34:43.149549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Function for making feature summary ","metadata":{}},{"cell_type":"code","source":"def resumetable(df):\n    print(f'Shape : {df.shape}')\n    summary = pd.DataFrame(df.dtypes, columns=['Data Type'])\n    summary = summary.reset_index()\n    summary = summary.rename(columns={'index': 'Feature'})\n    summary['Num of null'] = df.isnull().sum().values\n    summary['Num of unique'] = df.nunique().values\n    summary['First value'] = df.loc[0].values\n    summary['Second value'] = df.loc[1].values\n    summary['Third value'] = df.loc[2].values\n    return summary\n\nresumetable(games)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.154880Z","iopub.execute_input":"2021-10-09T15:34:43.155160Z","iopub.status.idle":"2021-10-09T15:34:43.190088Z","shell.execute_reply.started":"2021-10-09T15:34:43.155134Z","shell.execute_reply":"2021-10-09T15:34:43.189313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Function for writing percent at the top of the bar graph","metadata":{}},{"cell_type":"code","source":"def write_percent(ax, total_size):\n    '''Traverse the figure object and display the ratio at the top of the bar graph.'''\n    for patch in ax.patches:\n        height = patch.get_height() # Figure height (number of data)\n        width = patch.get_width() # Figure width\n        left_coord = patch.get_x() # The x-axis position on the left edge of the figure\n        percent = height/total_size*100 # percent\n        \n        # Type text in the (x, y) coordinates\n        ax.text(x=left_coord + width/2.0, # x-axis position\n                y=height + total_size*0.001, # y-axis position\n                s=f'{percent:1.1f}%', # Text\n                ha='center') # in the middle","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.192637Z","iopub.execute_input":"2021-10-09T15:34:43.192958Z","iopub.status.idle":"2021-10-09T15:34:43.200451Z","shell.execute_reply.started":"2021-10-09T15:34:43.192931Z","shell.execute_reply":"2021-10-09T15:34:43.199671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Make derivative features (month, day, hour)","metadata":{}},{"cell_type":"code","source":"games['month'] = games['gameDate'].apply(lambda x: int(x.split('/')[0]))\ngames['day'] = games['gameDate'].apply(lambda x: int(x.split('/')[1]))\ngames['hour'] = games['gameTimeEastern'].apply(lambda x: int(x.split(':')[0]))","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.201352Z","iopub.execute_input":"2021-10-09T15:34:43.201636Z","iopub.status.idle":"2021-10-09T15:34:43.220968Z","shell.execute_reply.started":"2021-10-09T15:34:43.201594Z","shell.execute_reply":"2021-10-09T15:34:43.219935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Visualization","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=15) # Set font size\nplt.figure(figsize=(7, 6)) # Set figure size\n\nax = sns.countplot(x='season', data=games)\nwrite_percent(ax, len(games)) \nax.set_title('Number of games for season');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.222927Z","iopub.execute_input":"2021-10-09T15:34:43.223424Z","iopub.status.idle":"2021-10-09T15:34:43.396207Z","shell.execute_reply.started":"2021-10-09T15:34:43.223375Z","shell.execute_reply":"2021-10-09T15:34:43.395398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### As the years go by, the number of games increases","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=15)\nplt.figure(figsize=(8, 6))\n\nax = sns.countplot(x='month', data=games)\nwrite_percent(ax, len(games))\nax.set_title('Number of games for month');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.397761Z","iopub.execute_input":"2021-10-09T15:34:43.398435Z","iopub.status.idle":"2021-10-09T15:34:43.538473Z","shell.execute_reply.started":"2021-10-09T15:34:43.398390Z","shell.execute_reply":"2021-10-09T15:34:43.537756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The game was held from September to January. There are especially many games in December, and they are rarely held in January","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(15, 7))\n\nax = sns.countplot(x='day', data=games)\nwrite_percent(ax, len(games))\nax.set_title('Number of games for day');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.539753Z","iopub.execute_input":"2021-10-09T15:34:43.540212Z","iopub.status.idle":"2021-10-09T15:34:43.935980Z","shell.execute_reply.started":"2021-10-09T15:34:43.540181Z","shell.execute_reply":"2021-10-09T15:34:43.935225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(15, 7))\n\nax = sns.countplot(x='gameTimeEastern', data=games)\nwrite_percent(ax, len(games))\nax.set_title('Number of games for gameTimeEastern');\nax.tick_params('x', labelrotation=30) # rotate 30 degree of x label","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:43.937339Z","iopub.execute_input":"2021-10-09T15:34:43.937659Z","iopub.status.idle":"2021-10-09T15:34:44.202099Z","shell.execute_reply.started":"2021-10-09T15:34:43.937604Z","shell.execute_reply":"2021-10-09T15:34:44.200971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(15, 7))\n\nax = sns.countplot(x='hour', data=games)\nwrite_percent(ax, len(games))\nax.set_title('Number of games for hour');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.203440Z","iopub.execute_input":"2021-10-09T15:34:44.203758Z","iopub.status.idle":"2021-10-09T15:34:44.516527Z","shell.execute_reply.started":"2021-10-09T15:34:44.203728Z","shell.execute_reply":"2021-10-09T15:34:44.515542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The most games were held at 1, 4, and 8","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(15, 7))\n\nax = sns.countplot(x='week', data=games)\nwrite_percent(ax, len(games))\nax.set_title('Number of games for week');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.517981Z","iopub.execute_input":"2021-10-09T15:34:44.518535Z","iopub.status.idle":"2021-10-09T15:34:44.801789Z","shell.execute_reply.started":"2021-10-09T15:34:44.518493Z","shell.execute_reply":"2021-10-09T15:34:44.801013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"2\"></a>\n<h2 style='background:transparent; border:0; color:black'><center>2. Player Data<center><h2>","metadata":{}},{"cell_type":"markdown","source":"### **Player data:** The players.csv file contains player-level information from players that participated in any of the tracking data files. The key variable is nflId\n\n* **nflId:** Player identification number, unique across players (numeric)\n\n* **height:** Player height (text)\n\n* **weight:** Player weight (numeric)\n\n* **birthDate:** Date of birth (YYYY-MM-DD)\n\n* **collegeName:** Player college (text)\n\n* **position:** Player position (text)\n\n* **displayName:** Player name (text)","metadata":{}},{"cell_type":"code","source":"players = pd.read_csv('../input/nfl-big-data-bowl-2022/players.csv')\nplayers","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.802778Z","iopub.execute_input":"2021-10-09T15:34:44.803136Z","iopub.status.idle":"2021-10-09T15:34:44.856540Z","shell.execute_reply.started":"2021-10-09T15:34:44.803109Z","shell.execute_reply":"2021-10-09T15:34:44.855808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players = downcast(players)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.857567Z","iopub.execute_input":"2021-10-09T15:34:44.857991Z","iopub.status.idle":"2021-10-09T15:34:44.866631Z","shell.execute_reply.started":"2021-10-09T15:34:44.857960Z","shell.execute_reply":"2021-10-09T15:34:44.865934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(players)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.867592Z","iopub.execute_input":"2021-10-09T15:34:44.868026Z","iopub.status.idle":"2021-10-09T15:34:44.897667Z","shell.execute_reply.started":"2021-10-09T15:34:44.867997Z","shell.execute_reply":"2021-10-09T15:34:44.896706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Convert all heights to feet","metadata":{}},{"cell_type":"code","source":"check = players['height'].str.split('-', expand=True)\n\ncheck.columns = ['first', 'second']\n\ncheck.loc[(check['second'].notnull()), 'first'] = check[check['second'].notnull()]['first'].astype(np.int16) * 12 + check[check['second'].notnull()]['second'].astype(np.int16)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.899169Z","iopub.execute_input":"2021-10-09T15:34:44.899757Z","iopub.status.idle":"2021-10-09T15:34:44.940877Z","shell.execute_reply.started":"2021-10-09T15:34:44.899711Z","shell.execute_reply":"2021-10-09T15:34:44.939825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players['height'] = check['first']\nplayers['height'] = players['height'].astype(np.float32)\nplayers['height'] /= 12\n\nplayers","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.942172Z","iopub.execute_input":"2021-10-09T15:34:44.942477Z","iopub.status.idle":"2021-10-09T15:34:44.963759Z","shell.execute_reply.started":"2021-10-09T15:34:44.942448Z","shell.execute_reply":"2021-10-09T15:34:44.962989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 6))\n\nax = sns.distplot(players['height'], bins=12)\nax.set_title('Height Distribution');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:44.964809Z","iopub.execute_input":"2021-10-09T15:34:44.965409Z","iopub.status.idle":"2021-10-09T15:34:45.157097Z","shell.execute_reply.started":"2021-10-09T15:34:44.965377Z","shell.execute_reply":"2021-10-09T15:34:45.156192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 6))\n\nax = sns.distplot(players['weight'])\nax.set_title('Weight Distribution');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.158215Z","iopub.execute_input":"2021-10-09T15:34:45.158670Z","iopub.status.idle":"2021-10-09T15:34:45.356360Z","shell.execute_reply.started":"2021-10-09T15:34:45.158609Z","shell.execute_reply":"2021-10-09T15:34:45.355453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"top_players_colleage = players['collegeName'].value_counts()[:20].reset_index()\ntop_players_colleage.columns = ['collageName', 'numberOfPlayers']","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.357919Z","iopub.execute_input":"2021-10-09T15:34:45.358200Z","iopub.status.idle":"2021-10-09T15:34:45.366646Z","shell.execute_reply.started":"2021-10-09T15:34:45.358172Z","shell.execute_reply":"2021-10-09T15:34:45.365855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=10) \nplt.figure(figsize=(15, 12))\n\nax = sns.barplot(x='numberOfPlayers', y='collageName', data=top_players_colleage)\nax.set_title('Number of players for collegeName');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.367650Z","iopub.execute_input":"2021-10-09T15:34:45.368018Z","iopub.status.idle":"2021-10-09T15:34:45.682952Z","shell.execute_reply.started":"2021-10-09T15:34:45.367991Z","shell.execute_reply":"2021-10-09T15:34:45.682143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create birth year feature","metadata":{}},{"cell_type":"code","source":"players['birthYear'] = 0","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.683998Z","iopub.execute_input":"2021-10-09T15:34:45.684405Z","iopub.status.idle":"2021-10-09T15:34:45.689149Z","shell.execute_reply.started":"2021-10-09T15:34:45.684377Z","shell.execute_reply":"2021-10-09T15:34:45.688183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are NA values in birthDate so that we should drop them","metadata":{}},{"cell_type":"code","source":"players.dropna(subset=['birthDate'], inplace=True)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.690550Z","iopub.execute_input":"2021-10-09T15:34:45.690885Z","iopub.status.idle":"2021-10-09T15:34:45.706399Z","shell.execute_reply.started":"2021-10-09T15:34:45.690856Z","shell.execute_reply":"2021-10-09T15:34:45.705495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Extract birth year","metadata":{}},{"cell_type":"code","source":"for idx, row in players.iterrows():\n    if len(row['birthDate'].split('/')) == 3: # ex) 05/17/1994 \n        players.loc[idx, 'birthYear'] = row['birthDate'].split('/')[2]\n        \n    elif len(row['birthDate'].split('-')) == 3: # ex) 1995-05-05\n        players.loc[idx, 'birthYear'] = row['birthDate'].split('-')[0]","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:45.707730Z","iopub.execute_input":"2021-10-09T15:34:45.708013Z","iopub.status.idle":"2021-10-09T15:34:46.817561Z","shell.execute_reply.started":"2021-10-09T15:34:45.707986Z","shell.execute_reply":"2021-10-09T15:34:46.816422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 5))\n\nax = sns.distplot(players['birthYear'], bins=25)\nax.set_title('Players birth year Distribution');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:46.818913Z","iopub.execute_input":"2021-10-09T15:34:46.819229Z","iopub.status.idle":"2021-10-09T15:34:47.035982Z","shell.execute_reply.started":"2021-10-09T15:34:46.819201Z","shell.execute_reply":"2021-10-09T15:34:47.035128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Those born in 1995 are the most common","metadata":{}},{"cell_type":"code","source":"players['birthYear'].min(), players['birthYear'].max()","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.037480Z","iopub.execute_input":"2021-10-09T15:34:47.037798Z","iopub.status.idle":"2021-10-09T15:34:47.045507Z","shell.execute_reply.started":"2021-10-09T15:34:47.037766Z","shell.execute_reply":"2021-10-09T15:34:47.044837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The oldest player was born in 1972, and the youngest player was born in 1999","metadata":{}},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n<h2 style='background:transparent; border:0; color:black'><center>3. Play Data<center><h2>","metadata":{}},{"cell_type":"markdown","source":"### **Play data:** The plays.csv file contains play-level information from each game. The key variables are gameId and playId\n- gameId: Game identifier, unique (numeric)\n- playId: Play identifier, not unique across games (numeric)\n- playDescription: Description of play (text)\n- quarter: Game quarter (numeric)\n- down: Down (numeric)\n- yardsToGo: Distance needed for a first down (numeric)\n- possessionTeam: Team punting, placekicking or kicking off the ball (text)\n- specialTeamsPlayType: Formation of play: Extra Point, Field Goal, Kickoff or Punt (text)\n- specialTeamsPlayResult: Special Teams outcome of play dependent on play type: Blocked Kick Attempt, Blocked Punt, Downed, Fair Catch, Kick Attempt Good, Kick Attempt No Good, Kickoff Team Recovery, Muffed, Non-Special Teams Result, Out of Bounds, Return or Touchback (text)\n- kickerId: nflId of placekicker, punter or kickoff specialist on play (numeric)\n- returnerId: nflId(s) of returner(s) on play if there was a special teams return. Multiple returners on a play are separated by a ; (text)\n- kickBlockerId: nflId of blocker of kick on play if there was a blocked field goal or blocked punt (numeric)\n- yardlineSide: 3-letter team code corresponding to line-of-scrimmage (text)\n- yardlineNumber: Yard line at line-of-scrimmage (numeric) \n- gameClock: Time on clock of play (MM:SS)\n- penaltyCodes: NFL categorization of the penalties that occurred on the play. Multiple penalties on a play are separated by a ; (text)\n- penaltyJerseyNumber: Jersey number and team code of the player committing each penalty. Multiple penalties on a play are separated by a ; (text)\n- penaltyYards: yards gained by possessionTeam by penalty (numeric)\n- preSnapHomeScore: Home score prior to the play (numeric)\n- preSnapVisitorScore: Visiting team score prior to the play (numeric)\n- passResult: Scrimmage outcome of the play if specialTeamsPlayResult is \"Non-Special Teams Result\" (C: Complete pass, I: Incomplete pass, S: Quarterback sack, IN: Intercepted pass, R: Scramble, ' ': Designed Rush, text)\n- kickLength: Kick length in air of kickoff, field goal or punt (numeric)\n- kickReturnYardage: Yards gained by return team if there was a return on a kickoff or punt (numeric)\n- playResult: Net yards gained by the kicking team, including penalty yardage (numeric)\n- absoluteYardlineNumber: Location of ball downfield in tracking data coordinates (numeric)","metadata":{}},{"cell_type":"code","source":"plays = pd.read_csv('../input/nfl-big-data-bowl-2022/plays.csv')\n\nplays","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.046645Z","iopub.execute_input":"2021-10-09T15:34:47.047079Z","iopub.status.idle":"2021-10-09T15:34:47.278001Z","shell.execute_reply.started":"2021-10-09T15:34:47.047050Z","shell.execute_reply":"2021-10-09T15:34:47.277106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plays = downcast(plays)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.279274Z","iopub.execute_input":"2021-10-09T15:34:47.279570Z","iopub.status.idle":"2021-10-09T15:34:47.308171Z","shell.execute_reply.started":"2021-10-09T15:34:47.279541Z","shell.execute_reply":"2021-10-09T15:34:47.307128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(plays)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.309567Z","iopub.execute_input":"2021-10-09T15:34:47.310048Z","iopub.status.idle":"2021-10-09T15:34:47.391489Z","shell.execute_reply.started":"2021-10-09T15:34:47.310016Z","shell.execute_reply":"2021-10-09T15:34:47.390413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### There are lots of null values in `returnerld`, `kickBlockerId`, `penaltyCodes`, `penaltyJerseyNumbers`, `penaltyYards`, `passResult`, `kickReturnYardage` features","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(12, 6))\n\nax = sns.countplot(x='quarter', data=plays)\nwrite_percent(ax, len(plays))\nax.set_title('Number of plays of every quarter');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.393557Z","iopub.execute_input":"2021-10-09T15:34:47.394000Z","iopub.status.idle":"2021-10-09T15:34:47.545958Z","shell.execute_reply.started":"2021-10-09T15:34:47.393956Z","shell.execute_reply":"2021-10-09T15:34:47.544752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(12, 6))\n\nax = sns.countplot(x='down', data=plays)\nwrite_percent(ax, len(plays))\nax.set_title('Number of plays of every down');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.550748Z","iopub.execute_input":"2021-10-09T15:34:47.551065Z","iopub.status.idle":"2021-10-09T15:34:47.711645Z","shell.execute_reply.started":"2021-10-09T15:34:47.551034Z","shell.execute_reply":"2021-10-09T15:34:47.710775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=12) \nplt.figure(figsize=(12, 6))\n\nax = sns.countplot(x='yardsToGo', data=plays)\nax.set_title('Number of plays for every yards to go category');","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:47.713836Z","iopub.execute_input":"2021-10-09T15:34:47.714143Z","iopub.status.idle":"2021-10-09T15:34:48.047937Z","shell.execute_reply.started":"2021-10-09T15:34:47.714113Z","shell.execute_reply":"2021-10-09T15:34:48.046875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 5))\n\nax = sns.distplot(plays['playResult'], bins=25);\nax.set_title('playResult Distribution'); ","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:48.049525Z","iopub.execute_input":"2021-10-09T15:34:48.049941Z","iopub.status.idle":"2021-10-09T15:34:48.264737Z","shell.execute_reply.started":"2021-10-09T15:34:48.049908Z","shell.execute_reply":"2021-10-09T15:34:48.263872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"playResult: Net yards gained by the offense, including penalty yardage (numeric)","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 5))\n\nax = sns.distplot(plays['preSnapHomeScore'], bins=12);\nax.set_title('preSnapHomeScore Distribution'); ","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:48.265987Z","iopub.execute_input":"2021-10-09T15:34:48.266281Z","iopub.status.idle":"2021-10-09T15:34:48.557649Z","shell.execute_reply.started":"2021-10-09T15:34:48.266252Z","shell.execute_reply":"2021-10-09T15:34:48.556755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"preSnapHomeScore: Home score prior to the play (numeric)","metadata":{}},{"cell_type":"code","source":"mpl.rc('font', size=15) \nplt.figure(figsize=(10, 5))\n\nax = sns.distplot(plays['preSnapVisitorScore'], bins=12);\nax.set_title('preSnapVisitorScore Distribution'); ","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:48.559262Z","iopub.execute_input":"2021-10-09T15:34:48.559687Z","iopub.status.idle":"2021-10-09T15:34:48.750836Z","shell.execute_reply.started":"2021-10-09T15:34:48.559640Z","shell.execute_reply":"2021-10-09T15:34:48.749769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"preSnapVisitorScore: Visiting team score prior to the play (numeric)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"3\"></a>\n<h2 style='background:transparent; border:0; color:black'><center>4. Tracking Data<center><h2>","metadata":{}},{"cell_type":"code","source":"tracking2018 = pd.read_csv('../input/nfl-big-data-bowl-2022/tracking2018.csv')\ntracking2018.head()","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:34:48.752360Z","iopub.execute_input":"2021-10-09T15:34:48.752857Z","iopub.status.idle":"2021-10-09T15:35:39.143584Z","shell.execute_reply.started":"2021-10-09T15:34:48.752810Z","shell.execute_reply":"2021-10-09T15:35:39.142734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tracking2018 = downcast(tracking2018)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:39.144752Z","iopub.execute_input":"2021-10-09T15:35:39.145019Z","iopub.status.idle":"2021-10-09T15:35:42.838748Z","shell.execute_reply.started":"2021-10-09T15:35:39.144993Z","shell.execute_reply":"2021-10-09T15:35:42.837440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This function is taken from the post created by ROB MULLA. See the post [here](https://www.kaggle.com/robikscube/nfl-big-data-bowl-2022-twitch-stream-eda). Thank you ROB MULLA :)","metadata":{}},{"cell_type":"markdown","source":"#### 2018123000 and playId == 36","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12, 8))\ntracking2018.query('gameId == 2018123000 and playId == 36').groupby('team') \\\n    .plot(x='x', y='y', ax=ax, style='.')\nplt.legend().remove();","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:42.840343Z","iopub.execute_input":"2021-10-09T15:35:42.840802Z","iopub.status.idle":"2021-10-09T15:35:43.573856Z","shell.execute_reply.started":"2021-10-09T15:35:42.840756Z","shell.execute_reply":"2021-10-09T15:35:43.572600Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### gameId == 2018091001 and playId == 4033","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12, 8))\ntracking2018.query('gameId == 2018091001 and playId == 4033').groupby('team') \\\n    .plot(x='x', y='y', ax=ax, style='.')\nplt.legend().remove();","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:43.575350Z","iopub.execute_input":"2021-10-09T15:35:43.575765Z","iopub.status.idle":"2021-10-09T15:35:43.881473Z","shell.execute_reply.started":"2021-10-09T15:35:43.575732Z","shell.execute_reply":"2021-10-09T15:35:43.880208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### gameId == 2018091609 and position == \"CB\"","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12, 8))\ntracking2018.query('gameId == 2018091609 and position == \"CB\"').groupby('team') \\\n    .plot(x='x', y='y', ax=ax, style='.')\nplt.legend().remove();","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:43.882955Z","iopub.execute_input":"2021-10-09T15:35:43.883266Z","iopub.status.idle":"2021-10-09T15:35:44.620417Z","shell.execute_reply.started":"2021-10-09T15:35:43.883235Z","shell.execute_reply":"2021-10-09T15:35:44.619375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### gameId == 2018091609 and position == \"LB\"","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12, 8))\ntracking2018.query('gameId == 2018091609 and position == \"LB\"').groupby('team') \\\n    .plot(x='x', y='y', ax=ax, style='.')\nplt.legend().remove();","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:44.621897Z","iopub.execute_input":"2021-10-09T15:35:44.622195Z","iopub.status.idle":"2021-10-09T15:35:45.322422Z","shell.execute_reply.started":"2021-10-09T15:35:44.622165Z","shell.execute_reply":"2021-10-09T15:35:45.321295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### gameId == 2018091609 and position == \"RB\"","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12, 8))\ntracking2018.query('gameId == 2018091609 and position == \"RB\"').groupby('team') \\\n    .plot(x='x', y='y', ax=ax, style='.')\nplt.legend().remove();","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:45.323653Z","iopub.execute_input":"2021-10-09T15:35:45.323941Z","iopub.status.idle":"2021-10-09T15:35:46.017585Z","shell.execute_reply.started":"2021-10-09T15:35:45.323914Z","shell.execute_reply":"2021-10-09T15:35:46.016705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Function to create football field\n","metadata":{}},{"cell_type":"markdown","source":"This function is taken from the post created by JARON_MICHAL. See the post [here](https://www.kaggle.com/jaronmichal/tracking-data-visualization)","metadata":{}},{"cell_type":"code","source":"import matplotlib.patches as patches\nfrom matplotlib.patches import Arc\nfrom matplotlib import pyplot as plt\nimport matplotlib.patches as mpatches\n\n# Change size of the figure\nplt.rcParams['figure.figsize'] = [12, 8]\ndef drawPitch(width, height, color=\"w\"):\n    fig = plt.figure()\n    ax = plt.axes(xlim=(-10, width + 30), ylim=(-15, height + 5))\n    plt.axis('off')\n\n    # Grass around pitch\n    rect = patches.Rectangle((-10, -5), width + 40, height + 10, linewidth=1, facecolor='#3f995b', capstyle='round')\n    ax.add_patch(rect)\n    ###################\n\n    # Pitch boundaries\n    rect = plt.Rectangle((0, 0), width + 20, height, ec=color, fc=\"None\", lw=2)\n    ax.add_patch(rect)\n    ###################\n\n    # vertical lines - every 5 yards\n    for i in range(21):\n        plt.plot([10 + 5 * i, 10 + 5 * i], [0, height], c=\"w\", lw=2)\n    ###################\n        \n    # distance markers - every 10 yards\n    for yards in range(10, width, 10):\n        yards_text = yards if yards <= width / 2 else width - yards\n        # top markers\n        plt.text(10 + yards - 2, height - 7.5, yards_text, size=15, c=\"w\", weight=\"bold\")\n        # botoom markers\n        plt.text(10 + yards - 2, 7.5, yards_text, size=15, c=\"w\", weight=\"bold\", rotation=180)\n    ###################\n\n    # yards markers - every yard\n    # bottom markers\n    for x in range(20):\n        for j in range(1, 5):\n            plt.plot([10 + x * 5 + j, 10 + x * 5 + j], [1, 3], color=\"w\", lw=2)\n\n    # top markers\n    for x in range(20):\n        for j in range(1, 5):\n            plt.plot([10 + x * 5 + j, 10 + x * 5 + j], [height - 1, height - 3], color=\"w\", lw=2)\n\n    # middle bottom markers\n    y = (height - 18.5) / 2\n    for x in range(20):\n        for j in range(1, 5):\n            plt.plot([10 + x * 5 + j, 10 + x * 5 + j], [y, y + 2], color=\"w\", lw=2)\n\n    # middle top markers\n    for x in range(20):\n        for j in range(1, 5):\n            plt.plot([10 + x * 5 + j, 10 + x * 5 + j], [height - y, height - y - 2], color=\"w\", lw=2)\n    ###################\n\n    # draw home end zone\n    plt.text(2.5, (height - 15) / 2, \"HOME\", size=30, c=\"w\", weight=\"bold\", rotation=90)\n    rect = plt.Rectangle((0, 0), 10, height, ec=color, fc=\"#0064dc\", lw=2)\n    ax.add_patch(rect)\n\n    # draw away end zone    \n    plt.text(111, (height - 15) / 2, \"AWAY\", size=30, c=\"w\", weight=\"bold\", rotation=-90)\n    rect = plt.Rectangle((width + 10, 0), 10, height, ec=color, fc=\"#c80014\", lw=2)\n    ax.add_patch(rect)\n    ###################\n    \n    # draw extra spot point\n    # left\n    y = (height - 3) / 2\n    plt.plot([10 + 2, 10 + 2], [y, y + 3], c=\"w\", lw=2)\n    \n    # right\n    plt.plot([width + 10 - 2, width + 10 - 2], [y, y + 3], c=\"w\", lw=2)\n    ###################\n    \n    # draw goalpost\n    goal_width = 6 # yards\n    y = (height - goal_width) / 2\n    # left\n    plt.plot([0, 0], [y, y + goal_width], \"-\", c=\"y\", lw=10, ms=20)\n    # right\n    plt.plot([width + 20, width + 20], [y, y + goal_width], \"-\", c=\"y\", lw=10, ms=20)\n    \n    return fig, ax","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-09T15:35:46.018931Z","iopub.execute_input":"2021-10-09T15:35:46.019237Z","iopub.status.idle":"2021-10-09T15:35:46.054134Z","shell.execute_reply.started":"2021-10-09T15:35:46.019209Z","shell.execute_reply":"2021-10-09T15:35:46.052818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" fig, ax = drawPitch(100, 53.3)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:46.055609Z","iopub.execute_input":"2021-10-09T15:35:46.055946Z","iopub.status.idle":"2021-10-09T15:35:46.683554Z","shell.execute_reply.started":"2021-10-09T15:35:46.055917Z","shell.execute_reply":"2021-10-09T15:35:46.682557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Function to create animation","metadata":{}},{"cell_type":"code","source":"games_ids = {}\ngames_tracking2018 = tracking2018.groupby(by=[\"gameId\"])\nfor game, data in games_tracking2018:\n    games_ids[game] = list(set(data.playId.tolist()))","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:46.684949Z","iopub.execute_input":"2021-10-09T15:35:46.685508Z","iopub.status.idle":"2021-10-09T15:35:49.068657Z","shell.execute_reply.started":"2021-10-09T15:35:46.685466Z","shell.execute_reply":"2021-10-09T15:35:49.067006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_one_game(game_id, play_id, df):\n    game = df[(df.gameId == game_id) & (df.playId == play_id)]\n    home = {}\n    away = {}\n    balls = []\n    \n    players = game.sort_values(['frameId'], ascending=True).groupby('nflId')\n    for id, dx in players:\n        jerseyNumber = int(dx.jerseyNumber.iloc[0])\n        if dx.team.iloc[0] == \"home\":\n            home[jerseyNumber] = list(zip(dx.x.tolist(), dx.y.tolist()))\n        elif dx.team.iloc[0] == \"away\":\n            away[jerseyNumber] = list(zip(dx.x.tolist(), dx.y.tolist()))\n\n\n    ball_df = game.sort_values(['frameId'], ascending=True) \n    ball_df = ball_df[ball_df.team == \"football\"]\n    balls = list(zip(ball_df.x.tolist(), ball_df.y.tolist()))\n    return home, away, balls","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-09T15:35:49.070333Z","iopub.execute_input":"2021-10-09T15:35:49.070760Z","iopub.status.idle":"2021-10-09T15:35:49.082931Z","shell.execute_reply.started":"2021-10-09T15:35:49.070715Z","shell.execute_reply":"2021-10-09T15:35:49.082145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib import animation\nfrom IPython.display import HTML\ndef animate_one_play(game_id, play_id, df):\n    fig, ax = drawPitch(100, 53.3)\n    \n    home, away, balls = extract_one_game(game_id, play_id, df)\n\n    team_left, = ax.plot([], [], 'o', markersize=20, markerfacecolor=\"r\", markeredgewidth=2, markeredgecolor=\"white\", zorder=7)\n    team_right, = ax.plot([], [], 'o', markersize=20, markerfacecolor=\"b\", markeredgewidth=2, markeredgecolor=\"white\", zorder=7)\n    ball, = ax.plot([], [], 'o', markersize=10, markerfacecolor=\"black\", markeredgewidth=2, markeredgecolor=\"white\", zorder=7)\n    drawings = [team_left, team_right, ball]\n\n    def init():\n        team_left.set_data([], [])\n        team_right.set_data([], [])\n        ball.set_data([], [])\n        return drawings\n\n    def draw_teams(i):\n        X = []\n        Y = []\n        for k, v in home.items():\n            x, y = v[i]\n            X.append(x)\n            Y.append(y)\n        team_left.set_data(X, Y)\n        \n        X = []\n        Y = []\n        for k, v in away.items():\n            x, y = v[i]\n            X.append(x)\n            Y.append(y)\n        team_right.set_data(X, Y)\n\n    def animate(i):\n        draw_teams(i)\n        \n        x, y = balls[i]\n        ball.set_data([x, y])\n        return drawings\n    \n    # !May take a while!\n    anim = animation.FuncAnimation(fig, animate, init_func=init,\n                                   frames=len(balls), interval=100, blit=True)\n\n    return HTML(anim.to_html5_video())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-09T15:35:49.084005Z","iopub.execute_input":"2021-10-09T15:35:49.084409Z","iopub.status.idle":"2021-10-09T15:35:49.112540Z","shell.execute_reply.started":"2021-10-09T15:35:49.084378Z","shell.execute_reply":"2021-10-09T15:35:49.110706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"animate_one_play(2018123000, 36, tracking2018)","metadata":{"execution":{"iopub.status.busy":"2021-10-09T15:35:49.114040Z","iopub.execute_input":"2021-10-09T15:35:49.114317Z","iopub.status.idle":"2021-10-09T15:36:01.892879Z","shell.execute_reply.started":"2021-10-09T15:35:49.114289Z","shell.execute_reply":"2021-10-09T15:36:01.892036Z"},"trusted":true},"execution_count":null,"outputs":[]}]}