def get_player_shot_chart_info(player_name, season_id, season_type): # Searching for requested player all_nba_players = players.get_players() player_dict = [ player for player in all_nba_players if player['full_name'] == player_name ][0] # Creating the dataframe for the player's career career = playercareerstats.PlayerCareerStats(player_id=player_dict['id']) career_df = career.get_data_frames()[0] # Finding the team that the player played for during the season team_id = career_df[career_df['SEASON_ID'] == season_id]['TEAM_ID'] # Endpoints to acquire the shot chart detail shot_chart = shotchartdetail.ShotChartDetail( team_id=int(team_id), player_id=int(player_dict['id']), season_type_all_star=season_type, season_nullable=season_id, context_measure_simple="FGA").get_data_frames() return shot_chart[0]
def get_shot_detail_data(player_id): if player_id: shot = shotchartdetail.ShotChartDetail( team_id='0', player_id=player_id, context_measure_simple='FGA').get_data_frames()[0] shot = shot[shot.LOC_Y <= 417] shot = hexagonify(shot.copy()) shot['min_left'] = shot['SECONDS_REMAINING'] / 60 + shot[ 'MINUTES_REMAINING'] shot['year'] = shot['GAME_DATE'].map(lambda x: int(x[:4])) else: shot = pd.DataFrame.from_dict({ 'EVENT_TYPE': ['Made Shot', 'Missed Shot'], 'LOC_X': [1000, 1000], 'LOC_Y': [1000, 1000], 'SHOT_ATTEMPTED_FLAG': [0, 0], 'SHOT_MADE_FLAG': [0, 0], 'x': [0, 0], 'y': [0, 0], 'min_left': [0, 0], 'year': [0, 0], 'SHOT_ZONE_BASIC': ['', ''], 'SHOT_ZONE_AREA': ['', ''], 'ACTION_TYPE': ['', ''], }) return shot
def get_player_shot_info(self, player_id, team_id, num_games): """Match player id to shot chart information. :param int player_id: Player ID that is associated with player user provided. :param int team_id: Team ID that is associated with the player user provided. :param int num_games: Indicate length of shot info to acquire. :returns DataFrame :rtype pandas.DataFrame """ try: current_shot_chart_info = shotchartdetail.ShotChartDetail( league_id='00', season_type_all_star='Regular Season', team_id=team_id, player_id=player_id, last_n_games=num_games) except requests.exceptions.ConnectionError: print("Request failed.") else: shots = current_shot_chart_info.shot_chart_detail.data['data'] headers = current_shot_chart_info.shot_chart_detail.data['headers'] shot_df = pandas.DataFrame(shots, columns=headers) return shot_df
def get_league_average_shot_data(): shot_json = shotchartdetail.ShotChartDetail( team_id=0, player_id=0, context_measure_simple='FGA', season_nullable='2020-21', season_type_all_star='Regular Season') shot_data = json.loads(shot_json.get_json()) la_relevant_data = shot_data['resultSets'][1] la_headers = la_relevant_data['headers'] la_rows = la_relevant_data['rowSet'] league_average_df = pd.DataFrame(la_rows) league_average_df.columns = la_headers league_average_zones_df = league_average_df.groupby('SHOT_ZONE_BASIC').agg( { 'FGM': 'sum', 'FGA': 'sum' }) league_average_zones_df['fg%'] = ( (league_average_zones_df['FGM'] / league_average_zones_df['FGA']) * 100).round(2).astype(str) + '%' league_average_zones_df['freq%'] = ( (league_average_zones_df['FGA'] / league_average_zones_df['FGA'].sum()) * 100).round(2).astype(str) + '%' return league_average_zones_df
def get_player_shotchartdetail(player_name, season_id, season_type): #player dictionary nba_players = players.get_players() player_dict = [ player for player in nba_players if player['full_name'] == player_name ] if len(player_dict) == 0: return None, None #career dataframe career = playercareerstats.PlayerCareerStats( player_id=player_dict[0]['id']) career_df = json.loads(career.get_json())['resultSets'][0]['rowSet'] #team id during the season team_ids = [ season[3] for season in career_df if season[1] == season_id ] #st.write(career_df[0]) shots = [] for team_id in team_ids: shotchartlist = shotchartdetail.ShotChartDetail( team_id=int(team_id), player_id=int(player_dict[0]['id']), season_type_all_star=season_type, season_nullable=season_id, context_measure_simple="FGA").get_data_frames() shots.extend(shotchartlist) return shotchartlist[0], shotchartlist[1]
def create_shot_chart(pid, tid, name): career = shotchartdetail.ShotChartDetail(team_id=tid, player_id=pid, headers=headers) shots = career.get_data_frames()[0] cmap = plt.cm.get_cmap('gist_heat_r') joint_shot_chart = sns.jointplot(shots.LOC_X, shots.LOC_Y, stat_func=None, kind='hex', space=0, color=cmap(.2), cmap=cmap, gridsize=26, height=8) joint_shot_chart.fig.set_size_inches(12, 11) ax = joint_shot_chart.ax_joint fig = joint_shot_chart.fig ax.set_xlim(-235, 235) ax.set_ylim(295, -20) ax.set_xlabel('') ax.set_ylabel('') ax.tick_params(labelbottom='off', labelleft='off') ax.set_title('{} FGA, 2018-2019 Regular Season'.format(name), y=1.2) return create_court(ax, fig=fig)
def get_player_shots_data(player_full_name): pd.set_option("display.max_rows", None) nba_players = players.get_players() try: current_player = [ player for player in nba_players if player["full_name"] == player_full_name ][0] except: return "Player not found." if not os.path.isdir( str(os.path.dirname(os.path.abspath(__file__))) + "/../data/" + str(current_player["id"]) + "/"): try: os.makedirs(str(os.path.dirname(os.path.abspath(__file__))) + "/../data/" + str(current_player["id"]) + "/", mode=0o777, exist_ok=True) except OSError as error: print(error) player = commonplayerinfo.CommonPlayerInfo( player_id=str(current_player["id"])) player_df = player.get_data_frames()[0] player_df = player_df.loc[:, [ "FIRST_NAME", "LAST_NAME", "COUNTRY", "HEIGHT", "WEIGHT", "JERSEY", "POSITION", "TEAM_ABBREVIATION", "FROM_YEAR", "TO_YEAR" ]] player_df.to_json(str(os.path.dirname(os.path.abspath(__file__))) + '/../data/' + str(current_player["id"]) + '/player_data.json', orient='records') shots = shotchartdetail.ShotChartDetail(team_id=0, player_id=str( current_player["id"]), context_measure_simple='FGA') shots_df = shots.get_data_frames()[0] shots_df = shots_df.loc[:, [ "TEAM_NAME", "PERIOD", "MINUTES_REMAINING", "SECONDS_REMAINING", "ACTION_TYPE", "SHOT_TYPE", "SHOT_DISTANCE", "LOC_X", "LOC_Y", "SHOT_MADE_FLAG", "GAME_DATE", "HTM", "VTM" ]] shots_distances = [] for i in range(shots_df.shape[0]): shots_distances += [ (shots_df.at[i, "LOC_X"]**2 + shots_df.at[i, "LOC_Y"]**2)**0.5 / 10 ] shots_df.drop(["SHOT_DISTANCE"], axis=1, inplace=True) shots_df.insert(5, "SHOT_DISTANCE", shots_distances, True) shots_angles = [] for i in range(shots_df.shape[0]): shots_angles += [shots_df.at[i, "LOC_Y"] / shots_df.at[i, "LOC_X"]] shots_df.insert(5, "SHOT_ANGLE", shots_angles, True) shots_df.drop(["LOC_X", "LOC_Y"], axis=1, inplace=True) shots_df.to_json(str(os.path.dirname(os.path.abspath(__file__))) + '/../data/' + str(current_player["id"]) + '/shots_data.json', orient='records') return "Player found and data added to database."
def get_team_shotchartdetail(team_id, season_id, season_type): # shotchartdetail endpoint shotchartlist = shotchartdetail.ShotChartDetail(team_id=int(team_id), player_id=0, season_type_all_star=season_type, season_nullable=season_id, context_measure_simple="FGA").get_data_frames() return shotchartlist[0], shotchartlist[1]
def build_basic_shotchart(the_player, season, season_type): player_name = players.find_player_by_id(the_player).get('full_name') response = shotchartdetail.ShotChartDetail( team_id=0, player_id=the_player, season_nullable=season, season_type_all_star=season_type, context_measure_simple='FGA') df = response.get_data_frames()[0] made_shots = df[df['SHOT_MADE_FLAG'] == 1] missed_shots = df[df['SHOT_MADE_FLAG'] == 0] fig = go.Figure() fig.add_trace( go.Scatter( # made shots x=made_shots['LOC_X'], y=made_shots['LOC_Y'], mode='markers', name='Made Shot', hoverinfo='skip', marker=dict( size=5, cmax=40, cmin=-40, color="#008000", ), )) fig.add_trace( go.Scatter( # missed shots x=missed_shots['LOC_X'], y=missed_shots['LOC_Y'], mode='markers', name='Missed Shot', hoverinfo='skip', marker=dict( size=5, cmax=40, cmin=-40, color="#FF0000", ), )) draw_court(fig) fig.update_layout(title={ 'text': player_name + " , " + str(season), 'y': 1, 'x': 0.42, 'xanchor': 'center', 'yanchor': 'top' }, xaxis_title='Basic Shot Chart', font=dict(family="Rockwell", size=15, color="#000000"), dragmode=False) return fig
def get_player_shotchartdetail(player, season_id, season_type): # career df career_df = playercareerstats.PlayerCareerStats( player_id=player).get_data_frames()[0] # team id during the season team_id = career_df[career_df['SEASON_ID'] == season_id]['TEAM_ID'] # shotchardtdetail endpoint shotchartlist = shotchartdetail.ShotChartDetail( team_id=int(team_id), player_id=int(player), season_type_all_star=season_type, season_nullable=season_id, context_measure_simple="FGA").get_data_frames() return shotchartlist[0], shotchartlist[1]
def get_team_shot_data(df, team_id, game_id): shot_json = shotchartdetail.ShotChartDetail( team_id=team_id, player_id=0, game_id_nullable=game_id, context_measure_simple='FGA', season_nullable='2020-21', season_type_all_star='Regular Season') shot_data = json.loads(shot_json.get_json()) relevant_data = shot_data['resultSets'][0] headers = relevant_data['headers'] rows = relevant_data['rowSet'] shots_df = pd.DataFrame(rows) shots_df.columns = headers return shots_df
def scrape_shots_by_player_id(id): response = shotchartdetail.ShotChartDetail( team_id=0, player_id=id, season_nullable='2020-21', season_type_all_star='Regular Season') response_json = response.get_json() data = json.loads(response_json) shot_list = data["resultSets"][0]["rowSet"] for shot in shot_list: new_shot = Shot(nba_player_id=shot[3], x=shot[17] + 250, y=shot[18] + 60, shot_zone=f'{shot[13]} - {shot[14]}', shot_made_flag=shot[20]) db.session.add(new_shot) db.session.commit() db.session.flush()
def scrape_shots_by_player_id(id): response = shotchartdetail.ShotChartDetail( team_id=0, player_id=id, season_nullable='2020-21', season_type_all_star='Regular Season', timeout=None ) response_json = response.get_json() directory = 'app/player_shot_data' file = f"{id}.txt" if os.path.isdir(directory): path = os.path.join(directory, file) text_file = open(f"{path}", "w") text_file.write(f"{response_json}") text_file.close() else: directory = os.mkdir('app/player_shot_data') path = os.path.join(directory, file) text_file = open(f"{directory}/{id}.txt", "w") text_file.write(f"{response_json}") text_file.close()
def get_player_shotchartdetail(player_name, season_id, season_progress): # player dictionary nba_players = players.get_players() player_dict = [player for player in nba_players if player['full_name'] == player_name][0] # career dataframe career = playercareerstats.PlayerCareerStats(player_id=player_dict['id']) career_df = career.get_data_frames()[0] # team id during the season team_id = career_df[career_df['SEASON_ID'] == season_id]['TEAM_ID'] # shotchartdetail endpoints shotchartlist = shotchartdetail.ShotChartDetail(team_id=int(team_id), player_id=int(player_dict['id']), season_type_all_star=season_progress, season_nullable=season_id, context_measure_simple='FGA').get_data_frames() return shotchartlist[0], shotchartlist[1]
def getJSON(self): print('Gathering JSON . . .') playerJSON = shotchartdetail.ShotChartDetail( team_id = self.teamId, player_id = self.playerId, context_measure_simple = self.metric, season_nullable = self.season, season_type_all_star = self.type ) playerData = json.loads(playerJSON.get_json()) playerData = playerData['resultSets'][0] self.headers = playerData['headers'] self.rows = playerData['rowSet'] self.df = pd.DataFrame(self.rows) self.df.columns = self.headers self.chart()
# Get player ID def get_player_id(first, last): first = first.lower() last = last.lower() for p in players: if p['firstName'].lower() == first and p['lastName'].lower() == last: return p['playerId'] return -1 # JSON request for 2020 Kuz shot_json = shotchartdetail.ShotChartDetail( team_id=get_team_id('los angeles lakers'), player_id=get_player_id('kyle', 'kuzma'), context_measure_simple='FGA', season_nullable='2019-20', season_type_all_star='Regular Season') # Converting data into dictionary, getting relevant data shot_data = json.loads(shot_json.get_json()) relevant_data = shot_data['resultSets'][0] headers = relevant_data['headers'] rows = relevant_data['rowSet'] # Create pandas data frame kuz_data = pd.DataFrame(rows) kuz_data.columns = headers # Drawing basketball court
#Clean and join with top 40 roles = df.iloc[1:] roles = roles[['Name', 'Offensive Archetype', 'Defensive Role']] final = pd.merge(fin, roles, how='left', left_on='Name', right_on='Name') # In[ ]: #Building Mitchell Robinson shot chart: web scrape through NBA stats API from nba_api.stats.endpoints import shotchartdetail import simplejson as json response = shotchartdetail.ShotChartDetail(team_id=0,player_id=1629011,season_nullable='2019-20',season_type_all_star='Regular Season') content = json.loads(response.get_json()) # In[ ]: #Set JSON as DataFrame results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] mitch = pd.DataFrame(rows) mitch.columns = headers #Write to csv file mitch.to_csv('~/Desktop/mitch.csv', index=False)
from nba_api.stats.endpoints import shotchartdetail import json import requests import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib.patches import Circle, Rectangle, Arc from matplotlib.offsetbox import OffsetImage import urllib.request #find the id matching team you want at https://github.com/bttmly/nba/blob/master/data/teams.json #find the id of player on nba.stats.com response = shotchartdetail.ShotChartDetail( team_id=1610612749, player_id=203507, season_nullable='2020-21', season_type_all_star='Regular Season') content = json.loads(response.get_json()) #transform content into dataframe results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] df = pd.DataFrame(rows) df.columns = headers #write to csv file df.to_csv("giannis.csv", index=False) sns.set_style("white")
from nba_api.stats.endpoints import shotchartdetail import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import os from court import draw_court pd.set_option('display.max_rows', None) player = shotchartdetail.ShotChartDetail(player_id='1628366', team_id='1610612740') table = player.get_data_frames()[0] #print(table.LOC_X) sns.set_style("white") sns.set_color_codes() # plt.figure(figsize=(12,11)) # draw_court(outer_lines=True) # plt.scatter(table.LOC_X, table.LOC_Y,s=10) # plt.xlim(300,-300) # plt.ylim(-100,500) # plt.show() cmap = plt.cm.gist_heat_r joint_chart = sns.jointplot(table.LOC_X, table.LOC_Y, stat_func=None, kind='hex', space=0, color=cmap(0.2), cmap=cmap) joint_chart.fig.set_size_inches(12, 11)
restricted_list = [] restricted_player_list = [] paint_list = [] paint_player_list = [] for player_roster in roster: name = player_roster #print('\n\n', name, '\n\n') playerid = get_playerid(name) response = shotchartdetail.ShotChartDetail( team_id=0, player_id=playerid, context_measure_simple='FGA', # FGA/FG3A are made & missed #season_type_all_star = 'Regular Season', season_nullable='2020-21' #period = '4', ) content = json.loads(response.get_json()) # transform contents into dataframe results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] fg_attempt = pd.DataFrame(rows) fg_attempt.columns = headers # all field goal attempts fg_attempt['LOC_X'] = -1 * fg_attempt['LOC_X']
def make_chart(request): if request.method == 'GET': date = datetime.datetime.today().strftime('%m-%d-%Y') response = {} plt.clf() teamID = '0' theme = request.GET['theme'] #type = request.GET['type'] seasonType = request.GET['seasonType'] playerID = request.GET['playerID'] season = request.GET['season'] #gameID = request.GET['gameID'] info = shotchartdetail.ShotChartDetail( player_id=playerID, team_id=teamID, season_type_all_star=seasonType, season_nullable=season, context_measure_simple='FG_PCT', ) info = info.get_json() shotChartData = json.loads(info) shots = shotChartData['resultSets'][0]['rowSet'] shotHeaders = shotChartData['resultSets'][0]['headers'] avg = shotChartData['resultSets'][1]['rowSet'] avgHeaders = shotChartData['resultSets'][1]['headers'] if (shots): shot_df = pd.DataFrame(shots, columns=shotHeaders) la_df = pd.DataFrame(avg, columns=avgHeaders) fig = plt.figure(figsize=(12, 10)) plot = nba.plot.grantland_shotchart(shotchart=shot_df, leagueaverage=la_df, season=season, seasonType=seasonType) plt.text(0, -8, 'data by: stats.nba.com ' + date, fontsize=7, horizontalalignment='center', verticalalignment='center') plt.text(0, -9, 'chart by: ballviz.com', fontsize=7, horizontalalignment='center', verticalalignment='center') stringIObytes = io.BytesIO() plt.savefig(stringIObytes, format='png', bbox_inches='tight', pad_inches=0.1, dpi=300) stringIObytes.seek(0) base64_data = base64.b64encode(stringIObytes.read()) base64_data = base64_data.decode("utf8") response = {'dataFound': True, 'imageData': base64_data} else: response = {'dataFound': False, 'imageData': ''} response = json.dumps(response) return HttpResponse(response) # Sending a success response else: return HttpResponse("Request method is not a GET")
logo_team = 'MIL' logo_url = "https://d2p3bygnnzw9w3.cloudfront.net/req/202001161/tlogo/bbr/" + logo_team + ".png" team_pic = urllib.request.urlretrieve(logo_url) team_logo = plt.imread(team_pic[0]) def get_player_id(first, last): for player in players: if player['firstName'] == first and player['lastName'] == last: return player['playerId'] return -1 shot_json = shotchartdetail.ShotChartDetail( team_id=get_team_id(f'{selected_team}'), player_id=get_player_id(f'{name}', f'{lastname}'), context_measure_simple='PTS', season_nullable='2018-19', season_type_all_star='Regular Season') shot_data = json.loads(shot_json.get_json()) relevant_data = shot_data['resultSets'][0] headers = relevant_data['headers'] shots = relevant_data['rowSet'] # Create pandas DataFrame player_data = pd.DataFrame(shots) player_data.columns = headers def create_court(ax, color):
import numpy as np import pandas as pd from matplotlib import pyplot import json # import nba_api from nba_api.stats.endpoints import shotchartdetail from nba_api.stats.static import teams, players l = players.find_players_by_first_name("LeBron") print(l) z = teams.find_teams_by_nickname("LAL") print(z) res = shotchartdetail.ShotChartDetail(0, 2544) content = json.loads(res.get_json()) results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] df = pd.DataFrame(rows) df.columns = headers df.to_csv("f.csv", index=False) custom_headers = { 'Host': 'stats.nba.com', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0',
'SHOT_ZONE_BASIC','SHOT_ZONE_AREA','SHOT_ZONE_RANGE','SHOT_DISTANCE', 'LOC_X','LOC_Y','SHOT_MADE_FLAG','HTM','VTM'] First = True # For each season for Season in Seasons: # For each team for ID in TeamIDs: # We'll grab the shot chart data for the team, extract the relevant # columns from the dataframe, then append the most recently retrieved # data onto the running dataframe. if First: First = False NBAShots = shotchartdetail.ShotChartDetail(team_id = ID, player_id = 0, season_nullable = Season, context_measure_simple = 'FGA') if len(NBAShots.get_data_frames()[0]) != 0: NBAShots_DF = [df for df in NBAShots.get_data_frames() if df['GRID_TYPE'][0] == 'Shot Chart Detail'][0][Columns].copy() NBAShots_DF['Season'] = Season del NBAShots else: First = True else: Temp = shotchartdetail.ShotChartDetail(team_id = ID, player_id = 0, season_nullable = Season, context_measure_simple = 'FGA') if len(Temp.get_data_frames()[0]) != 0: Temp_DF = [df for df in Temp.get_data_frames() if df['GRID_TYPE'][0] == 'Shot Chart Detail'][0][Columns].copy() Temp_DF['Season'] = Season
import numpy as np import pandas as pd import json #import nba api from nba_api.stats.endpoints import leaguegamefinder from nba_api.stats.endpoints import shotchartdetail from nba_api.stats.static import teams, players nba_teams = teams.get_teams() gsw = [team for team in nba_teams if team['abbreviation'] == 'GSW'][0] gsw_id = gsw['id'] gamefinder = leaguegamefinder.LeagueGameFinder(team_id_nullable=gsw_id) games = gamefinder.get_data_frames()[0] games.head() gsw_shotchart = shotchartdetail.ShotChartDetail(team_id=gsw_id, player_id=0, season_nullable="2017-18") gsw_shotchart_json = json.loads(gsw_shotchart.get_json()) results = gsw_shotchart_json['resultSets'][0] headers = results['headers'] rows = results['rowSet'] df = pd.DataFrame(rows) df.columns = headers df.to_csv("gsw.csv", index=None)
def fg_dist(player_or_teams, plot_flag = 0, fg_attempt_filter = 100): current_players_id_list, current_players_list = CommonAllPlayers_func.create_currentplayers_lists(teams = player_or_teams) if current_players_list == []: current_players_list = [player_or_teams] players_filtered_list = [] furthest_makes_list = [] avg_makes_list = [] fg_make_shotdist_list = [] # fig_box, ax_box = plt.subplots() for name in current_players_list: playerid = CommonAllPlayers_func.get_playerid(name) response = shotchartdetail.ShotChartDetail( team_id = 0, player_id = playerid, context_measure_simple = 'FGA', # FGA/FG3A are made & missed #season_type_all_star = 'Regular Season', season_nullable = '2020-21' #period = '4', ) time.sleep(0.1) content = json.loads(response.get_json()) # transform contents into dataframe results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] fg_attempt = pd.DataFrame(rows) if fg_attempt.empty == False and fg_attempt.shape[0] >= fg_attempt_filter: fg_attempt.columns = headers # all field goal attempts fg_attempt['LOC_X'] = -1 * fg_attempt['LOC_X'] fg_attempt['shot_dist'] = ((fg_attempt['LOC_X'] ** 2 + fg_attempt['LOC_Y'] ** 2) ** 0.5) / (5 / 6 * 12) # all successful field goals fg_make = fg_attempt.loc[fg_attempt['SHOT_MADE_FLAG'] == 1] fg_make_shotdist_list.append(fg_make['shot_dist'].tolist()) # all unsuccessful field goals fg_miss = fg_attempt.loc[fg_attempt['SHOT_MADE_FLAG'] == 0] furthest_make_ft = fg_make['shot_dist'].max() #/ (5 / 6 * 12) avg_make_ft = fg_make['shot_dist'].mean() #/ (5 / 6 * 12) players_filtered_list.append(name) furthest_makes_list.append(furthest_make_ft) avg_makes_list.append(avg_make_ft) # if plot_flag == 1: # plt.boxplot(fg_make['shot_dist']) # plt.pause(0.05) else: continue if plot_flag == 1: fig_box, ax_box = plt.subplots() plt.boxplot(x = fg_make_shotdist_list, whis = (0, 100)) corner3_dist = 22 arc3_dist = 23.75 #plt.axhline(corner3_dist) plt.axhline(arc3_dist) ax_box.set_xticklabels(players_filtered_list) plt.xticks(rotation = 20) plt.title('FG Distance [ft], ' + player_or_teams) #ax_box.legend('Arc 3 Point Line') plt.show() shot_range_df = pd.DataFrame(list(zip(players_filtered_list, furthest_makes_list, avg_makes_list)), columns = ['Player', 'Furthest FG', 'Average Distance FG']) shot_range_df.sort_values(by = ['Average Distance FG'], inplace = True) # if plot_flag == 1: # fig_bar, ax_bar = plt.subplots() # #plt.bar(shot_range_df['Player'], shot_range_df['Average Distance FG']) # plt.boxplot(shot_range_df['Average Distance FG']) # plt.show() return shot_range_df
def compute_league_averages(zone, x): area = zone[0] # print("The area is " + area) dict = { '(R)': 'Right Side(R)', '(C)': 'Center(C)', '(L)': 'Left Side(L)', '(RC)': 'Right Side Center(RC)', '(LC)': 'Left Side Center(LC)' } side = dict[zone[1]] filenames = { ('Right Corner 3', 'Right Side(R)'): 'rightcorner3.txt', ('Left Corner 3', 'Left Side(L)'): 'leftcorner3.txt', ('Mid-Range', 'Left Side(L)'): 'midrangeleft.txt', ('Mid-Range', 'Left Side Center(LC)'): 'midrangeleftcenter.txt', ('Mid-Range', 'Center(C)'): 'midrangecenter.txt', ('Mid-Range', 'Right Side Center(RC)'): 'midrangerightcenter.txt', ('Mid-Range', 'Right Side(R)'): 'midrangeright.txt', ('Above the Break 3', 'Left Side Center(LC)'): 'abovethebreak3leftcenter.txt', ('Above the Break 3', 'Center(C)'): 'abovethebreak3center.txt', ('Above the Break 3', 'Right Side Center(RC)'): 'abovethebreak3rightcenter.txt', ('Restricted Area', 'Center(C)'): 'restrictedareacenter.txt', ('In The Paint (Non-RA)', 'Right Side(R)'): 'inthepaintright.txt', ('In The Paint (Non-RA)', 'Center(C)'): 'inthepaintcenter.txt', ('In The Paint (Non-RA)', 'Left Side(L)'): 'inthepaintleft.txt' } input_list = [area, side] filename = filenames[tuple(input_list)] # print("The side is " + side) total_makes = 0 total_shots = 0 for player in players[x:x + 1]: # print(player['']) team_id = player['teamId'] player_id = player['playerId'] context_measure_simple = 'FGA' season_nullable = '2020-21' season_type_all_start = 'Regular Season' # print("TEAM ID: " + str(team_id)) # print("PLAYER ID: " + str(player_id)) # print("CONTEXT MEASURE SIMPLE: " + context_measure_simple) # print("SEASON NUMBER: " + season_nullable) # print("SEASON TYPE: " + season_type_all_start) player_shot_json = shotchartdetail.ShotChartDetail( team_id=team_id, player_id=player_id, context_measure_simple=context_measure_simple, season_nullable=season_nullable, season_type_all_star=season_type_all_start) player_shot_data = json.loads(player_shot_json.get_json()) player_relevant_data = player_shot_data['resultSets'][0] headers = player_relevant_data['headers'] rows = player_relevant_data['rowSet'] player_data = pd.DataFrame(rows) # print(player_data.head()) # print(player_data.columns) if (player_data.shape[0] != 0): player_data.columns = headers # print(player_data.head()) # print(player_data.columns) #player_data.to_csv('lameloballbefore.csv', index=False) player_data = player_data.loc[ (player_data['SHOT_ZONE_BASIC'] == area) & (player_data['SHOT_ZONE_AREA'] == side)] #player_data.to_csv('lameloball.csv', index=False) total_shots += player_data.shape[0] total_makes += player_data["SHOT_MADE_FLAG"].sum() file = open(filename, 'a') res = str(total_makes) + ' ' + str(total_shots) + '\n' file.write(res) file.close()
from nba_api.stats.endpoints import shotchartdetail import pandas as pd import json import pandas as pd import plotly.graph_objs as go from kawhi_shot import court_shapes response = shotchartdetail.ShotChartDetail( team_id=0, player_id=201142, season_nullable='2020-21', season_type_all_star='Regular Season' ) kd_data = json.loads(response.get_json()) # transform the JSON into Pandas dataframe results = kd_data['resultSets'][0] headers = results['headers'] rows = results['rowSet'] kd_df = pd.DataFrame(rows) kd_df.columns = headers # write new dataframe to csv file kd_df.to_csv(r'/home/aram/Downloads/kd.csv', index=False) kd_df = pd.read_csv('/home/aram/Downloads/kd.csv', encoding='Latin-1') trace_shot = go.Scatter( x = kd_df['LOC_X'], y = kd_df['LOC_Y'], mode = 'markers',
def player_shotchart(player, season = 0, fg_type = 'FGA', season_type = 'Regular Season', period = 0, plot_flag = 1, twitter_flag = 1, bin_edge_count = 15, plot_fg = 'all', savefig_flag = 0): # start timer start_time = time.time() # import pickled dictionaries league_make_bybin = pickle.load(open('playermake_2003-04.pkl', 'rb')) league_attempt_bybin = pickle.load(open('playerattempt_2003-04.pkl', 'rb')) league_make_sum_bybin = np.zeros([bin_edge_count, bin_edge_count]) league_attempt_sum_bybin = np.zeros([bin_edge_count, bin_edge_count]) for key in league_make_bybin: league_make_sum_bybin = np.add(league_make_sum_bybin, league_make_bybin[key]) league_attempt_sum_bybin = np.add(league_attempt_sum_bybin, league_attempt_bybin[key]) league_avg_eff_bybin = np.divide(league_make_sum_bybin, league_attempt_sum_bybin) # print title print('--------------------\n', player[0], '\n', season, '\n--------------------', '\n\n', sep = '') # get player ID from name input playerid = get_playerid(player) # retrieve data response = shotchartdetail.ShotChartDetail( context_measure_simple = 'FGA', period = period, player_id = playerid, season_type_all_star = season_type, team_id = 0, season_nullable = season) content = json.loads(response.get_json()) # transform contents into dataframe results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] fg_attempt = pd.DataFrame(rows) fg_attempt.columns = headers # mirror x, NBA's data is reversed fg_attempt['LOC_X'] = -1 * fg_attempt['LOC_X'] # calculate distance of fg fg_attempt['shot_dist'] = (fg_attempt['LOC_X'] ** 2 + fg_attempt['LOC_Y'] ** 2) ** 0.5 # create identifier for shot zones fg_attempt['shot_id'] = fg_attempt['SHOT_ZONE_BASIC'] + fg_attempt['SHOT_ZONE_AREA'] + fg_attempt['SHOT_ZONE_RANGE'] # all successful field goals fg_make = fg_attempt.loc[fg_attempt['SHOT_MADE_FLAG'] == 1] # all unsuccessful field goals fg_miss = fg_attempt.loc[fg_attempt['SHOT_MADE_FLAG'] == 0] # successful field goal statistics furthest_ft = round(fg_make['shot_dist'].max() / (5 / 6 * 12), 1) avg_ft = round(fg_make['shot_dist'].mean() / (5 / 6 * 12), 1) std_ft = round(fg_make['shot_dist'].std() / (5 / 6 * 12), 1) var_ft = round(fg_make['shot_dist'].var() / (5 / 6 * 12), 1) # create summary table of stats stats_headers = [['Furthest', 'Average', 'Standard Deviation', 'Variance'], [furthest_ft, avg_ft, std_ft, var_ft]] print('SHOT DISTANCE:\n', tabulate(stats_headers, headers = 'firstrow', tablefmt = 'fancy_grid'), sep = '') # categorize field goals by NBA-defined zones make_dict, miss_dict = ShotChartZones_Func.create_dict_shotzones_df(fg_make, fg_miss) print('\n\n', 'MADE FIELD GOALS:\n', fg_make) # shotid_make_gb = fg_attempt.groupby(['shot_id'])['SHOT_MADE_FLAG'].sum() # shotid_attempt_gb = fg_attempt.groupby(['shot_id'])['SHOT_ATTEMPTED_FLAG'].sum() # player_eff_byzone = shotid_make_gb / shotid_attempt_gb # create plots if plot_flag == 1: # create figures with shot charts fig_court1, ax_court1 = plt.subplots() ax, x_min, x_max, y_min, y_max = NBA_court_zones.draw_NBA_court( color = 'white', lw = 2, zones_flag = 0) if twitter_flag == 1: tweet.add_twitterhandle(fig_court1) fig_court2, ax_court2 = plt.subplots() ax, x_min, x_max, y_min, y_max = NBA_court_zones.draw_NBA_court( color = 'white', lw = 2, zones_flag = 0) if twitter_flag == 1: tweet.add_twitterhandle(fig_court2) fig_court3, ax_court3 = plt.subplots() ax, x_min, x_max, y_min, y_max = NBA_court_zones.draw_NBA_court( color = 'white', lw = 2, zones_flag = 0) if twitter_flag == 1: tweet.add_twitterhandle(fig_court3) # create dataframes of makes, misses, and all fg_make_loc = fg_make[['LOC_X', 'LOC_Y']].copy().reset_index(drop = True) fg_miss_loc = fg_miss[['LOC_X', 'LOC_Y']].copy().reset_index(drop = True) fg_attempt_loc = fg_attempt[['LOC_X', 'LOC_Y']].copy().reset_index(drop = True) # bin succcessful field goals by location court_bin_make, xedges_make, yedges_make, binnumber_make = stats.binned_statistic_2d( x = fg_make_loc['LOC_X'], y = fg_make_loc['LOC_Y'], values = None, statistic = 'count', bins = bin_edge_count, range = ((x_min, x_max), (y_min, y_max)) ) # bin all field goals by location court_bin_attempt, xedges_attempt, yedges_attempt, binnumber_attempt = stats.binned_statistic_2d( x = fg_attempt_loc['LOC_X'], y = fg_attempt_loc['LOC_Y'], values = None, statistic = 'count', bins = bin_edge_count, range = ((x_min, x_max), (y_min, y_max)) ) court_bin_make = court_bin_make.flatten() court_bin_attempt = court_bin_attempt.flatten() fga_filter = np.sort(court_bin_attempt)[-bin_edge_count] commonbins = np.where(court_bin_attempt < fga_filter, 0, court_bin_attempt) center_x = [] center_y = [] # need to find center of each bin to then plot a shape at for i in range(0, len(xedges_make) - 1): center_x.append((xedges_make[i] + xedges_make[i + 1]) / 2) center_y.append((yedges_make[i] + yedges_make[i + 1]) / 2) # count of all field goals in each bin fg_eff = commonbins # loop through bins for bin_i in range(0, len(fg_eff)): # divide successful field goal count by attempted field goal count for each bin if commonbins[bin_i] == 0: fg_eff[bin_i] = 2.01 else: fg_eff[bin_i] = court_bin_make[bin_i] / commonbins[bin_i] fg_eff = np.reshape(fg_eff, (bin_edge_count, bin_edge_count)) fg_eff_diff = np.subtract(fg_eff, league_avg_eff_bybin) # print(fg_eff_diff) fg_eff_masked = np.ma.masked_greater(fg_eff, 1) fg_eff_masked_lgavg = np.ma.masked_greater(fg_eff_diff, 1) fg_eff_masked_lgavg = np.ma.masked_invalid(fg_eff_masked_lgavg) # select color map and quantity of colors cmap_discrete = plt.cm.get_cmap('bwr', 10) # mesh grid based on bin edges xedges, yedges = np.meshgrid(xedges_make, yedges_make) plot_eff2 = ax_court2.pcolormesh(xedges, yedges, fg_eff_masked.T, cmap = cmap_discrete) cbar2 = plt.colorbar(plot_eff2, ax = ax_court2) xcenters, ycenters = np.meshgrid(center_x, center_y) attempts_reshaped = np.reshape(court_bin_attempt, (bin_edge_count, bin_edge_count)).T np.nan_to_num(fg_eff_diff, copy = False, nan = 1.01) cmap_bounds = [-0.1, -0.05, 0.05, 0.1] cmap_colors = ['steelblue', 'lightblue', 'grey', 'orange', 'red'] cmap_reps = ['-0.1', '-0.05', '0.0', '0.05', '0.1'] fg_eff_diff_cmap = fg_eff_diff fg_eff_diff_cmap = np.where(fg_eff_diff <= cmap_bounds[0], cmap_bounds[0], fg_eff_diff_cmap) fg_eff_diff_cmap = np.where((fg_eff_diff <= cmap_bounds[1]) & (fg_eff_diff > cmap_bounds[0]), cmap_bounds[1], fg_eff_diff_cmap) fg_eff_diff_cmap = np.where((fg_eff_diff < cmap_bounds[2]) & (fg_eff_diff > cmap_bounds[1]), 0.0, fg_eff_diff_cmap) fg_eff_diff_cmap = np.where((fg_eff_diff < cmap_bounds[3]) & (fg_eff_diff >= cmap_bounds[2]), cmap_bounds[2], fg_eff_diff_cmap) fg_eff_diff_cmap = np.where((fg_eff_diff_cmap >= cmap_bounds[3]) & (fg_eff_diff_cmap <= 1), cmap_bounds[3], fg_eff_diff_cmap) fg_eff_diff_cmap_str = fg_eff_diff_cmap.astype(str) fg_eff_diff_cmap_str = np.where(fg_eff_diff_cmap_str == cmap_reps[0], cmap_colors[0], fg_eff_diff_cmap_str) fg_eff_diff_cmap_str = np.where(fg_eff_diff_cmap_str == cmap_reps[1], cmap_colors[1], fg_eff_diff_cmap_str) fg_eff_diff_cmap_str = np.where(fg_eff_diff_cmap_str == cmap_reps[2], cmap_colors[2], fg_eff_diff_cmap_str) fg_eff_diff_cmap_str = np.where(fg_eff_diff_cmap_str == cmap_reps[3], cmap_colors[3], fg_eff_diff_cmap_str) fg_eff_diff_cmap_str = np.where(fg_eff_diff_cmap_str == cmap_reps[4], cmap_colors[4], fg_eff_diff_cmap_str) fg_eff_diff_cmap_str = fg_eff_diff_cmap_str.T for column in range(0, bin_edge_count): for row in range(0, bin_edge_count): if fg_eff.T[row, column] > 1: pass else: ax_court3.scatter(x = xcenters[row, column], y = ycenters[row, column], s = 10 * attempts_reshaped[row, column], c = fg_eff_diff_cmap_str[row, column], marker = 'h') if plot_fg == 'makes': # plot successful field goals ax_court1.scatter(fg_make['LOC_X'], fg_make['LOC_Y'], c = 'green', marker = 'o', alpha = 1, s = 10) elif plot_fg == 'misses': # plot unsuccessful field goals ax_court1.scatter(fg_miss['LOC_X'], fg_miss['LOC_Y'], c = 'red', marker = 'x', alpha = 0.8, s = 10) else: # plot all field goals ax_court1.scatter(fg_make['LOC_X'], fg_make['LOC_Y'], c = 'green', marker = 'o', alpha = 1, s = 10) ax_court1.scatter(fg_miss['LOC_X'], fg_miss['LOC_Y'], c = 'red', marker = 'x', alpha = 0.6, s = 10) # set titles ax_court1.set(title = player[0] + ', ' + season) ax_court2.set(title = player[0] + ', FG%, ' + season) ax_court3.set(title = player[0] + ', ' + season) # set background colors ax_court1.set_facecolor('black') ax_court2.set_facecolor('black') ax_court3.set_facecolor('black') # remove axes ticks ax_court1.set_xticks([]) ax_court1.set_yticks([]) ax_court2.set_xticks([]) ax_court2.set_yticks([]) ax_court3.set_xticks([]) ax_court3.set_yticks([]) add_hexlegend.add_legend_shotchart(ax_court3) if savefig_flag == 1: # specify file type image_type = '.jpeg' # specify file name fig1_name = player[0] + '_' + season + '_shotchart' + image_type fig2_name = player[0] + '_' + season + '_shotchartEff' + image_type fig3_name = player[0] + '_' + season + '_shotchartEff2' + image_type fig_court3.set_size_inches(10, 8) # save file fig_court1.savefig(fig1_name, dpi = 1000, bbox_inches = 'tight') fig_court2.savefig(fig2_name, dpi = 1000, bbox_inches = 'tight') fig_court3.savefig(fig3_name, dpi = 500, bbox_inches = 'tight') print('\n--- %s seconds ---\n' % (time.time() - start_time)) plt.show() return fg_make
def AnotacionesJugador(p_id, season, gametype): def draw_court(ax=None, color='black', lw=2, outer_lines=False): # If an axes object isn't provided to plot onto, just get current one if ax is None: ax = plt.gca() # Create the various parts of an NBA basketball court # Create the basketball hoop # Diameter of a hoop is 18" so it has a radius of 9", which is a value # 7.5 in our coordinate system hoop = Circle((0, 0), radius=7.5, linewidth=lw, color=color, fill=False) # Create backboard backboard = Rectangle((-30, -7.5), 60, -1, linewidth=lw, color=color) # The paint # Create the outer box 0f the paint, width=16ft, height=19ft outer_box = Rectangle((-80, -47.5), 160, 190, linewidth=lw, color=color, fill=False) # Create the inner box of the paint, widt=12ft, height=19ft inner_box = Rectangle((-60, -47.5), 120, 190, linewidth=lw, color=color, fill=False) # Create free throw top arc top_free_throw = Arc((0, 142.5), 120, 120, theta1=0, theta2=180, linewidth=lw, color=color, fill=False) # Create free throw bottom arc bottom_free_throw = Arc((0, 142.5), 120, 120, theta1=180, theta2=0, linewidth=lw, color=color, linestyle='dashed') # Restricted Zone, it is an arc with 4ft radius from center of the hoop restricted = Arc((0, 0), 80, 80, theta1=0, theta2=180, linewidth=lw, color=color) # Three point line # Create the side 3pt lines, they are 14ft long before they begin to arc corner_three_a = Rectangle((-220, -47.5), 0, 140, linewidth=lw, color=color) corner_three_b = Rectangle((220, -47.5), 0, 140, linewidth=lw, color=color) # 3pt arc - center of arc will be the hoop, arc is 23'9" away from hoop # I just played around with the theta values until they lined up with the # threes three_arc = Arc((0, 0), 475, 475, theta1=22, theta2=158, linewidth=lw, color=color) # Center Court center_outer_arc = Arc((0, 422.5), 120, 120, theta1=180, theta2=0, linewidth=lw, color=color) center_inner_arc = Arc((0, 422.5), 40, 40, theta1=180, theta2=0, linewidth=lw, color=color) # List of the court elements to be plotted onto the axes court_elements = [ hoop, backboard, outer_box, inner_box, top_free_throw, bottom_free_throw, restricted, corner_three_a, corner_three_b, three_arc, center_outer_arc, center_inner_arc ] if outer_lines: # Draw the half court line, baseline and side out bound lines outer_lines = Rectangle((-250, -47.5), 500, 470, linewidth=lw, color=color, fill=False) court_elements.append(outer_lines) # Add the court elements onto the axes for element in court_elements: ax.add_patch(element) return ax response = shotchartdetail.ShotChartDetail(team_id=0, player_id=p_id, season_nullable=season, season_type_all_star=gametype) content = json.loads(response.get_json()) # transform contents into dataframe results = content['resultSets'][0] headers = results['headers'] rows = results['rowSet'] shot_df = pd.DataFrame(rows) shot_df.columns = headers ssl._create_default_https_context = ssl._create_unverified_context # we pass in the link to the image as the 1st argument pic = urllib.request.urlretrieve( f"http://stats.nba.com/media/players/230x185/{p_id}.png", f"{p_id}.png") # urlretrieve returns a tuple with our image as the first # element and imread reads in the image as a # mutlidimensional numpy array so matplotlib can plot it harden_pic = plt.imread(pic[0]) # get our colormap for the main kde plot # Note we can extract a color from cmap to use for # the plots that lie on the side and top axes cmap = plt.cm.gist_heat_r # n_levels sets the number of contour lines for the main kde plot joint_shot_chart = sns.jointplot(shot_df.LOC_X, shot_df.LOC_Y, stat_func=None, kind='kde', space=0, color=cmap(0.1), cmap=cmap, n_levels=50) joint_shot_chart.fig.set_size_inches(12, 11) # A joint plot has 3 Axes, the first one called ax_joint, # It's the one we want to draw our court onto and adjust some other settings ax = joint_shot_chart.ax_joint draw_court(ax, color="gray", lw=1) # Adjust the axis limits and orientation of the plot in order # to plot half court, with the hoop by the top of the plot ax.set_xlim(-250, 250) ax.set_ylim(422.5, -47.5) # Get rid of axis labels and tick marks ax.set_xlabel('') ax.set_ylabel('') ax.tick_params(labelbottom='off', labelleft='off') # Add Data Scource and Author ax.text(-250, 445, 'Data Source: stats.nba.com', fontsize=12) # Add Harden's image to the top right # First create our OffSetImage by passing in our image # and set the zoom level to make the image small enough # to fit on our plot img = OffsetImage(harden_pic, zoom=0.6) # Pass in a tuple of x,y coordinates to set_offset # to place the plot where you want, I just played around # with the values until I found a spot where I wanted # the image to be img.set_offset((625, 621)) # add the image ax.add_artist(img) plt.show()