{"cells":[{"metadata":{},"cell_type":"markdown","source":"# EDA for NCAA March Madness"},{"metadata":{},"cell_type":"markdown","source":"This kernel is very simple EDA about NCAA March Madness. I referred to [Rob Mulla's kernel](https://www.kaggle.com/robikscube/2020-march-madness-data-first-look-eda). There are lots of input data files in this competition so that you can dive into EDA with other input data files not used in this kernel. Let's get started!!"},{"metadata":{},"cell_type":"markdown","source":"### [EDA](#EDA)\n [- MTeams](#MTeams)  \n [- MNCAATourneySeeds](#MNCAATourneySeeds)  \n [- MRegularSeasonCompactResults](#MRegularSeasonCompactResults)  \n [- MEvents](#MEvents)  \n [- MPlayers](#MPlayers)"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport glob\nimport pandas as pd\nimport numpy as np\nimport re\nimport random\nimport seaborn as sns\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Circle, Rectangle, Arc\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.utils import shuffle\nfrom sklearn.model_selection import GridSearchCV\n\n%matplotlib inline\n\nplt.style.use('fivethirtyeight')\nsns.set(font_scale=2.2)\nsns.set(style=\"whitegrid\")\nbase_color = sns.color_palette()[0]\nsecond_color = sns.color_palette()[1]\nthird_color = sns.color_palette()[2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"files = glob.glob('/kaggle/input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/MEvents*.csv')","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"# Load all csv file started with 'MEvents'\ndata_frames = [pd.read_csv(file) for file in files]\n\nevents = pd.concat(data_frames, axis=0, sort=False)\nevents.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Debugging: When it is true, load 50,000 rows randomly according to MEvents. if false, load all rows\n# Reference: https://stackoverflow.com/questions/22258491/read-a-small-random-sample-from-a-big-csv-file-into-a-python-data-frame\n\nDEBUG = False\nif DEBUG:\n    sample_size = 50000\nelse: \n    sample_size = None\n\ndef get_skiprows(file, sample_size):\n    num_of_records = sum(1 for line in open(file))\n    # the 0-indexed header will not be included in the skip list\n    if DEBUG:\n        skiprows = sorted(random.sample(range(1,num_of_records+1),\n                                    num_of_records-sample_size))\n    else:\n        skiprows=None\n    return skiprows","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"PATH = '../input/google-cloud-ncaa-march-madness-2020-division-1-mens-tournament/'\ndfs = {'MEvents': [], 'Misc': {}}\nfor root, dirs, files in os.walk(PATH):\n    print(PATH)\n    for file in files:\n        path_and_file = os.path.join(root, file)\n        print(path_and_file)\n        if bool(re.search('MEvents', path_and_file)):\n            skiprows = get_skiprows(path_and_file, sample_size)\n            dfs['MEvents'].append(pd.read_csv(path_and_file, skiprows=skiprows))\n            \n        elif bool(re.search('.DS_Store', path_and_file)):\n            pass\n        else:\n            file_name_start_index = path_and_file.rfind('/') + 1\n            file_name_end_index = re.search('.csv', path_and_file).span()[0]\n            if bool(re.search('MTeamSpellings', path_and_file)):\n                dfs['Misc'][path_and_file[file_name_start_index:file_name_end_index]] = pd.read_csv(path_and_file, encoding='cp1252')\n            else: \n                dfs['Misc'][path_and_file[file_name_start_index:file_name_end_index]] = pd.read_csv(path_and_file)                \n            ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# EDA"},{"metadata":{},"cell_type":"markdown","source":"## MTeams"},{"metadata":{},"cell_type":"markdown","source":"- `FirstD1Season`: the first season in our dataset that the school was a Division-I school\n- `LastD1Season`: the last season in our dataset that the school was a Division-I school"},{"metadata":{"trusted":true},"cell_type":"code","source":"dfs['Misc'].keys()","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MTeams = dfs['Misc']['MTeams']\nMTeams.head()","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MTeams.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"There are 367 teams."},{"metadata":{"trusted":true},"cell_type":"code","source":"MTeams.sort_values('FirstD1Season', ascending=False).head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"`Merrimack` has just moved to Division I this year."},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"def plot_bar_chart(df, feature):\n    plt.figure(figsize=(12, 5))\n    counts = df[feature].value_counts()\n    sns.barplot(x=counts.index, y=counts.values, color=base_color)\n\n\nplot_bar_chart(MTeams, 'FirstD1Season')\nplt.title('FirstD1Season Counts', fontsize=18); plt.xlabel('FirstD1Season', fontsize=15); plt.ylabel('Counts', fontsize=15)\nplt.xticks(rotation=30);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"rate_of_FirstD1Season = round(MTeams['FirstD1Season'].value_counts().max() / MTeams.shape[0], 2)\nrate_of_FirstD1Season = int(rate_of_FirstD1Season*100)\nprint(f'{rate_of_FirstD1Season}% of the teams got into Division I in 1985. Note that the teams that entered before 1985 are also recorded as 1985')","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"plot_bar_chart(MTeams, 'LastD1Season')\nplt.title('LastD1Season Counts', fontsize=18); plt.xlabel('LastD1Season', fontsize=15); plt.ylabel('Counts', fontsize=15)\nplt.xticks(rotation=30);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"rate_of_LastD1Season = round(MTeams['LastD1Season'].value_counts().max() / MTeams.shape[0], 2)\nrate_of_LastD1Season = int(rate_of_LastD1Season*100)\nprint(f'{rate_of_LastD1Season}% of the teams remain until now')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## MSeasons"},{"metadata":{"trusted":true},"cell_type":"code","source":"MSeasons = dfs['Misc']['MSeasons']\nMSeasons.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MSeasons.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## MNCAATourneySeeds"},{"metadata":{"trusted":true},"cell_type":"code","source":"MNCAATourneySeeds = dfs['Misc']['MNCAATourneySeeds']\nMNCAATourneySeeds.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MNCAATourneySeeds.shape","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MNCAATourneySeeds['Seed'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## MRegularSeasonCompactResults"},{"metadata":{},"cell_type":"markdown","source":"This data is about the games before the selection sunday(`DayNum`==132). It is also known as pre-season tournament, a non-conference game, a regular conference game."},{"metadata":{},"cell_type":"markdown","source":" **NOTE**: In order to accomplish this uniqueness, we had to adjust one game's date. In March 2008, the SEC postseason tournament had to reschedule one game (Georgia-Kentucky) to a subsequent day because of a tornado, so Georgia had to actually play two games on the same day. In order to enforce this uniqueness, we moved the game date for the Georgia-Kentucky game back to its original scheduled date."},{"metadata":{"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults = dfs['Misc']['MRegularSeasonCompactResults']\nMRegularSeasonCompactResults.head()","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### MRegularSeasonCompactResults와 MTeams Merge\nAdd Winning team name and Losing team name on `MRegularSeasonCompactResults`"},{"metadata":{"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults = \\\n    MRegularSeasonCompactResults.merge(MTeams[['TeamID', 'TeamName']],\n                                      left_on='WTeamID',\n                                      right_on='TeamID',\n                                      validate='many_to_one').drop('TeamID', axis=1)\nMRegularSeasonCompactResults.rename(columns={'TeamName': 'WTeamName'}, inplace=True)\n\nMRegularSeasonCompactResults = \\\n    MRegularSeasonCompactResults.merge(MTeams[['TeamID', 'TeamName']],\n                                      left_on='LTeamID',\n                                      right_on='TeamID',\n                                      validate='many_to_one').drop('TeamID', axis=1)\nMRegularSeasonCompactResults.rename(columns={'TeamName': 'LTeamName'}, inplace=True)\n\nMRegularSeasonCompactResults.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Difference between Winning team and Losing team"},{"metadata":{"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults['ScoreDiff'] = MRegularSeasonCompactResults['WScore'] - MRegularSeasonCompactResults['LScore']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults['ScoreDiff'].plot(kind='hist',\n                                              bins=90,\n                                              figsize=(15,5))\nplt.title('Score Difference between WTeam and LTeam', fontsize=18);","execution_count":null,"outputs":[]},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"num_winning = MRegularSeasonCompactResults['WTeamName'].value_counts()\nnum_winning = num_winning.head(20)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### The team that won the most in Pre-Season"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12, 5))\ncounts = MRegularSeasonCompactResults['WTeamName'].value_counts().head(20)\nsns.barplot(y=counts.index, x=counts.values, color=second_color, orient='h')\n\nplt.title('Most Winning (pre-season) Teams', fontsize=18); plt.ylabel('Winning Teams', fontsize=15); plt.xlabel('Counts', fontsize=15)\nplt.xlim(600, 920);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### The team that won least in Pre-Season"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12, 5))\ncounts = MRegularSeasonCompactResults['WTeamName'].value_counts().tail(20)\nsns.barplot(y=counts.index, x=counts.values, color=base_color, orient='h')\n\nplt.title('Least Winning (pre-season) Teams', fontsize=18); plt.ylabel('Winning Teams', fontsize=15); plt.xlabel('Counts', fontsize=15)\nplt.xlim(0, 150);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### The team that losed most in Pre-Season"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12, 5))\ncounts = MRegularSeasonCompactResults['LTeamName'].value_counts().head(20)\nsns.barplot(y=counts.index, x=counts.values, color=third_color, orient='h')\n\nplt.title('Most Losing (pre-season) Teams', fontsize=18); plt.ylabel('Losing Teams', fontsize=15); plt.xlabel('Counts', fontsize=15)\nplt.xlim(600, 750);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Difference between number of home team winning and away team winning"},{"metadata":{"trusted":true},"cell_type":"code","source":"total_num_of_pre_game = MRegularSeasonCompactResults.shape[0]\n\nMRegularSeasonCompactResults['WLoc'].value_counts() / total_num_of_pre_game","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"You can see that the winning rate of the Home team is about twice as high as that of the Away team."},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults['NumOT'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MRegularSeasonCompactResults.groupby(['Season'])['WScore'].mean().plot()\nplt.title('Mean Scores of winning teams by season in regular plays', fontsize=18);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## MEvents"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Concatenate MEvents2015, 2016, 2017, 2018, 2019 together\nMEvents = pd.concat(dfs['MEvents'], axis=0, sort=False)\nMEvents.head()","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"MEvents.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Event type Counts"},{"metadata":{"scrolled":false,"trusted":true},"cell_type":"code","source":"plot_bar_chart(MEvents, 'EventType')\nplt.title('EventType Counts', fontsize=18); plt.xlabel('EventType', fontsize=15); plt.ylabel('Counts', fontsize=15)\nplt.xticks(rotation=30);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Area of Event"},{"metadata":{"trusted":true},"cell_type":"code","source":"area_mapping = {0: np.nan,\n                1: 'under basket',\n                2: 'in the paint',\n                3: 'inside right wing',\n                4: 'inside right',\n                5: 'inside center',\n                6: 'inside left',\n                7: 'inside left wing',\n                8: 'outside right wing',\n                9: 'outside right',\n                10: 'outside center',\n                11: 'outside left',\n                12: 'outside left wing',\n                13: 'backcourt'}\n\nMEvents['Area_Name'] = MEvents['Area'].map(area_mapping)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MEvents['counter'] = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_bar_chart(MEvents, 'EventType')\nplt.title('EventType Counts', fontsize=18); plt.xlabel('EventType', fontsize=15); plt.ylabel('Counts', fontsize=15)\nplt.xticks(rotation=30);","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(12, 5))\ncounts = MEvents.groupby('Area_Name')['counter'].sum().sort_values(ascending=False)\nsns.barplot(y=counts.index, x=counts.values, color=third_color, orient='h')\n\nplt.title('Events Area Counts', fontsize=18); plt.ylabel('Area Name', fontsize=15); plt.xlabel('Counts', fontsize=15);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Visualizing Event Area"},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(15, 8))\nfor area, df in MEvents.loc[~MEvents['Area_Name'].isna()].groupby('Area_Name'):\n    df.plot(x='X', y='Y', style='.', label=area, ax=ax, title='Visualizing Event Areas')\n    ax.legend()\nplt.legend(bbox_to_anchor=(1.03,1), loc=\"upper left\")\nax.set_xticks([])\nax.set_yticks([])\nax.set_xlabel('')\nax.set_xlim(0, 100)\nax.set_ylim(0, 100);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Normalizing X, Y Data\nThe coat is 50 feet wide and 94 feet long, so the X and Y data should be normalized."},{"metadata":{"trusted":true},"cell_type":"code","source":"MEvents['X_'] = (MEvents['X'] * (94/100))\nMEvents['Y_'] = (MEvents['Y'] * (50/100))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### NCAA Court Plot Function"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_ncaa_full_court(ax=None, three_line='mens', court_color='#edc993',\n                           lw=3, lines_color='black', lines_alpha=0.5,\n                           paint_fill='blue', paint_alpha=0.4):\n    \"\"\"\n    Creates NCAA Basketball\n    Dimensions are in feet (Court is 97x50 ft)\n    Created by: Rob Mulla / https://github.com/RobMulla\n\n    * Note that this function uses \"feet\" as the unit of measure.\n    * NCAA Data is provided on a x range: 0, 100 and y-range 0 to 100\n    * To plot X/Y positions first convert to feet like this:\n    ```\n    Events['X_'] = (Events['X'] * (94/100))\n    Events['Y_'] = (Events['Y'] * (50/100))\n    ```\n\n    three_line: 'mens', 'womens' or 'both' defines 3 point line plotted\n    court_color : (hex) Color of the court\n    lw : line width\n    lines_color : Color of the lines\n    paint_fill : Color inside the paint\n    paint_alpha : transparency of the \"paint\"\n    \"\"\"\n    if ax is None:\n        ax = plt.gca()\n\n    # Create Pathes for Court Lines\n    center_circle = Circle((94/2, 50/2), 6,\n                           linewidth=lw, color=lines_color, lw=lw,\n                           fill=False, alpha=lines_alpha)\n#     inside_circle = Circle((94/2, 50/2), 2,\n#                            linewidth=lw, color=lines_color, lw=lw,\n#                            fill=False, alpha=lines_alpha)\n\n    hoop_left = Circle((5.25, 50/2), 1.5 / 2,\n                       linewidth=lw, color=lines_color, lw=lw,\n                       fill=False, alpha=lines_alpha)\n    hoop_right = Circle((94-5.25, 50/2), 1.5 / 2,\n                        linewidth=lw, color=lines_color, lw=lw,\n                        fill=False, alpha=lines_alpha)\n\n    # Paint - 18 Feet 10 inches which converts to 18.833333 feet - gross!\n    left_paint = Rectangle((0, (50/2)-6), 18.833333, 12,\n                           fill=paint_fill, alpha=paint_alpha,\n                           lw=lw, edgecolor=None)\n    right_paint = Rectangle((94-18.83333, (50/2)-6), 18.833333,\n                            12, fill=paint_fill, alpha=paint_alpha,\n                            lw=lw, edgecolor=None)\n    \n    left_paint_boarder = Rectangle((0, (50/2)-6), 18.833333, 12,\n                           fill=False, alpha=lines_alpha,\n                           lw=lw, edgecolor=lines_color)\n    right_paint_boarder = Rectangle((94-18.83333, (50/2)-6), 18.833333,\n                            12, fill=False, alpha=lines_alpha,\n                            lw=lw, edgecolor=lines_color)\n\n    left_arc = Arc((18.833333, 50/2), 12, 12, theta1=-\n                   90, theta2=90, color=lines_color, lw=lw,\n                   alpha=lines_alpha)\n    right_arc = Arc((94-18.833333, 50/2), 12, 12, theta1=90,\n                    theta2=-90, color=lines_color, lw=lw,\n                    alpha=lines_alpha)\n    \n    leftblock1 = Rectangle((7, (50/2)-6-0.666), 1, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    leftblock2 = Rectangle((7, (50/2)+6), 1, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(leftblock1)\n    ax.add_patch(leftblock2)\n    \n    left_l1 = Rectangle((11, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    left_l2 = Rectangle((14, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    left_l3 = Rectangle((17, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(left_l1)\n    ax.add_patch(left_l2)\n    ax.add_patch(left_l3)\n    left_l4 = Rectangle((11, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    left_l5 = Rectangle((14, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    left_l6 = Rectangle((17, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(left_l4)\n    ax.add_patch(left_l5)\n    ax.add_patch(left_l6)\n    \n    rightblock1 = Rectangle((94-7-1, (50/2)-6-0.666), 1, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    rightblock2 = Rectangle((94-7-1, (50/2)+6), 1, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(rightblock1)\n    ax.add_patch(rightblock2)\n\n    right_l1 = Rectangle((94-11, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    right_l2 = Rectangle((94-14, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    right_l3 = Rectangle((94-17, (50/2)-6-0.666), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(right_l1)\n    ax.add_patch(right_l2)\n    ax.add_patch(right_l3)\n    right_l4 = Rectangle((94-11, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    right_l5 = Rectangle((94-14, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    right_l6 = Rectangle((94-17, (50/2)+6), 0.166, 0.666,\n                           fill=True, alpha=lines_alpha,\n                           lw=0, edgecolor=lines_color,\n                           facecolor=lines_color)\n    ax.add_patch(right_l4)\n    ax.add_patch(right_l5)\n    ax.add_patch(right_l6)\n    \n    # 3 Point Line\n    if (three_line == 'mens') | (three_line == 'both'):\n        # 22' 1.75\" distance to center of hoop\n        three_pt_left = Arc((6.25, 50/2), 44.291, 44.291, theta1=-78,\n                            theta2=78, color=lines_color, lw=lw,\n                            alpha=lines_alpha)\n        three_pt_right = Arc((94-6.25, 50/2), 44.291, 44.291,\n                             theta1=180-78, theta2=180+78,\n                             color=lines_color, lw=lw, alpha=lines_alpha)\n\n        # 4.25 feet max to sideline for mens\n        ax.plot((0, 11.25), (3.34, 3.34),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.plot((0, 11.25), (50-3.34, 50-3.34),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.plot((94-11.25, 94), (3.34, 3.34),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.plot((94-11.25, 94), (50-3.34, 50-3.34),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.add_patch(three_pt_left)\n        ax.add_patch(three_pt_right)\n\n    if (three_line == 'womens') | (three_line == 'both'):\n        # womens 3\n        three_pt_left_w = Arc((6.25, 50/2), 20.75 * 2, 20.75 * 2, theta1=-85,\n                              theta2=85, color=lines_color, lw=lw, alpha=lines_alpha)\n        three_pt_right_w = Arc((94-6.25, 50/2), 20.75 * 2, 20.75 * 2,\n                               theta1=180-85, theta2=180+85,\n                               color=lines_color, lw=lw, alpha=lines_alpha)\n\n        # 4.25 inches max to sideline for mens\n        ax.plot((0, 8.3), (4.25, 4.25), color=lines_color,\n                lw=lw, alpha=lines_alpha)\n        ax.plot((0, 8.3), (50-4.25, 50-4.25),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.plot((94-8.3, 94), (4.25, 4.25),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n        ax.plot((94-8.3, 94), (50-4.25, 50-4.25),\n                color=lines_color, lw=lw, alpha=lines_alpha)\n\n        ax.add_patch(three_pt_left_w)\n        ax.add_patch(three_pt_right_w)\n\n    # Add Patches\n    ax.add_patch(left_paint)\n    ax.add_patch(left_paint_boarder)\n    ax.add_patch(right_paint)\n    ax.add_patch(right_paint_boarder)\n    ax.add_patch(center_circle)\n#     ax.add_patch(inside_circle)\n    ax.add_patch(hoop_left)\n    ax.add_patch(hoop_right)\n    ax.add_patch(left_arc)\n    ax.add_patch(right_arc)\n\n    # Restricted Area Marker\n    restricted_left = Arc((6.25, 50/2), 8, 8, theta1=-90,\n                        theta2=90, color=lines_color, lw=lw,\n                        alpha=lines_alpha)\n    restricted_right = Arc((94-6.25, 50/2), 8, 8,\n                         theta1=180-90, theta2=180+90,\n                         color=lines_color, lw=lw, alpha=lines_alpha)\n    ax.add_patch(restricted_left)\n    ax.add_patch(restricted_right)\n    \n    # Backboards\n    ax.plot((4, 4), ((50/2) - 3, (50/2) + 3),\n            color=lines_color, lw=lw*1.5, alpha=lines_alpha)\n    ax.plot((94-4, 94-4), ((50/2) - 3, (50/2) + 3),\n            color=lines_color, lw=lw*1.5, alpha=lines_alpha)\n    ax.plot((4, 4.6), (50/2, 50/2), color=lines_color,\n            lw=lw, alpha=lines_alpha)\n    ax.plot((94-4, 94-4.6), (50/2, 50/2),\n            color=lines_color, lw=lw, alpha=lines_alpha)\n\n    # Half Court Line\n    ax.axvline(94/2, color=lines_color, lw=lw, alpha=lines_alpha)\n\n    # Boarder\n    boarder = Rectangle((0.3,0.3), 94-0.6, 50-0.6, fill=False, lw=3, color='black', alpha=lines_alpha)\n    ax.add_patch(boarder)\n    \n    # Plot Limit\n    ax.set_xlim(0, 94)\n    ax.set_ylim(0, 50)\n    ax.set_facecolor(court_color)\n    ax.set_xticks([])\n    ax.set_yticks([])\n    ax.set_xlabel('')\n    return ax","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(15, 8.5))\ncreate_ncaa_full_court(ax, three_line='both', paint_alpha=0.2);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Turnover locations"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(15, 7.5))\nmarker_size = 10\nax = create_ncaa_full_court(ax, paint_alpha=0.15)\nMEvents.loc[MEvents['EventType'] == 'turnover'].plot(x='X_',\n                                                    y='Y_',\n                                                    style='X',\n                                                    c='red',\n                                                    alpha=0.3,\n                                                    markersize=marker_size,\n                                                    ax=ax)\nax.set_title('Turnover Locations', fontsize=18)\nax.set_xlabel('')\nax.get_legend().remove();","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_of_total_rows = MEvents.loc[MEvents['EventType'] == 'turnover'].shape[0]\nnum_of_total_rows","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"turnover = MEvents.loc[MEvents['EventType'] == 'turnover']\nnum_of_not_zero_X_rows = turnover.loc[turnover['X_'] != 0].shape[0]\nnum_of_not_zero_X_rows","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"print(f'총 {num_of_total_rows}개의 rows가 있지만 {num_of_not_zero_X_rows}개만이 0이 아닌 X_를 가지고 있어, plot된 점이 적습니다.')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Location that 3-points shot made"},{"metadata":{"trusted":true},"cell_type":"code","source":"matplotlib.rcParams['agg.path.chunksize']=100000\n\nif DEBUG:\n    alpha = 0.4\n    style = 'X'\nelse:\n    alpha = 0.01\n    style = 'o'\n\nfig, ax = plt.subplots(figsize=(10, 5.5))\nax = create_ncaa_full_court(ax, paint_alpha=0.2)\nMEvents.loc[MEvents['EventType'] == 'made3'].plot(x='X_',\n                                                 y='Y_',\n                                                 marker=style,\n                                                 color='blue',\n                                                 alpha=alpha,\n                                                 ax=ax)\nax.set_title('3 Pointers Made', fontsize=18)\nax.set_xlabel('')\nax.get_legend().remove();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Location that 3-points shot missed"},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"fig2, ax2 = plt.subplots(figsize=(10, 5.5))\nax2 = create_ncaa_full_court(ax2, paint_alpha=0.2)\nMEvents.loc[MEvents['EventType']=='miss3'].plot(x='X_',\n                                                y='Y_',\n                                                marker=style,\n                                                color='red',\n                                                alpha=alpha,\n                                                ax=ax2)\nax2.set_title('3 Pointers Missed', fontsize=18)\nax2.set_xlabel('')\nax2.get_legend().remove();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Location that 2-points shot made"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig3, ax3 = plt.subplots(figsize=(10, 5.5))\nax3 = create_ncaa_full_court(ax3, paint_alpha=0.2)\nMEvents.loc[MEvents['EventType'] == 'made2'].plot(x='X_',\n                                                 y='Y_',\n                                                 marker=style,\n                                                 color='blue',\n                                                 alpha=alpha,\n                                                 ax=ax3)\nax3.set_title('2 Pointers Made', fontsize=18)\nax3.set_xlabel('')\nax3.get_legend().remove()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Location that 2-points shot missed"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(10, 5.5))\nax = create_ncaa_full_court(ax, paint_alpha=0.2)\nMEvents.loc[MEvents['EventType'] == 'miss2'].plot(x='X_',\n                                                 y='Y_',\n                                                 marker=style,\n                                                 color='red',\n                                                 alpha=alpha,\n                                                 ax=ax)\nax.set_title('2 Pointers Missed', fontsize=18)\nax.set_xlabel('')\nax.get_legend().remove();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## MPlayers"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Merge events and MPlayers\nMEvents = MEvents.merge(dfs['Misc']['MPlayers'],\n             how='left',\n             left_on = ['EventTeamID', 'EventPlayerID'],\n             right_on = ['TeamID', 'PlayerID'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MEvents.drop(['PlayerID', 'TeamID'], axis=1, inplace=True)\nMEvents.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"'LastName' and 'FirstName' combined well."},{"metadata":{},"cell_type":"markdown","source":"#### Full Name 만들기"},{"metadata":{"trusted":true},"cell_type":"code","source":"MEvents['FullName'] = MEvents['FirstName'] + ' ' + MEvents['LastName']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Plotting Specific Player's Made/Missed Shots"},{"metadata":{},"cell_type":"markdown","source":"Let's draw the location of the famous player's made and missed shots on the court."},{"metadata":{},"cell_type":"markdown","source":"#### Mamadi Diakite's 2 points Made/Missed"},{"metadata":{"trusted":true},"cell_type":"code","source":"marker_size = 15\n\nfirst_name = 'Mamadi'\nlast_name = 'Diakite'\n\nfig, ax = plt.subplots(figsize=(15, 8))\nax = create_ncaa_full_court(ax, paint_alpha=0.2)\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"made2\"') \\\n    .plot(x='X_', y='Y_', style='o', label='Made 2',\n         markersize=marker_size, ax=ax);\n\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"miss2\"') \\\n    .plot(x='X_', y='Y_', style='X', label='Missed 2',\n         color='red', markersize=marker_size, ax=ax);\nplt.legend(loc='lower center')\nplt.title('Mamadi Diakite Shots');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Kyle Guy's 2 points Made/Missed"},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"marker_size = 15\n\nfirst_name = 'Kyle'\nlast_name = 'Guy'\n\n# first_name = 'Zion'\n# last_name = 'Williamson'\n\nfig, ax = plt.subplots(figsize=(15, 8))\nax = create_ncaa_full_court(ax, paint_alpha=0.2)\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"made2\"') \\\n    .plot(x='X_', y='Y_', style='o', label='Made 2',\n         markersize=marker_size, ax=ax);\n\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"miss2\"') \\\n    .plot(x='X_', y='Y_', style='X', label='Missed 2',\n         color='red', markersize=marker_size, ax=ax);\nplt.legend(loc='lower center')\nplt.title('Kyle Guy Shots');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Aaron Henry's 3 points Made/Missed (One of the best 3-pointers)"},{"metadata":{"scrolled":true,"trusted":true},"cell_type":"code","source":"marker_size = 15\n\n# Best Shooting Guard\nfirst_name = 'Aaron'\nlast_name = 'Henry'\n\nfig, ax = plt.subplots(figsize=(15, 8))\nax = create_ncaa_full_court(ax, paint_alpha=0.2)\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"made3\"') \\\n    .plot(x='X_', y='Y_', style='o', label='Made 3',\n         markersize=marker_size, ax=ax);\n\nMEvents.query('FirstName == @first_name and LastName == @last_name and EventType == \"miss3\"') \\\n    .plot(x='X_', y='Y_', style='X', label='Missed 3',\n         color='red', markersize=marker_size, ax=ax);\nplt.legend(loc='lower center')\nplt.title('Kyle Guy Shots');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Shot Heatmap"},{"metadata":{},"cell_type":"markdown","source":"#### Plot the heatmap about the number of shots tried (including shot made and missed)"},{"metadata":{"trusted":true},"cell_type":"code","source":"N_bins=100\nshot_events = MEvents.loc[MEvents['EventType'].isin(['miss3','made3','miss2','made2']) & (MEvents['X_'] != 0)]\nfig, ax = plt.subplots(figsize=(15, 7))\nax = create_ncaa_full_court(ax=ax,\n                            paint_alpha=0.0,\n                            court_color='black',\n                            lines_color='white')\nplt.hist2d(shot_events['X_'].values, \n           shot_events['Y_'].values,\n           bins=N_bins, norm=matplotlib.colors.LogNorm(),\n           cmap='plasma')\n\n# Plot a colorbar with label.\ncb = plt.colorbar()\ncb.set_label('Numer of Shots')\nax.set_title('Shot Heatmap', fontsize=18);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Reference: \n- https://www.kaggle.com/robikscube/2020-march-madness-data-first-look-eda"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.3"}},"nbformat":4,"nbformat_minor":1}