{"cells":[{"metadata":{},"cell_type":"markdown","source":"# NFL Surface Comparison\n\nWith our data we'll be seeing if we can identify any differences on synthetic and natural surfaces that lead to a heightened chance of injury.\n\n"},{"metadata":{},"cell_type":"markdown","source":"# The Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Loading in our data\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport plotly.graph_objects as go\nimport plotly.express as px\nfrom plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot\ninit_notebook_mode(connected=True)\n\ninj = pd.read_csv('../input/nfl-playing-surface-analytics/InjuryRecord.csv')\nplay = pd.read_csv('../input/nfl-playing-surface-analytics/PlayList.csv')\nplayer = pd.read_csv('../input/nfl-playing-surface-analytics/PlayerTrackData.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Looking at our data\n\ninj.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"play.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"player.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Cleaning"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let's start with Injury Record data.\n\ninj.groupby('BodyPart').count()['PlayerKey'] \\\n    .sort_values() \\\n    .plot(kind='bar', figsize=(15, 5), title='Count of Injuries by Body Part')\nplt.show()\n\ninj.groupby('Surface').count()['PlayerKey'] \\\n    .sort_values() \\\n    .plot(kind='barh', figsize=(15, 5), title='Count of Injuries by Field Surface')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Overall the Injury Record data looks pretty clean. Let's move along to the play list."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Play List Data\n\nplay.groupby('FieldType').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='bar', figsize=(15, 5), title = 'Plays by Field Type')\nplt.show()\n\nplay.groupby('RosterPosition').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='bar', figsize=(15, 5), title = 'Plays by Roster Position')\nplt.show()\n\nplay.groupby('PlayType').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='bar', figsize=(15, 5), title = 'Plays by Play Type')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"*Interesting* - the amount of plays on natural fields is higher than synthetic, but we know that the amount of injuries on synthetic fields in our data is greater. We'll come back to that but let's continue exploring our data."},{"metadata":{"trusted":true},"cell_type":"code","source":"# First opportunity for cleaning. The Stadium Types have some misspellings and redundancies. Let's condense this to 4 values: outdoors, indoors, open, or closed.\n\nplay['StadiumType'].unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"array_outdoors = ['Outdoor', 'Oudoor', 'Outdoors',\n       'Ourdoor', 'Outddors', 'Heinz Field', 'Outdor', 'Outside', 'Cloudy']\narray_indoors = ['Indoors', 'Indoor', 'Indoor', 'Retractable Roof']\narray_open = ['Open','Outdoor Retr Roof-Open', 'Retr. Roof-Open', 'Indoor, Open Roof',\n       'Domed, Open', 'Domed, open', 'Retr. Roof - Open']\narray_closed = ['Closed Dome', 'Domed, closed', 'Dome', 'Domed',\n       'Retr. Roof-Closed', 'Outdoor Retr Roof-Open', 'Retractable Roof', 'Indoor, Roof Closed', 'Retr. Roof - Closed', 'Bowl', 'Dome, closed',\n       'Retr. Roof Closed']\n\nplay['StadiumType'] = play['StadiumType'].replace(array_outdoors, 'Outdoors')\nplay['StadiumType'] = play['StadiumType'].replace(array_indoors, 'Indoors')\nplay['StadiumType'] = play['StadiumType'].replace(array_open, 'Open')\nplay['StadiumType'] = play['StadiumType'].replace(array_closed, 'Closed')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# That's better.\n\nplay.groupby('StadiumType').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='barh', figsize=(15, 5), title= 'Plays by Stadium Type')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Weather is another one that can use some work. We'll condense this to clear, cloudy, indoors, and precipitation.\n\nplay['Weather'].unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"array_clear = ['Clear and warm', 'Sunny', 'Clear',\n       'Sunny and warm', 'Clear and Cool',\n       'Clear and cold', 'Sunny and cold', 'Partly Sunny',\n       'Mostly Sunny', 'Clear Skies', 'Partly sunny', \n       'Sunny and clear', 'Clear skies',\n       'Sunny Skies', 'Fair', 'Partly clear', \n       'Heat Index 95', 'Sunny, highs to upper 80s', \n       'Mostly sunny', 'Sunny, Windy', 'Mostly Sunny Skies', \n       'Clear and Sunny', 'Clear and sunny',\n       'Clear to Partly Cloudy', 'Cold']\n\narray_cloudy = ['Mostly Cloudy', 'Cloudy',\n       'Cloudy, fog started developing in 2nd quarter',\n       'Partly Cloudy', 'Mostly cloudy', 'Cloudy and cold',\n       'Cloudy and Cool', 'Partly cloudy', \n       'Party Cloudy', 'Hazy', 'Partly Clouidy',\n       'Overcast', 'Cloudy, 50% change of rain',\n       'Mostly Coudy', 'Cloudy, chance of rain',\n       'Sun & clouds', 'Cloudy, Rain',\n       'cloudy', 'Coudy']\n\narray_indoors = ['Controlled Climate','Indoor',\n       'N/A (Indoors)', 'Indoors', 'N/A Indoor']\n\narray_precip = ['Rain',\n       'Snow',\n       'Scattered Showers',\n       'Light Rain',\n       'Heavy lake effect snow', 'Cloudy, Rain',\n       'Rainy',\n       'Cloudy, light snow accumulating 1-3\"',\n       'Cloudy with periods of rain, thunder possible. Winds shifting to WNW, 10-20 mph.',\n       'Rain shower', 'Rain likely, temps in low 40s.', 'Rain Chance 40%', 'Rain likely, temps in low 40s.',\n       'Cloudy, 50% change of rain', '10% Chance of Rain', 'Showers', '30% Chance of Rain']\n\nplay['Weather'] = play['Weather'].replace(array_clear, 'Clear')\nplay['Weather'] = play['Weather'].replace(array_cloudy, 'Cloudy')\nplay['Weather'] = play['Weather'].replace(array_indoors, 'Indoors')\nplay['Weather'] = play['Weather'].replace(array_precip, 'Precipitation')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Now we have 4 categories to ease our analyses.\n\nplay.groupby('Weather').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='barh', figsize=(15, 5), title= 'Plays by Weather')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Analysis\n\nNow using Plotly to be able to gain deeper insights and make use of the powerful interactive tools to compare surface types and situations."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating a merged table to be able to analyze injury plays deeper.\n\nmerge = pd.merge(inj, play)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Since some injury records are missing a Play Key, only 77 of these records will remain."},{"metadata":{"trusted":true},"cell_type":"code","source":"pos = merge.groupby(['RosterPosition','Surface']) \\\n    .count() \\\n    .unstack('Surface')['PlayKey'] \\\n    .T.apply(lambda x: x / x.sum()) \\\n    .sort_values('Surface').T.sort_values('Synthetic', ascending=False) \\\n\npos['RosterPosition'] = pos.index\npos.columns = ['Natural', 'Synthetic', 'RosterPosition']\n\nfig = go.Figure(data=[\n    go.Bar(name='Natural', x=pos['RosterPosition'], y=pos['Natural']),\n    go.Bar(name='Synthetic', x=pos['RosterPosition'], y=pos['Synthetic'])\n])\n\nfig.update_layout(barmode='stack', title='Injuries by Roster Position')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Cornerback has the largest percentage of synthetic injuries. We'll take a deeper look at this later on."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Injury analysis by body part.\n\nbp = merge.groupby(['BodyPart','Surface']) \\\n    .count() \\\n    .unstack('BodyPart')['PlayKey'] \\\n\nbp['Surface'] = bp.index\nbp.columns = ['Ankle', 'Foot', 'Knee', 'Surface']\n\nfig = go.Figure(data=[\n    go.Bar(name='Ankle', x=bp['Surface'], y=bp['Ankle']),\n    go.Bar(name='Knee', x=bp['Surface'], y=bp['Knee']),\n    go.Bar(name='Foot', x=bp['Surface'], y=bp['Foot'])\n])\n\nfig.update_layout(barmode='group', title='Injuries by Body Part')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Ankle injuries see a significant increase with Synthetic surfaces."},{"metadata":{"trusted":true},"cell_type":"code","source":"pt = merge.groupby(['PlayType','Surface']) \\\n    .count() \\\n    .unstack('Surface')['PlayKey'] \\\n    .T.apply(lambda x: x / x.sum()) \\\n    .sort_values('Surface').T.sort_values('Synthetic', ascending=False) \\\n\npt['PlayType'] = pt.index\n\npt.columns = 'Natural', 'Synthetic', 'PlayType'\n\nfig = go.Figure(data=[\n    go.Bar(name='Natural', x=pt['PlayType'], y=pt['Natural']),\n    go.Bar(name='Synthetic', x=pt['PlayType'], y=pt['Synthetic'])\n])\n\nfig.update_layout(barmode='stack', title='Injuries by Play Type')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Pass and Rush are the main play types we are concerned with as we saw the special teams injuries make up a small portion of our data. Here we can see we have slightly more injuries recorded on Natural surfaces for these 2 play types."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Isolating our pass & rush plays.\n\nis_pass = merge['PlayType']=='Pass'\n\nis_rush = merge['PlayType']=='Rush'\n\npassmerge = merge[is_pass]\n\nrushmerge = merge[is_rush]\n\npassrush = pd.merge(passmerge, rushmerge, how='outer')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pr = passrush.groupby(['PlayType','PositionGroup']) \\\n    .count() \\\n    .unstack('PositionGroup')['PlayKey'] \\\n    .sort_values('PlayType').T.sort_values('Pass', ascending=False) \\\n\npr['PositionGroup'] = pr.index\n\npr.columns = 'Pass', 'Rush', 'PositionGroup'\n\nfig = go.Figure(data=[\n    go.Bar(name='Rush', x=pr['PositionGroup'], y=pr['Rush']),\n    go.Bar(name='Pass', x=pr['PositionGroup'], y=pr['Pass'])\n])\n\nfig.update_layout(barmode='stack', title='Injury Play Type by Position Group')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Position clearly plays a large role in the Play Type on injuries. Positions like DB & WR will have more injuries on pass plays, which is excpected and RB's will have more on Rush plays. LB and DL will also have more injuries on rushes while OL is pretty split."},{"metadata":{},"cell_type":"markdown","source":"# Weather & Temperature\nWe'll use matplotlib here to quickly compare to our master data we saw earlier."},{"metadata":{"trusted":true},"cell_type":"code","source":"merge.groupby('Weather').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='barh', figsize=(15, 5), title= 'Plays by Weather')\nplt.show()\n\nmerge.groupby('Temperature').count()['PlayKey'] \\\n    .sort_values() \\\n    .plot(kind='barh', figsize=(15, 10), title= 'Plays by Temperature')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Weather and temperature don't appear to have any significant effect as these match up with the number of total plays for each condition we viewed earlier."},{"metadata":{},"cell_type":"markdown","source":"# Cornerback Drilldown:"},{"metadata":{"trusted":true},"cell_type":"code","source":"is_cb = merge['RosterPosition']=='Cornerback'\n\ncbmerge = merge[is_cb]\n\ncbmerge['PlayKey'].nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We're working with a pretty small sample of CB injuries here, but we'll go ahead and explore some."},{"metadata":{"trusted":true},"cell_type":"code","source":"cbpt = cbmerge.groupby(['PlayType','PlayKey']) \\\n    .count() \\\n    .unstack('PlayKey')['PlayerKey'] \\\n\ncbpt['PlayType'] = cbpt.index\n\ncbpt.columns = 'Play1','Play2','Play3','Play4','Play5','Play6','Play7','PlayType'\n\ncbpt.fillna(0, inplace=True)\n\ncbpt['Count']= cbpt['Play1'] + cbpt['Play2'] + cbpt['Play3'] + cbpt['Play4'] + cbpt['Play5'] + cbpt['Play6'] + cbpt['Play7']\n\nfig = px.bar(cbpt, x='PlayType', y='Count')\nfig.update_layout(title='CB Injuries by Play Type')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Most of these injuries were in passing situations. Let's compare in the next graph how many were on synthetic fields and how many were on natural fields."},{"metadata":{"trusted":true},"cell_type":"code","source":"cbpts = cbmerge.groupby(['PlayType','FieldType']) \\\n    .count() \\\n    .unstack('FieldType')['PlayKey'] \\\n    .T.apply(lambda x: x / x.sum()) \\\n    .sort_values('FieldType').T.sort_values('Synthetic', ascending=False) \\\n\ncbpts['PlayType'] = cbpts.index\n\ncbpts.columns = 'Natural', 'Synthetic', 'PlayType'\n\nfig = go.Figure(data=[\n    go.Bar(name='Natural', x=cbpts['PlayType'], y=cbpts['Natural']),\n    go.Bar(name='Synthetic', x=cbpts['PlayType'], y=cbpts['Synthetic'])\n])\n\nfig.update_layout(barmode='stack', title='CB Injuries by Play Type & Surface')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"All except one of our CB injuries was recorded on a synthetic surface."},{"metadata":{"trusted":true},"cell_type":"code","source":"cbbp = cbmerge.groupby(['BodyPart', 'PlayKey']) \\\n    .count() \\\n    .unstack('PlayKey')['PlayerKey'] \\\n\ncbbp['BodyPart'] = cbbp.index\n\ncbbp.columns = 'Play1','Play2','Play3','Play4','Play5','Play6','Play7','BodyPart'\n\ncbbp.fillna(0, inplace=True)\n\ncbbp['Count']= cbbp['Play1'] + cbbp['Play2'] + cbbp['Play3'] + cbbp['Play4'] + cbbp['Play5'] + cbbp['Play6'] + cbbp['Play7']\n\nfig = px.bar(cbbp, x='BodyPart', y='Count')\nfig.update_layout(title='CB Injuries by Body Part')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As is the case with the rest of our data, Ankle is the most common injury type."},{"metadata":{"trusted":true},"cell_type":"code","source":"cbil = cbmerge[['DM_M1','DM_M7','DM_M28','DM_M42']].sum().reset_index()\n\ncbil.columns = 'Length','Count'\n\nfig = px.bar(cbil, x='Length', y='Count')\nfig.update_layout(title='CB Injuries by Length')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"To summarize our CB section:\n\nCB's are mainly having ankle injuries on pass plays. The majority put them out for a week."},{"metadata":{},"cell_type":"markdown","source":"# Distribution of Player Speed & Distance\n\nNow we'll take a look at the distribution of speed / distance based on the data we were given in the Player Track csv."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Merging tables to gain s and dis on our injury plays.\n\ninj_detail = pd.merge(inj, player)\n\ninj_detail_syn = inj_detail['Surface']=='Synthetic'\ninjsynthviolin = inj_detail[inj_detail_syn]\n\ninj_detail_nat = inj_detail['Surface']=='Natural'\ninjnatviolin = inj_detail[inj_detail_nat]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating groups for synthetic and natural field types by max speed.\n\ninj_s_syn = injsynthviolin.groupby('PlayKey', as_index=False)['s'].max()\ninj_s_nat = injnatviolin.groupby('PlayKey', as_index=False)['s'].max()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = px.violin(inj_s_nat, y='s', box=True,\n                points='all', title='Distribution of Max Speed - Natural'\n               )\nfig.show()\n\nfig = px.violin(inj_s_syn, y='s', box=True,\n                points='all', title='Distribution of Max Speed - Synthetic'\n               )\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Our distributions appear pretty similar - we can see a higher distribution as the max speed on the play rises in both."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Creating groups for synthetic and natural field types by max distance.\n\ninj_dis_syn = injsynthviolin.groupby('PlayKey', as_index=False)['dis'].max()\ninj_dis_nat = injnatviolin.groupby('PlayKey', as_index=False)['dis'].max()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = px.violin(inj_dis_nat, y='dis', box=True,\n                points='all', title='Distribution of Max Distance - Natural'\n               )\nfig.show()\n\nfig = px.violin(inj_dis_syn, y='dis', box=True,\n                points='all', title='Distribution of Max Distance - Synthetic'\n               )\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Our distribution for distance looks similar as well, there is a bump in the mid to higher distances traveled for both."},{"metadata":{},"cell_type":"markdown","source":"# Plotting the Plays:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_football_field(linenumbers=True,\n                          endzones=True,\n                          highlight_line=False,\n                          highlight_line_number=50,\n                          highlighted_name='Line of Scrimmage',\n                          fifty_is_los=False,\n                          figsize=(12, 6.33)):\n \n    rect = patches.Rectangle((0, 0), 120, 53.3, linewidth=0.1,\n                             edgecolor='r', facecolor='darkgreen', zorder=0)\n\n    fig, ax = plt.subplots(1, figsize=figsize)\n    ax.add_patch(rect)\n\n    plt.plot([10, 10, 10, 20, 20, 30, 30, 40, 40, 50, 50, 60, 60, 70, 70, 80,\n              80, 90, 90, 100, 100, 110, 110, 120, 0, 0, 120, 120],\n             [0, 0, 53.3, 53.3, 0, 0, 53.3, 53.3, 0, 0, 53.3, 53.3, 0, 0, 53.3,\n              53.3, 0, 0, 53.3, 53.3, 0, 0, 53.3, 53.3, 53.3, 0, 0, 53.3],\n             color='white')\n    if fifty_is_los:\n        plt.plot([60, 60], [0, 53.3], color='gold')\n        plt.text(62, 50, '<- Player Yardline at Snap', color='gold')\n    # Endzones\n    if endzones:\n        ez1 = patches.Rectangle((0, 0), 10, 53.3,\n                                linewidth=0.1,\n                                edgecolor='r',\n                                facecolor='blue',\n                                alpha=0.2,\n                                zorder=0)\n        ez2 = patches.Rectangle((110, 0), 120, 53.3,\n                                linewidth=0.1,\n                                edgecolor='r',\n                                facecolor='blue',\n                                alpha=0.2,\n                                zorder=0)\n        ax.add_patch(ez1)\n        ax.add_patch(ez2)\n    plt.xlim(0, 120)\n    plt.ylim(-5, 58.3)\n    plt.axis('off')\n    if linenumbers:\n        for x in range(20, 110, 10):\n            numb = x\n            if x > 50:\n                numb = 120 - x\n            plt.text(x, 5, str(numb - 10),\n                     horizontalalignment='center',\n                     fontsize=20,  # fontname='Arial',\n                     color='white')\n            plt.text(x - 0.95, 53.3 - 5, str(numb - 10),\n                     horizontalalignment='center',\n                     fontsize=20,  # fontname='Arial',\n                     color='white', rotation=180)\n    if endzones:\n        hash_range = range(11, 110)\n    else:\n        hash_range = range(1, 120)\n\n    for x in hash_range:\n        ax.plot([x, x], [0.4, 0.7], color='white')\n        ax.plot([x, x], [53.0, 52.5], color='white')\n        ax.plot([x, x], [22.91, 23.57], color='white')\n        ax.plot([x, x], [29.73, 30.39], color='white')\n\n    if highlight_line:\n        hl = highlight_line_number + 10\n        plt.plot([hl, hl], [0, 53.3], color='yellow')\n        plt.text(hl + 2, 50, '<- {}'.format(highlighted_name),\n                 color='yellow')\n    return fig, ax\n\ncreate_football_field()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# To start off we'll use an example from our CB data.\n\ncbmerge.head(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"example_play = player['PlayKey']=='43518-6-25'\n\nexample = player[example_play]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plotting our first play\n\nfig, ax = create_football_field()\nexample.groupby('PlayKey'), example.plot(kind='scatter', x='x', y='y', ax=ax, color='orange', alpha=0.2)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Breaking our injuries apart by synthetic and natural fields.\n\ninj_syn = passrush['Surface']=='Synthetic'\ninjsynthetic = passrush[inj_syn]\ninj_nat = passrush['Surface']=='Natural'\ninjnatural = passrush[inj_nat]\n\nsynplot = pd.merge(injsynthetic, player)\nnatplot = pd.merge(injnatural, player)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = create_football_field()\nnatplot.groupby('PlayKey'), natplot.plot(kind='scatter', x='x', y='y', ax=ax, color='orange', alpha=0.2, title='Natural Surface')\nplt.show()\n\nfig, ax = create_football_field()\nsynplot.groupby('PlayKey'), synplot.plot(kind='scatter', x='x', y='y', ax=ax, color='red', alpha=0.2, title='Synthetic Surface')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"There seems to be a difference in where these plays end. Injuries on Natural surfaces seemed to start and end in the middle of the field and injuries on Synthetic surfaces seemed to end more in the end zones, out of bounds, or along the side lines. This seems to possibly indicate that more non-contact injuries are occuring on synthetic surfaces, as these plays are not ending due to being tackled as much as on Natural surfaces."},{"metadata":{},"cell_type":"markdown","source":"# Conclusion\n\nFrom our findings, we are able to identify some differences in the injuries we were provided based on the field surfaces. Some of these findings include the following:\n\n- Total injury rate on Synthetic surfaces is higher in the data we were provided.\n- Lower limb injuries are more common on Synthetic surfaces.\n- Skill positions and DB's have more injuries on Synthetic surfaces.\n- There appears to be a higher concentration of injuries as speed and distance increase.\n- Non-contact injuries appear to be the result of more injuries on Synthetic surfaces judging from our play plots on the field."}],"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":4,"nbformat_minor":1}