Spaces:
Runtime error
Runtime error
print('Running CSW%:') | |
import requests | |
import pandas as pd | |
import seaborn as sns | |
import matplotlib.pyplot as plt | |
from matplotlib.pyplot import figure | |
from matplotlib.offsetbox import OffsetImage, AnnotationBbox | |
# from scipy import stats | |
import matplotlib.lines as mlines | |
import matplotlib.transforms as mtransforms | |
import numpy as np | |
import time | |
# import plotly.express as px | |
#!pip install chart_studio | |
# import chart_studio.tools as tls | |
from bs4 import BeautifulSoup | |
import matplotlib.pyplot as plt | |
import numpy as np | |
import matplotlib.font_manager as font_manager | |
from datetime import datetime | |
import pytz | |
from matplotlib.ticker import MaxNLocator | |
datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y') | |
# Configure Notebook | |
#%matplotlib inline | |
plt.style.use('fivethirtyeight') | |
sns.set_context("notebook") | |
import warnings | |
import inflect | |
warnings.filterwarnings('ignore') | |
# import yfpy | |
# from yfpy.query import YahooFantasySportsQuery | |
# import yahoo_oauth | |
from matplotlib.pyplot import text | |
import json | |
# import openpyxl | |
# from sklearn import preprocessing | |
from datetime import timedelta | |
# import dataframe_image as dfi | |
# from google.colab import drive | |
def percentile(n): | |
def percentile_(x): | |
return np.nanpercentile(x, n) | |
percentile_.__name__ = 'percentile_%s' % n | |
return percentile_ | |
import matplotlib | |
import pygsheets | |
import os | |
# import praw | |
# import matplotlib.pyplot as plt | |
# import matplotlib.colors | |
import math | |
import matplotlib.ticker as mtick | |
colour_palette = ['#FFB000','#648FFF','#785EF0', | |
'#DC267F','#FE6100','#3D1EB2','#894D80','#16AA02','#B5592B','#A3C1ED'] | |
# print('hugging face test') | |
# from huggingface_hub import snapshot_download | |
# from huggingface_hub import hf_hub_download | |
# hf_hub_download(repo_id="nesticot/exit_df_all", filename="test.txt") | |
#cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"]) | |
#cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#4285f4","#FFFFFF","#F0E442"]) | |
# teams = requests.get(url='https://statsapi.mlb.com/api/v1/teams/').json() | |
# #Select only teams that are at the MLB level | |
# # mlb_teams_city = [x['franchiseName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball'] | |
# # mlb_teams_name = [x['teamName'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball'] | |
# # mlb_teams_franchise = [x['name'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball'] | |
# # mlb_teams_id = [x['id'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball'] | |
# # mlb_teams_abb = [x['abbreviation'] for x in teams['teams'] if x['sport']['name'] == 'Major League Baseball'] | |
# mlb_teams_city = [x['franchiseName'] if 'franchiseName' in x else None for x in teams['teams']] | |
# mlb_teams_name = [x['teamName'] if 'franchiseName' in x else None for x in teams['teams']] | |
# mlb_teams_franchise = [x['name'] if 'franchiseName' in x else None for x in teams['teams']] | |
# mlb_teams_id = [x['id'] if 'franchiseName' in x else None for x in teams['teams']] | |
# mlb_teams_abb = [x['abbreviation'] if 'franchiseName' in x else None for x in teams['teams']] | |
# mlb_teams_parent = [x['parentOrgName'] if 'parentOrgName' in x else None for x in teams['teams']] | |
# #Create a dataframe of all the teams | |
# mlb_teams_df = pd.DataFrame(data={'team_id':mlb_teams_id,'city':mlb_teams_franchise,'name':mlb_teams_name,'franchise':mlb_teams_franchise,'abbreviation':mlb_teams_abb,'parent_org':mlb_teams_parent}).drop_duplicates() | |
# ##Create a dataframe of all players in the database | |
# #Make an api call to get a dictionary of all players | |
# player_data = requests.get(url=f'https://statsapi.mlb.com/api/v1/sports/1/players').json() | |
# #Select relevant data that will help distinguish players from one another | |
# fullName_list = [x['fullName'] for x in player_data['people']] | |
# id_list = [x['id'] for x in player_data['people']] | |
# position_list = [x['primaryPosition']['abbreviation'] for x in player_data['people']] | |
# team_list = [x['currentTeam']['id']for x in player_data['people']] | |
# age_list = [x['currentAge']for x in player_data['people']] | |
# mlb_teams_df = mlb_teams_df.merge(right=mlb_teams_df[['abbreviation','franchise']],left_on='parent_org',right_on='franchise',how='left').drop_duplicates().reset_index(drop=True) | |
# mlb_teams_df = mlb_teams_df[mlb_teams_df.columns[:-1]] | |
# mlb_teams_df.columns = ['team_id', 'city', 'name', 'franchise', 'abbreviation', | |
# 'parent_org', 'parent_org_abb'] | |
# mlb_teams_df.parent_org_abb = mlb_teams_df.abbreviation | |
# mlb_teams_df = mlb_teams_df.drop_duplicates(subset=['parent_org_abb','abbreviation']) | |
# mlb_a_player_df = pd.DataFrame(data={'player_id':id_list,'batter':fullName_list,'position':position_list,'team_id':team_list,'age':age_list}) | |
# #Use the teams dataframe to merge the team name to the players dataframe | |
# mlb_a_player_df = mlb_a_player_df.merge(right=mlb_teams_df[['team_id','franchise','parent_org_abb']],left_on='team_id',right_on='team_id',how='left',suffixes=['','_y']) | |
# #drop the duplicated id column | |
# #player_df_all = player_df_all.drop(columns=['team_id']) | |
# #make a column of the names all uppercase to make lookups easier | |
# mlb_a_player_df['upper_name'] = mlb_a_player_df['batter'].str.upper() | |
# #rename to make the data clearer | |
# mlb_a_player_df = mlb_a_player_df.rename(columns={'franchise':'currentTeam'}) | |
# # from bs4 import BeautifulSoup | |
# # import re | |
# # page_url = 'https://www.mlb.com/prospects/stats/top-prospects' | |
# # headers = { | |
# # 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', | |
# # } | |
# # rawpage = requests.get(page_url,headers=headers) | |
# # soup = BeautifulSoup(rawpage.content, 'html.parser') | |
# # content = soup.findAll('tr') | |
# # batting = str(content).split('</th></tr>')[1] | |
# # pitching = str(content).split('</th></tr>')[2] | |
# # batting_rank = [item.split('<')[0] for item in batting.split('" style="cursor: pointer;"><td class="tr-data"> <span>')[1:]] | |
# # batting_list = [item[:6] for item in batting.split('Prospects-tr_')[1:]] | |
# # pitching_rank = [item.split('<')[0] for item in pitching.split('" style="cursor: pointer;"><td class="tr-data"> <span>')[1:]] | |
# # pitching_list = [item[:6] for item in pitching.split('Prospects-tr_')[1:]] | |
# # prospect_rank_df = pd.DataFrame(data={'rank_pl':batting_rank+pitching_rank,'player_id':batting_list+pitching_list}) | |
# # prospect_rank_df.player_id = prospect_rank_df.player_id.astype(int) | |
# # prospect_rank_df.rank_pl = prospect_rank_df.rank_pl.astype(int) | |
# # page_url_top30 = 'https://www.mlb.com/prospects/stats/top-prospects?type=all&dateRange=30day&minPA=1' | |
# # headers = { | |
# # 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', | |
# # } | |
# # rawpage_top30 = requests.get(page_url_top30,headers=headers) | |
# # soup_top30 = BeautifulSoup(rawpage_top30.content, 'html.parser') | |
# # content_top30 = soup_top30.findAll('tr') | |
# # batting_top30 = str(content_top30).split('</th></tr>')[1] | |
# # pitching_top30 = str(content_top30).split('</th></tr>')[2] | |
# # batting_rank_top30 = [item.split('<')[0] for item in batting_top30.split('" style="cursor: pointer;"><td class="tr-data"> <span>')[1:]] | |
# # batting_list_top30 = [item[:6] for item in batting_top30.split('Prospects-tr_')[1:]] | |
# # pitching_rank_top30 = [item.split('<')[0] for item in pitching_top30.split('" style="cursor: pointer;"><td class="tr-data"> <span>')[1:]] | |
# # pitching_list_top30 = [item[:6] for item in pitching_top30.split('Prospects-tr_')[1:]] | |
# # prospect_rank_df_top30 = pd.DataFrame(data={'rank_pl_top30':batting_rank_top30+pitching_rank_top30,'player_id':batting_list_top30+pitching_list_top30}) | |
# # prospect_rank_df_top30.player_id = prospect_rank_df_top30.player_id.astype(int) | |
# # prospect_rank_df_top30.rank_pl = prospect_rank_df_top30.rank_pl_top30.astype(int) | |
# # mlb_a_player_df = mlb_a_player_df.merge(right=prospect_rank_df,left_on='player_id',right_on='player_id',how='left') | |
# # mlb_a_player_df = mlb_a_player_df.merge(right=prospect_rank_df_top30,left_on='player_id',right_on='player_id',how='left') | |
# print(mlb_a_player_df) | |
# # milb_a_ev_df = pd.read_csv('/content/drive/MyDrive/Python/Baseball/mlb/2023/exit_velo_df.csv',index_col=[0]) | |
# milb_a_ev_df = pd.read_csv('C:/Users/thoma/Google Drive/Python/Baseball/mlb/2023/exit_velo_df.csv',index_col=[0]) | |
# triple_a_ev_df = pd.read_csv('triple_a/exit_velo_df.csv',index_col=[0]) | |
# double_a_ev_df = pd.read_csv('double_a/exit_velo_df.csv',index_col=[0]) | |
# a_high_a_ev_df = pd.read_csv('high_a/exit_velo_df.csv',index_col=[0]) | |
# single_a_ev_df = pd.read_csv('single_a/exit_velo_df.csv',index_col=[0]) | |
# #\mlb_a_player_df = pd.read_csv('C:/Users/thoma/Google Drive/Python/Baseball/mlb/2023/player_df_all.csv',index_col=[0]) | |
# triple_a_player_df = pd.read_csv('triple_a/player_df_all.csv',index_col=[0]) | |
# double_a_player_df = pd.read_csv('double_a/player_df_all.csv',index_col=[0]) | |
# a_high_a_player_df = pd.read_csv('high_a/player_df_all.csv',index_col=[0]) | |
# single_a_player_df = pd.read_csv('single_a/player_df_all.csv',index_col=[0]) | |
# milb_a_ev_df['level'] = 'MLB' | |
# triple_a_ev_df['level'] = 'AAA' | |
# double_a_ev_df['level'] = 'AA' | |
# a_high_a_ev_df['level'] = 'A+' | |
# single_a_ev_df['level'] = 'A' | |
print('Starting Everything:') | |
# exit_velo_df = milb_a_ev_df.append([triple_a_ev_df,double_a_ev_df,a_high_a_ev_df,single_a_ev_df]).reset_index(drop=True) | |
# player_df_all = mlb_a_player_df.append([triple_a_player_df,double_a_player_df,a_high_a_player_df,single_a_player_df]).reset_index(drop=True) | |
from datasets import load_dataset | |
# exit_velo_df = load_dataset("nesticot/exit_df_all") | |
exit_velo_df = pd.read_csv('exit_velo_df_all.csv',index_col=[0]) | |
player_df_all = pd.read_csv('player_df_all.csv',index_col=[0]) | |
#exit_velo_df.play_id = exit_velo_df.play_id.astype(int) | |
exit_velo_df = exit_velo_df.reset_index(drop=True) | |
#player_df_all.play_id = player_df_all.play_id.astype(int) | |
pa_df = pd.read_csv('pa_df_all.csv',index_col=[0]) | |
#pa_df.play_id = pa_df.play_id.astype(int) | |
exit_velo_df.date = pd.to_datetime(exit_velo_df.date).dt.date | |
pa_df_full_na = pa_df.dropna(subset=['event_type']) | |
pa_df_full_na = pa_df_full_na.reset_index(drop=True) | |
pa_df_full_na['is_out'] = [True if pa_df_full_na.event_type[x]=='strikeout' or pa_df_full_na.event_type[x]=='strikeout_double_play' else pa_df_full_na.is_out[x] for x in range(0,len(pa_df_full_na))] | |
pa_df_full_na['is_in_play'] = [False if pa_df_full_na.event_type[x]=='strikeout' or pa_df_full_na.event_type[x]=='strikeout_double_play' else pa_df_full_na.is_in_play[x] for x in range(0,len(pa_df_full_na))] | |
end_codes = ['single', 'strikeout', 'walk', 'field_out', | |
'grounded_into_double_play', 'fielders_choice', 'force_out', | |
'double', 'sac_fly', 'field_error', 'home_run', 'triple', | |
'hit_by_pitch', 'sac_bunt', 'double_play', 'intent_walk', | |
'fielders_choice_out', 'strikeout_double_play', | |
'sac_fly_double_play', 'catcher_interf', | |
'other_out','triple_play'] | |
hit_codes = ['single', | |
'double','home_run', 'triple'] | |
ab_codes = ['single', 'strikeout', 'field_out', | |
'grounded_into_double_play', 'fielders_choice', 'force_out', | |
'double', 'field_error', 'home_run', 'triple', | |
'double_play', | |
'fielders_choice_out', 'strikeout_double_play', | |
'other_out','triple_play'] | |
obp_true_codes = ['single', 'walk', | |
'double','home_run', 'triple', | |
'hit_by_pitch', 'intent_walk'] | |
obp_codes = ['single', 'strikeout', 'walk', 'field_out', | |
'grounded_into_double_play', 'fielders_choice', 'force_out', | |
'double', 'sac_fly', 'field_error', 'home_run', 'triple', | |
'hit_by_pitch', 'double_play', 'intent_walk', | |
'fielders_choice_out', 'strikeout_double_play', | |
'sac_fly_double_play', | |
'other_out','triple_play'] | |
pa_df_full_na_codes = pa_df_full_na[pa_df_full_na.event_type.isin(end_codes)] | |
pa_df_full_na_codes['pa'] = 1 | |
conditions_hit = [pa_df_full_na_codes.event_type.isin(hit_codes)] | |
choices_hit = [True] | |
pa_df_full_na_codes['hits'] = np.select(conditions_hit, choices_hit, default=False) | |
conditions_ab = [pa_df_full_na_codes.event_type.isin(ab_codes)] | |
choices_ab = [True] | |
pa_df_full_na_codes['ab'] = np.select(conditions_ab, choices_ab, default=False) | |
conditions_obp_true = [pa_df_full_na_codes.event_type.isin(obp_true_codes)] | |
choices_obp_true = [True] | |
pa_df_full_na_codes['on_base'] = np.select(conditions_obp_true, choices_obp_true, default=False) | |
conditions_obp = [pa_df_full_na_codes.event_type.isin(obp_codes)] | |
choices_obp = [True] | |
pa_df_full_na_codes['obp'] = np.select(conditions_obp, choices_obp, default=False) | |
pa_df_full_na_codes['k'] = pa_df_full_na_codes.event_type.isin(list(filter(None, [x if 'strikeout' in x else '' for x in pa_df_full_na_codes.event_type.unique()]))) | |
pa_df_full_na_codes['bb'] = pa_df_full_na_codes.event_type.isin(['walk','intent_walk']) | |
pa_df_full_na_codes['k_minus_bb'] = pa_df_full_na_codes['k'].astype(np.float32)-pa_df_full_na_codes['bb'].astype(np.float32) | |
pa_df_full_na_codes['bb_minus_k'] = pa_df_full_na_codes['bb'].astype(np.float32)-pa_df_full_na_codes['k'].astype(np.float32) | |
exit_velo_df = exit_velo_df.merge(right=player_df_all,left_on='batter_id',right_on='player_id',how='left',suffixes=('','_batter')) | |
exit_velo_df = exit_velo_df.merge(right=player_df_all,left_on='pitcher_id',right_on='player_id',how='left',suffixes=('','_pitcher')) | |
print('Running CSW%:') | |
exit_velo_df = exit_velo_df.drop_duplicates(subset=['play_id']) | |
exit_velo_df.sort_values(by='launch_speed',ascending=False)[['batter','launch_speed']].dropna().head(20)#.to_clipboard() | |
swing_codes = ['Swinging Strike', 'In play, no out', | |
'Foul', 'In play, out(s)', | |
'In play, run(s)', 'Swinging Strike (Blocked)', | |
'Foul Bunt','Foul Tip', 'Missed Bunt','Foul Pitchout','Swinging Pitchout'] | |
swings_in = ['Swinging Strike', 'In play, no out', | |
'Foul', 'In play, out(s)', | |
'In play, run(s)', 'Swinging Strike (Blocked)', | |
'Foul Bunt','Foul Tip', 'Missed Bunt','Foul Pitchout','Swinging Pitchout'] | |
swing_strike_codes = ['Swinging Strike', | |
'Swinging Strike (Blocked)','Missed Bunt','Foul Tip','Swinging Pitchout'] | |
contact_codes = ['In play, no out', | |
'Foul', 'In play, out(s)', | |
'In play, run(s)', | |
'Foul Bunt'] | |
codes_in = ['In play, out(s)', | |
'Swinging Strike', | |
'Ball', | |
'Foul', | |
'In play, no out', | |
'Called Strike', | |
'Foul Tip', | |
'In play, run(s)', | |
'Hit By Pitch', | |
'Ball In Dirt', | |
'Pitchout', | |
'Swinging Strike (Blocked)', | |
'Foul Bunt', | |
'Missed Bunt', | |
'Foul Pitchout', | |
'Intent Ball', | |
'Swinging Pitchout'] | |
codes_in_pa = ['Swinging Strike', 'Ball', 'In play, no out', 'Called Strike', | |
'Foul', 'In play, out(s)', 'Ball In Dirt', | |
'In play, run(s)', 'Swinging Strike (Blocked)', | |
'Foul Bunt', 'Foul Tip', | |
'Automatic Ball - Pitcher Pitch Timer Violation', | |
'Automatic Strike - Batter Pitch Timer Violation', 'Hit By Pitch', | |
'Automatic Ball - Intentional', | |
'Automatic Ball - Catcher Pitch Timer Violation', | |
'Missed Bunt', | |
'Automatic Strike - Batter Timeout Violation', 'Pitchout', | |
'Automatic Ball - Defensive Shift Violation', 'Automatic Ball', | |
'Foul Pitchout', 'Automatic Strike', 'Intent Ball', | |
'Swinging Pitchout'] | |
exit_velo_df = exit_velo_df.drop_duplicates(subset=['play_id']) | |
exit_velo_df_codes = exit_velo_df[exit_velo_df.description.isin(codes_in_pa)]#.dropna(subset=['in_zone']) | |
exit_velo_df_codes['bip'] = ~exit_velo_df_codes.launch_speed.isna() | |
conditions = [ | |
(exit_velo_df_codes['launch_speed'].isna()), | |
(exit_velo_df_codes['launch_speed']*1.5 - exit_velo_df_codes['launch_angle'] >= 117 ) & (exit_velo_df_codes['launch_speed'] + exit_velo_df_codes['launch_angle'] >= 124) & (exit_velo_df_codes['launch_speed'] > 98) & (exit_velo_df_codes['launch_angle'] >= 8) & (exit_velo_df_codes['launch_angle'] <= 50) | |
] | |
choices = [False,True] | |
exit_velo_df_codes['barrel'] = np.select(conditions, choices, default=np.nan) | |
conditions_ss = [ | |
(exit_velo_df_codes['launch_angle'].isna()), | |
(exit_velo_df_codes['launch_angle'] >= 8 ) * (exit_velo_df_codes['launch_angle'] <= 32 ) | |
] | |
choices_ss = [False,True] | |
exit_velo_df_codes['sweet_spot'] = np.select(conditions_ss, choices_ss, default=np.nan) | |
conditions_hh = [ | |
(exit_velo_df_codes['launch_speed'].isna()), | |
(exit_velo_df_codes['launch_speed'] >= 94.5 ) | |
] | |
choices_hh = [False,True] | |
exit_velo_df_codes['hard_hit'] = np.select(conditions_hh, choices_hh, default=np.nan) | |
conditions_tb = [ | |
(pa_df_full_na_codes['event_type']=='single'), | |
(pa_df_full_na_codes['event_type']=='double'), | |
(pa_df_full_na_codes['event_type']=='triple'), | |
(pa_df_full_na_codes['event_type']=='home_run'), | |
] | |
choices_tb = [1,2,3,4] | |
pa_df_full_na_codes['tb'] = np.select(conditions_tb, choices_tb, default=np.nan) | |
conditions_woba = [ | |
(pa_df_full_na_codes['event_type']=='walk'), | |
(pa_df_full_na_codes['event_type']=='hit_by_pitch'), | |
(pa_df_full_na_codes['event_type']=='single'), | |
(pa_df_full_na_codes['event_type']=='double'), | |
(pa_df_full_na_codes['event_type']=='triple'), | |
(pa_df_full_na_codes['event_type']=='home_run'), | |
] | |
choices_woba = [0.698, | |
0.728, | |
0.887, | |
1.253, | |
1.583, | |
2.027] | |
pa_df_full_na_codes['woba'] = np.select(conditions_woba, choices_woba, default=np.nan) | |
woba_codes = ['strikeout', 'field_out', 'single', 'walk', 'hit_by_pitch', | |
'double', 'sac_fly', 'force_out', 'home_run', | |
'grounded_into_double_play', 'fielders_choice', 'field_error', | |
'triple', 'sac_bunt', 'double_play', | |
'fielders_choice_out', 'strikeout_double_play', | |
'sac_fly_double_play', 'other_out'] | |
conditions_woba_code = [ | |
(pa_df_full_na_codes['event_type'].isin(woba_codes)) | |
] | |
choices_woba_code = [1] | |
pa_df_full_na_codes['woba_codes'] = np.select(conditions_woba_code, choices_woba_code, default=np.nan) | |
#exit_velo_df_codes['barrel'] = (exit_velo_df_codes.launch_speed >= 98) & (exit_velo_df_codes.launch_angle >= (26 - (-98 + exit_velo_df_codes.launch_speed))) & (exit_velo_df_codes.launch_angle <= 30 + (-98 + exit_velo_df_codes.launch_speed)) & (exit_velo_df_codes.launch_angle >= 8) & (exit_velo_df_codes.launch_angle <= 50) | |
print('Running CSW%:') | |
conditions_pitch = [ | |
(exit_velo_df_codes['description'].isin(codes_in)), | |
] | |
choices_pitch = [1] | |
exit_velo_df_codes['pitches'] = np.select(conditions_pitch, choices_pitch, default=np.nan) | |
#exit_velo_df_codes['pitches'] = 1 | |
exit_velo_df_codes['whiffs'] = [1 if ((x == 'S')|(x == 'W')|(x =='T')) else 0 for x in exit_velo_df_codes.code] | |
exit_velo_df_codes['csw'] = [1 if ((x == 'S')|(x == 'W')|(x =='T')|(x == 'C')) else 0 for x in exit_velo_df_codes.code] | |
exit_velo_df_codes['swings'] = [1 if x in swings_in else 0 for x in exit_velo_df_codes.description] | |
exit_velo_df_codes['out_zone'] = exit_velo_df_codes.in_zone == False | |
exit_velo_df_codes['zone_swing'] = (exit_velo_df_codes.in_zone == True)&(exit_velo_df_codes.swings == 1) | |
exit_velo_df_codes['zone_contact'] = (exit_velo_df_codes.in_zone == True)&(exit_velo_df_codes.swings == 1)&(exit_velo_df_codes.whiffs == 0) | |
exit_velo_df_codes['ozone_swing'] = (exit_velo_df_codes.in_zone==False)&(exit_velo_df_codes.swings == 1) | |
exit_velo_df_codes['ozone_contact'] = (exit_velo_df_codes.in_zone==False)&(exit_velo_df_codes.swings == 1)&(exit_velo_df_codes.whiffs == 0) | |
exit_velo_df_codes = exit_velo_df_codes.merge(right=pa_df_full_na_codes,left_on='play_id',right_on='play_id',how='left',suffixes=('','_pa_list')) | |
print('Trust') | |
print(exit_velo_df_codes) | |
exit_velo_df_codes_summ_batter = exit_velo_df_codes.groupby(['batter_id','batter','level']).agg( | |
pa = ('pa','sum'), | |
ab = ('ab','sum'), | |
obp_pa = ('obp','sum'), | |
hits = ('hits','sum'), | |
on_base = ('on_base','sum'), | |
k = ('k','sum'), | |
bb = ('bb','sum'), | |
bb_minus_k = ('bb_minus_k','sum'), | |
csw = ('csw','sum'), | |
bip = ('bip','sum'), | |
tb = ('tb','sum'), | |
woba = ('woba','sum'), | |
woba_codes = ('woba_codes','sum'), | |
hard_hit = ('hard_hit','sum'), | |
barrel = ('barrel','sum'), | |
sweet_spot = ('sweet_spot','sum'), | |
max_launch_speed = ('launch_speed','max'), | |
launch_speed_90 = ('launch_speed',percentile(90)), | |
launch_speed = ('launch_speed','mean'), | |
launch_angle = ('launch_angle','mean'), | |
pitches = ('pitches','sum'), | |
swings = ('swings','sum'), | |
in_zone = ('in_zone','sum'), | |
out_zone = ('out_zone','sum'), | |
whiffs = ('whiffs','sum'), | |
zone_swing = ('zone_swing','sum'), | |
zone_contact = ('zone_contact','sum'), | |
ozone_swing = ('ozone_swing','sum'), | |
ozone_contact = ('ozone_contact','sum'), | |
).reset_index() | |
#exit_velo_df_codes_summ['out_zone'] = ~exit_velo_df_codes_summ.in_zone | |
#bip_min_input = int(input()) | |
#bip_min = min(bip_min_input,50) | |
#exit_velo_df_codes_summ = exit_velo_df_codes_summ[exit_velo_df_codes_summ.balls_in_play>=bip_min] | |
exit_velo_df_codes_summ_batter['avg'] = [exit_velo_df_codes_summ_batter.hits[x]/exit_velo_df_codes_summ_batter.ab[x] if exit_velo_df_codes_summ_batter.ab[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['obp'] = [exit_velo_df_codes_summ_batter.on_base[x]/exit_velo_df_codes_summ_batter.obp_pa[x] if exit_velo_df_codes_summ_batter.obp_pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['slg'] = [exit_velo_df_codes_summ_batter.tb[x]/exit_velo_df_codes_summ_batter.ab[x] if exit_velo_df_codes_summ_batter.ab[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['ops'] = exit_velo_df_codes_summ_batter['obp']+exit_velo_df_codes_summ_batter['slg'] | |
exit_velo_df_codes_summ_batter['k_percent'] = [exit_velo_df_codes_summ_batter.k[x]/exit_velo_df_codes_summ_batter.pa[x] if exit_velo_df_codes_summ_batter.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['bb_percent'] =[exit_velo_df_codes_summ_batter.bb[x]/exit_velo_df_codes_summ_batter.pa[x] if exit_velo_df_codes_summ_batter.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['bb_minus_k_percent'] =[(exit_velo_df_codes_summ_batter.bb_minus_k[x])/exit_velo_df_codes_summ_batter.pa[x] if exit_velo_df_codes_summ_batter.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['bb_over_k_percent'] =[exit_velo_df_codes_summ_batter.bb[x]/exit_velo_df_codes_summ_batter.k[x] if exit_velo_df_codes_summ_batter.k[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['csw_percent'] =[exit_velo_df_codes_summ_batter.csw[x]/exit_velo_df_codes_summ_batter.pitches[x] if exit_velo_df_codes_summ_batter.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['sweet_spot_percent'] = [exit_velo_df_codes_summ_batter.sweet_spot[x]/exit_velo_df_codes_summ_batter.bip[x] if exit_velo_df_codes_summ_batter.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['woba_percent'] = [exit_velo_df_codes_summ_batter.woba[x]/exit_velo_df_codes_summ_batter.woba_codes[x] if exit_velo_df_codes_summ_batter.woba_codes[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
#exit_velo_df_codes_summ_batter['hard_hit_percent'] = [exit_velo_df_codes_summ_batter.sweet_spot[x]/exit_velo_df_codes_summ_batter.bip[x] if exit_velo_df_codes_summ_batter.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['hard_hit_percent'] = [exit_velo_df_codes_summ_batter.hard_hit[x]/exit_velo_df_codes_summ_batter.bip[x] if exit_velo_df_codes_summ_batter.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['barrel_percent'] = [exit_velo_df_codes_summ_batter.barrel[x]/exit_velo_df_codes_summ_batter.bip[x] if exit_velo_df_codes_summ_batter.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['zone_contact_percent'] = [exit_velo_df_codes_summ_batter.zone_contact[x]/exit_velo_df_codes_summ_batter.zone_swing[x] if exit_velo_df_codes_summ_batter.zone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['zone_swing_percent'] = [exit_velo_df_codes_summ_batter.zone_swing[x]/exit_velo_df_codes_summ_batter.in_zone[x] if exit_velo_df_codes_summ_batter.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['zone_percent'] = [exit_velo_df_codes_summ_batter.in_zone[x]/exit_velo_df_codes_summ_batter.pitches[x] if exit_velo_df_codes_summ_batter.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['chase_percent'] = [exit_velo_df_codes_summ_batter.ozone_swing[x]/(exit_velo_df_codes_summ_batter.pitches[x] - exit_velo_df_codes_summ_batter.in_zone[x]) if (exit_velo_df_codes_summ_batter.pitches[x]- exit_velo_df_codes_summ_batter.in_zone[x]) != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['chase_contact'] = [exit_velo_df_codes_summ_batter.ozone_contact[x]/exit_velo_df_codes_summ_batter.ozone_swing[x] if exit_velo_df_codes_summ_batter.ozone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['swing_percent'] = [exit_velo_df_codes_summ_batter.swings[x]/exit_velo_df_codes_summ_batter.pitches[x] if exit_velo_df_codes_summ_batter.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['whiff_rate'] = [exit_velo_df_codes_summ_batter.whiffs[x]/exit_velo_df_codes_summ_batter.swings[x] if exit_velo_df_codes_summ_batter.swings[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter['swstr_rate'] = [exit_velo_df_codes_summ_batter.whiffs[x]/exit_velo_df_codes_summ_batter.pitches[x] if exit_velo_df_codes_summ_batter.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_batter))] | |
exit_velo_df_codes_summ_batter = exit_velo_df_codes_summ_batter.dropna(subset=['bip']) | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.set_index(['batter_id','batter','level']) | |
# exit_velo_df_codes_summ_rank = exit_velo_df_codes_summ[exit_velo_df_codes_summ.columns].rank(method='max',ascending=False) | |
# exit_velo_df_codes_summ_rank.columns = exit_velo_df_codes_summ_rank.columns+['_rank'] | |
# exit_velo_df_codes_summ_rank_percent = exit_velo_df_codes_summ.rank(pct=True) | |
# exit_velo_df_codes_summ_rank_percent.columns = exit_velo_df_codes_summ_rank_percent.columns+['_percent'] | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.merge(exit_velo_df_codes_summ_rank,left_on=['batter_id','batter','level'],right_on=['batter_id','batter','level'],suffixes=['','_rank']) | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.merge(exit_velo_df_codes_summ_rank_percent,left_on=['batter_id','batter','level'],right_on=['batter_id','batter','level'],suffixes=['','_percent']) | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.reset_index() | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.drop_duplicates(subset=['batter_id','level']) | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.drop_duplicates(subset=['batter_id','level']) | |
# #exit_velo_df_codes_summ = exit_velo_df_codes_summ.set_index(['batter_id','batter','level']) | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.merge(right=player_df_all[['parent_org_abb','player_id','age','rank_pl','rank_pl_top30']],left_on='batter_id',right_on='player_id',how='left') | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ.drop_duplicates(subset=['player_id','level']) | |
#exit_velo_df_codes_summ = exit_velo_df_codes_summ.round(1) | |
print('we made it here') | |
# exit_velo_df_codes_summ = exit_velo_df_codes_summ[['player_id', 'batter','age','parent_org_abb','rank_pl','rank_pl_top30','level','pa','bb','k', 'balls_in_play', 'barrels','max_launch_speed', | |
# 'launch_speed_90', 'launch_speed', 'launch_angle', 'pitches', 'swings','bb_percent','k_percent','zone_swing', 'zone_contact', | |
# 'zone_percent', 'chase_percent', 'chase_contact', | |
# 'swing_percent', 'whiff_rate','swstr_rate']] | |
exit_velo_df_codes_summ_batter.head() | |
exit_velo_df_codes_summ_batter = exit_velo_df_codes_summ_batter.merge(right=player_df_all,left_on='batter_id',right_on='player_id',how='left',suffixes=('','_batter')) | |
exit_velo_df_codes_summ_batter = exit_velo_df_codes_summ_batter.drop_duplicates(subset=['batter_id','level']) | |
# exit_velo_df_codes_summ['batter'] = '=hyperlink("https://baseballsavant.mlb.com/savant-player/'+exit_velo_df_codes_summ['player_id'].astype(str)+'", "'+exit_velo_df_codes_summ['batter']+'")' | |
# exit_velo_df_codes_summ.columns = ['Batter ID','Batter','Age','Team','Top 100 Rank','Team Rank','Level','Balls In Play','Barrel%','Max EV','90th EV','Average EV','Launch Angle','Pitches','Swings','Z-Swing%','Z-Contact%','Zone%','O-Swing%','O-Contact%','Swing%','Whiff%','SwStr%'] | |
# for i in exit_velo_df_codes_summ.columns[-8:]: | |
# exit_velo_df_codes_summ[i] = ["{:.1%}".format(i) for i in exit_velo_df_codes_summ[i]] | |
# for i in exit_velo_df_codes_summ.columns[8:9]: | |
# exit_velo_df_codes_summ[i] = ["{:.1%}".format(i) for i in exit_velo_df_codes_summ[i]] | |
# gc = pygsheets.authorize(service_file='stunning-hue-363921-db5ac144d947.json') | |
# Create empty dataframe | |
#open the google spreadsheet (where 'PY to Gsheet Test' is the name of my sheet) | |
# for i in range(0,len(unique_pitch_types)): | |
# sh[i].title = unique_pitch_types[i] + ' (' +unique_pitch_names[i]+ ')' | |
# print('Writing Statcast Data to sheets') | |
# tz_NY = pytz.timezone('America/New_York') | |
# sh = gc.open_by_key('1_Xy3i50Y-TTwZvgvNK_MDz4mPYiSlsTekrbJLZOFtck') | |
# exit_velo_df_codes_summ_drive = exit_velo_df_codes_summ.copy() | |
# exit_velo_df_codes_summ_drive = exit_velo_df_codes_summ_drive.round(1) | |
# # exit_velo_df_codes_summ_drive['SwStr%'] = ["{:.1%}".format(i) for i in pitch_whiff_df_drive['SwStr%']] | |
# # exit_velo_df_codes_summ_drive['Whiff%'] = ["{:.1%}".format(i) for i in pitch_whiff_df_drive['Whiff%']] | |
# # exit_velo_df_codes_summ_drive['CSW%'] = ["{:.1%}".format(i) for i in pitch_whiff_df_drive['CSW%']] | |
# levels = ['MLB','AAA','AA','A+','A'] | |
# datetime_NY = datetime.now(tz_NY) | |
# for i in range(0,len(levels)): | |
# print(i) | |
# if levels[i] == 'AA' or levels[i] == 'A+': | |
# sh[i].set_dataframe(exit_velo_df_codes_summ_drive[exit_velo_df_codes_summ_drive.Level==levels[i]].reset_index(drop=True).reindex(list(range(0, 5000)))[['Batter ID','Batter','Age','Team','Top 100 Rank','Team Rank','Level','Balls In Play','Pitches','Swings','Swing%','Whiff%','SwStr%']].fillna(''),(4,1)) | |
# else: | |
# sh[i].set_dataframe(exit_velo_df_codes_summ_drive[exit_velo_df_codes_summ_drive.Level==levels[i]].reset_index(drop=True).reindex(list(range(0, 5000))).sort_values(by=('Max EV'),ascending=False).fillna(''),(4,1)) | |
# # test_df = test_df[['ID', 'hyperlink', 'Team', 'balls_in_play','max_launch_speed','launch_speed_95', 'launch_speed', 'launch_angle']] | |
# # test_df.columns = ['ID','Pitcher','Team','Balls In Play','Max EV','95th EV','Average EV','Launch Angle'] | |
# sh[i].update_value('A3', 'Updated: '+datetime_NY.strftime("%Y-%m-%d, %H:%M EST")) | |
woba_list = ['woba'] | |
pa_list = ['k','bb','k_minus_bb','bb_minus_k'] | |
balls_in_play_list = ['hard_hit','launch_speed','launch_speed_90','launch_angle','barrel','sweet_spot'] | |
pitches_list = ['zone_percent','swing_percent','sw_str','csw'] | |
swings_list = ['whiff_percent'] | |
in_zone_pitches_list = ['zone_swing'] | |
in_zone_swings_list = ['zone_contact'] | |
out_zone_pitches_list = ['chase_percent'] | |
out_zone_swings_list = ['chase_contact'] | |
plot_dict_batter = { | |
'k':{'x_axis':'Plate Appearances','y_axis':'K%','title':'K%','x_value':'k','x_range':[0.0,0.1,0.2,0.3,0.4],'percent':True,'percentile_label':'k_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'bb':{'x_axis':'Plate Appearances','y_axis':'BB%','title':'BB%','x_value':'bb','x_range':[0.0,0.1,0.2,0.3],'percent':True,'percentile_label':'bb_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'bb_minus_k':{'x_axis':'Plate Appearances','y_axis':'BB-K%','title':'BB-K%','x_value':'bb_minus_k','x_range':[-0.3,-0.2,-0.1,0,0.1,0.2],'percent':True,'percentile_label':'bb_minus_k_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'csw':{'x_axis':'Pitches','y_axis':'CSW%','title':'CSW%','x_value':'csw','x_range':[.2,.25,.3,.35,.4],'percent':True,'percentile_label':'csw_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'woba':{'x_axis':'wOBA PA','y_axis':'wOBA','title':'wOBA','x_value':'woba','x_range':[0.10,.20,.30,.40,.50,.60],'percent':False,'percentile_label':'woba_percent','flip_p':False,'percentile':False,'avg_adjust':True}, | |
'launch_speed':{'x_axis':'Balls In Play','y_axis':'Exit Velocity','title':'Exit Velocity','x_value':'launch_speed','x_range':[85,90,95,100,105],'percent':False,'percentile_label':'launch_speed','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'launch_speed_90':{'x_axis':'Balls In Play','y_axis':'90th Percentile Exit Velocity','title':'90th Percentile Exit Velocity','x_value':'launch_speed','x_range':[90,95,100,105,110,115,120],'percent':False,'percentile_label':'launch_speed_90','flip_p':False,'percentile':True,'avg_adjust':False}, | |
'hard_hit':{'x_axis':'Balls In Play','y_axis':'HardHit%','title':'HardHit%','x_value':'hard_hit','x_range':[0.2,0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'hard_hit_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'sweet_spot':{'x_axis':'Balls In Play','y_axis':'SweetSpot%','title':'SweetSpot%','x_value':'sweet_spot','x_range':[0.2,0.3,0.4,0.5,0.6],'percent':True,'percentile_label':'sweet_spot_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'launch_angle':{'x_axis':'Balls In Play','y_axis':'Launch Angle','title':'Launch Angle','x_value':'launch_angle','x_range':[-20,-10,0,10,20],'percent':False,'percentile_label':'launch_angle','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'barrel':{'x_axis':'Balls In Play','y_axis':'Barrel%','title':'Barrel%','x_value':'barrel','x_range':[0,0.05,0.10,.15,.20,.25,.30],'percent':True,'percentile_label':'barrel_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'zone_percent':{'x_axis':'Pitches','y_axis':'Zone%','title':'Zone%','x_value':'in_zone','x_range':[0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'zone_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'swing_percent':{'x_axis':'Pitches','y_axis':'Swing%','title':'Swing%','x_value':'swings','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'swing_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'whiff_percent':{'x_axis':'Swings','y_axis':'Whiff%','title':'Whiff%','x_value':'whiffs','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'whiff_rate','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'sw_str':{'x_axis':'Pitches','y_axis':'SwStr%','title':'SwStr%','x_value':'whiffs','x_range':[0.0,0.05,0.1,0.15,0.2,0.25],'percent':True,'percentile_label':'swstr_rate','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'zone_swing':{'x_axis':'In-Zone Pitches','y_axis':'Z-Swing%','title':'Z-Swing%','x_value':'zone_swing','x_range':[0.3,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_swing_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'zone_contact':{'x_axis':'In-Zone Swings','y_axis':'Z-Contact%','title':'Z-Contact%','x_value':'zone_contact','x_range':[0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_contact_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'chase_percent':{'x_axis':'Out-of-Zone Pitches','y_axis':'O-Swing%','title':'O-Swing%','x_value':'ozone_swing','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'chase_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'chase_contact':{'x_axis':'Out-of-Zone Swings','y_axis':'O-Contact%','title':'O-Contact%','x_value':'ozone_contact','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'chase_contact','flip_p':False,'percentile':False,'avg_adjust':False},} | |
plot_dict = { | |
'k':{'x_axis':'Plate Appearances','y_axis':'K%','title':'K%','x_value':'k','x_range':[0.0,0.1,0.2,0.3,0.4],'percent':True,'percentile_label':'k_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'bb':{'x_axis':'Plate Appearances','y_axis':'BB%','title':'BB%','x_value':'bb','x_range':[0.0,0.1,0.2,0.3],'percent':True,'percentile_label':'bb_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'k_minus_bb':{'x_axis':'Plate Appearances','y_axis':'K-BB%','title':'K-BB%','x_value':'k_minus_bb','x_range':[-0.1,0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'k_minus_bb_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'csw':{'x_axis':'Pitches','y_axis':'CSW%','title':'CSW%','x_value':'csw','x_range':[.2,.25,.3,.35,.4],'percent':True,'percentile_label':'csw_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'woba':{'x_axis':'wOBA PA','y_axis':'wOBA','title':'wOBA','x_value':'woba','x_range':[.1,0.2,.30,.40,.50,.60],'percent':False,'percentile_label':'woba_percent','flip_p':True,'percentile':False,'avg_adjust':True}, | |
'launch_speed':{'x_axis':'Balls In Play','y_axis':'Exit Velocity','title':'Exit Velocity','x_value':'launch_speed','x_range':[85,90,95,100,105],'percent':True,'percentile_label':'launch_speed','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'launch_speed_90':{'x_axis':'Balls In Play','y_axis':'90th Percentile Exit Velocity','title':'90th Percentile Exit Velocity','x_value':'launch_speed','x_range':[90,95,100,105,110,115,120],'percent':False,'percentile_label':'launch_speed_90','flip_p':True,'percentile':True,'avg_adjust':False}, | |
'hard_hit':{'x_axis':'Balls In Play','y_axis':'HardHit%','title':'HardHit%','x_value':'hard_hit','x_range':[0.2,0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'hard_hit_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'sweet_spot':{'x_axis':'Balls In Play','y_axis':'SweetSpot%','title':'SweetSpot%','x_value':'sweet_spot','x_range':[0.2,0.3,0.4,0.5,0.6],'percent':True,'percentile_label':'sweet_spot_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'launch_angle':{'x_axis':'Balls In Play','y_axis':'Launch Angle','title':'Launch Angle','x_value':'launch_angle','x_range':[-20,-10,0,10,20],'percent':False,'percentile_label':'launch_angle','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'barrel':{'x_axis':'Balls In Play','y_axis':'Barrel%','title':'Barrel%','x_value':'barrel','x_range':[0,0.05,0.10,.15,.20,.25,.30],'percent':True,'percentile_label':'barrel_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'zone_percent':{'x_axis':'Pitches','y_axis':'Zone%','title':'Zone%','x_value':'in_zone','x_range':[0.3,0.4,0.5,0.6,0.7],'percent':True,'percentile_label':'zone_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'swing_percent':{'x_axis':'Pitches','y_axis':'Swing%','title':'Swing%','x_value':'swings','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'swing_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'whiff_percent':{'x_axis':'Swings','y_axis':'Whiff%','title':'Whiff%','x_value':'whiffs','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'whiff_rate','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'sw_str':{'x_axis':'Pitches','y_axis':'SwStr%','title':'SwStr%','x_value':'whiffs','x_range':[0.0,0.05,0.1,0.15,0.2,0.25],'percent':True,'percentile_label':'swstr_rate','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'zone_swing':{'x_axis':'In-Zone Pitches','y_axis':'Z-Swing%','title':'Z-Swing%','x_value':'zone_swing','x_range':[0.3,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_swing_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'zone_contact':{'x_axis':'In-Zone Swings','y_axis':'Z-Contact%','title':'Z-Contact%','x_value':'zone_contact','x_range':[0.5,0.6,0.7,0.8,0.9,1],'percent':True,'percentile_label':'zone_contact_percent','flip_p':True,'percentile':False,'avg_adjust':False}, | |
'chase_percent':{'x_axis':'Out-of-Zone Pitches','y_axis':'O-Swing%','title':'O-Swing%','x_value':'ozone_swing','x_range':[0.0,0.1,0.2,0.3,0.4,0.5],'percent':True,'percentile_label':'chase_percent','flip_p':False,'percentile':False,'avg_adjust':False}, | |
'chase_contact':{'x_axis':'Out-of-Zone Swings','y_axis':'O-Contact%','title':'O-Contact%','x_value':'ozone_contact','x_range':[0.2,0.3,0.4,0.5,0.6,0.7,0.8],'percent':True,'percentile_label':'chase_contact','flip_p':True,'percentile':False,'avg_adjust':False},} | |
pitcher_dict_stat = { 'sweet_spot_percent':{'x_axis':'SweetSpot%','title':'SweetSpot%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'max_launch_speed':{'x_axis':'Max Exit Velocity','title':'Max Exit Velocity','flip_p':False,'decimal_format':'string_0','percent_adjust':1}, | |
'launch_speed_90':{'x_axis':'90th Percentile EV','title':'90th Percentile EV','flip_p':False,'decimal_format':'string_0','percent_adjust':1}, | |
'launch_speed':{'x_axis':'Exit Velocity','title':'Exit Velocity','flip_p':False,'decimal_format':'string_0','percent_adjust':1}, | |
'launch_angle':{'x_axis':'Launch Angle','title':'Launch Angle','flip_p':False,'decimal_format':'string_0','percent_adjust':100}, | |
'avg':{'x_axis':'AVG','title':'AVG','flip_p':False,'decimal_format':'string_3','percent_adjust':100}, | |
'obp':{'x_axis':'OBP','title':'OBP','flip_p':False,'decimal_format':'string_3','percent_adjust':100}, | |
'slg':{'x_axis':'SLG','title':'SLG','flip_p':False,'decimal_format':'string_3','percent_adjust':100}, | |
'ops':{'x_axis':'OPS','title':'OPS','flip_p':False,'decimal_format':'string_3','percent_adjust':100}, | |
'k_percent':{'x_axis':'K%','title':'K%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'bb_percent':{'x_axis':'BB%','title':'BB%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'bb_over_k_percent':{'x_axis':'K/BB','title':'K/BB','flip_p':True,'decimal_format':'string_1','percent_adjust':100}, | |
'bb_minus_k_percent':{'x_axis':'K%-BB%','title':'K%-BB%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'csw_percent':{'x_axis':'CSW%','title':'CSW%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'woba_percent':{'x_axis':'wOBA','title':'wOBA','flip_p':False,'decimal_format':'string_3','percent_adjust':100}, | |
'hard_hit_percent':{'x_axis':'HardHit%','title':'HardHit%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'barrel_percent':{'x_axis':'Barrel%','title':'Barrel%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'zone_contact_percent':{'x_axis':'Z-Contact%','title':'Z-Contact%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'zone_swing_percent':{'x_axis':'Z-Swing%','title':'Z-Swing%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'zone_percent':{'x_axis':'Zone%','title':'Zone%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'chase_percent':{'x_axis':'O-Swing%','title':'O-Swing%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'chase_contact':{'x_axis':'O-Contact%','title':'O-Contact%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'swing_percent':{'x_axis':'Swing%','title':'Swing%','flip_p':False,'decimal_format':'percent_1','percent_adjust':100}, | |
'whiff_rate':{'x_axis':'Whiff%','title':'Whiff%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
'swstr_rate':{'x_axis':'SwStr%','title':'SwStr%','flip_p':True,'decimal_format':'percent_1','percent_adjust':100}, | |
} | |
batter_test_df = exit_velo_df.sort_values(by='batter').drop_duplicates(subset='batter_id').reset_index(drop=True)[['batter_id','batter']]#['pitcher'].to_dict() | |
batter_test_df = batter_test_df.set_index('batter_id') | |
pitcher_test_df = exit_velo_df.sort_values(by='pitcher').drop_duplicates(subset='pitcher_id').reset_index(drop=True)[['pitcher_id','pitcher']]#['pitcher'].to_dict() | |
pitcher_test_df = pitcher_test_df.set_index('pitcher_id') | |
#test_df = test_df[test_df.pitcher == 'Chris Bassitt'].append(test_df[test_df.pitcher != 'Chris Bassitt']) | |
batter_dict = batter_test_df['batter'].to_dict() | |
pitcher_dict = pitcher_test_df['pitcher'].to_dict() | |
plot_dict_small_all_input = { | |
'k_percent':'k_percent', | |
'bb_percent':'bb_percent', | |
'bb_minus_k_percent':'bb_minus_k_percent', | |
'csw_percent':'csw_percent', | |
'woba_percent':'woba_percent', | |
'launch_speed':'launch_speed', | |
'launch_speed_90':'launch_speed_90', | |
'hard_hit_percent':'hard_hit_percent', | |
'sweet_spot_percent':'sweet_spot_percent', | |
'launch_angle':'launch_angle', | |
'zone_percent':'zone_percent', | |
'barrel_percent':'barrel_percent', | |
'swing_percent':'swing_percent', | |
'whiff_rate':'whiff_rate', | |
'swstr_rate':'swstr_rate', | |
'zone_swing_percent':'zone_swing_percent', | |
'zone_contact_percent':'zone_contact_percent', | |
'chase_percent':'chase_percent', | |
'chase_contact':'chase_contact',} | |
level_dict = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'} | |
level_dict_pitch = {'MLB':'MLB','AAA':'AAA','AA':'AA','A+':'A+','A':'A'} | |
plot_dict_small_all = { | |
'k':'k_percent', | |
'bb':'bb_percent', | |
'bb_minus_k':'bb_minus_k_percent', | |
'csw':'csw_percent', | |
'woba':'woba_percent', | |
'launch_speed':'launch_speed', | |
'launch_speed_90':'launch_speed_90', | |
'hard_hit':'hard_hit_percent', | |
'sweet_spot':'sweet_spot_percent', | |
'launch_angle':'launch_angle', | |
'zone_percent':'zone_percent', | |
'barrel':'barrel_percent', | |
'swing_percent':'swing_percent', | |
'whiff_percent':'whiff_rate', | |
'sw_str':'swstr_rate', | |
'zone_swing':'zone_swing_percent', | |
'zone_contact':'zone_contact_percent', | |
'chase_percent':'chase_percent', | |
'chase_contact':'chase_contact',} | |
plot_dict_small_this_one = { | |
'k_percent':'K%', | |
'bb_percent':'BB%', | |
'bb_minus_k_percent':'BB%-K%', | |
'csw_percent':'CSW%', | |
'woba_percent':'wOBA', | |
'launch_speed':'Exit Velocity', | |
'launch_speed_90':'90th Percentile Exit Velocity', | |
'hard_hit_percent':'HardHit%', | |
'sweet_spot_percent':'SweetSpot%', | |
'launch_angle':'Launch Angle', | |
'zone_percent':'Zone%', | |
'barrel_percent':'Barrel%', | |
'swing_percent':'Swing%', | |
'whiff_rate':'Whiff%', | |
'swstr_rate':'SwStr%', | |
'zone_swing_percent':'Z-Swing%', | |
'zone_contact_percent':'Z-Contact%', | |
'chase_percent':'O-Swing%', | |
'chase_contact':'O-Contact%',} | |
plot_dict_small = { | |
'k':'K%', | |
'bb':'BB%', | |
'bb_minus_k':'BB%-K%', | |
'csw':'CSW%', | |
'woba':'wOBA', | |
'launch_speed':'Exit Velocity', | |
'launch_speed_90':'90th Percentile Exit Velocity', | |
'hard_hit':'HardHit%', | |
'sweet_spot':'SweetSpot%', | |
'launch_angle':'Launch Angle', | |
'zone_percent':'Zone%', | |
'barrel':'Barrel%', | |
'swing_percent':'Swing%', | |
'whiff_percent':'Whiff%', | |
'sw_str':'SwStr%', | |
'zone_swing':'Z-Swing%', | |
'zone_contact':'Z-Contact%', | |
'chase_percent':'O-Swing%', | |
'chase_contact':'O-Contact%',} | |
plot_dict_small_pitch = { | |
'k':'K%', | |
'bb':'BB%', | |
'bb_minus_k':'BB%-K%', | |
'csw':'CSW%', | |
'woba':'wOBA', | |
'launch_speed':'Exit Velocity', | |
'launch_speed_90':'90th Percentile Exit Velocity', | |
'hard_hit':'HardHit%', | |
'sweet_spot':'SweetSpot%', | |
'launch_angle':'Launch Angle', | |
'zone_percent':'Zone%', | |
'barrel':'Barrel%', | |
'swing_percent':'Swing%', | |
'whiff_percent':'Whiff%', | |
'sw_str':'SwStr%', | |
'zone_swing':'Z-Swing%', | |
'zone_contact':'Z-Contact%', | |
'chase_percent':'O-Swing%', | |
'chase_contact':'O-Contact%',} | |
plot_dict_small_this_format = { | |
'k_percent':'{:,.1%}', | |
'bb_percent':'{:,.1%}', | |
'bb_minus_k_percent':'{:,.1%}', | |
'csw_percent':'{:,.1%}', | |
'woba_percent':'{:,.3f}', | |
'launch_speed':'{:,.1f}', | |
'launch_speed_90':'{:,.1f}', | |
'hard_hit_percent':'{:,.1%}', | |
'sweet_spot_percent':'{:,.1%}', | |
'launch_angle':'{:,.1f}', | |
'zone_percent':'{:,.1%}', | |
'barrel_percent':'{:,.1%}', | |
'swing_percent':'{:,.1%}', | |
'whiff_rate':'{:,.1%}', | |
'swstr_rate':'{:,.1%}', | |
'zone_swing_percent':'{:,.1%}', | |
'zone_contact_percent':'{:,.1%}', | |
'chase_percent':'{:,.1%}', | |
'chase_contact':'{:,.1%}',} | |
plot_dict_small_this_format_diff = { | |
'k_percent':'{0:+.1%}', | |
'bb_percent':'{0:+.1%}', | |
'bb_minus_k_percent':'{0:+.1%}', | |
'csw_percent':'{0:+.1%}', | |
'woba_percent':'{0:+.3f}', | |
'launch_speed':'{0:+.1f}', | |
'launch_speed_90':'{0:+.1f}', | |
'hard_hit_percent':'{0:+.1%}', | |
'sweet_spot_percent':'{0:+.1%}', | |
'launch_angle':'{0:+.1f}', | |
'zone_percent':'{0:+.1%}', | |
'barrel_percent':'{0:+.1%}', | |
'swing_percent':'{0:+.1%}', | |
'whiff_rate':'{0:+.1%}', | |
'swstr_rate':'{0:+.1%}', | |
'zone_swing_percent':'{0:+.1%}', | |
'zone_contact_percent':'{0:+.1%}', | |
'chase_percent':'{0:+.1%}', | |
'chase_contact':'{0:+.1%}',} | |
plot_dict_small_this_format_sorted = { | |
'k_percent':False, | |
'bb_percent':True, | |
'bb_minus_k_percent':True, | |
'csw_percent':False, | |
'woba_percent':True, | |
'launch_speed':True, | |
'launch_speed_90':True, | |
'hard_hit_percent':True, | |
'sweet_spot_percent':True, | |
'launch_angle':True, | |
'zone_percent':False, | |
'barrel_percent':True, | |
'swing_percent':True, | |
'whiff_rate':False, | |
'swstr_rate':False, | |
'zone_swing_percent':False, | |
'zone_contact_percent':True, | |
'chase_percent':False, | |
'chase_contact':True,} | |
team_list = ['All'] + sorted(list(exit_velo_df_codes_summ_batter.parent_org_abb.unique())) | |
sort_list = ['Season Stat','Timeframe Stat','Difference'] | |
team_list = ['All'] + sorted(list(exit_velo_df_codes_summ_batter.parent_org_abb.unique())) | |
sort_list = ['Season Stat','Timeframe Stat','Difference'] | |
from shiny import ui, render, App | |
import matplotlib.image as mpimg | |
# app_ui = ui.page_fluid( | |
# # ui.output_plot("plot"), | |
# #ui.h2('MLB Batter Launch Angle vs Exit Velocity'), | |
# ui.layout_sidebar( | |
# ui.panel_sidebar( | |
# ui.input_select("id", "Select Batter",batter_dict), | |
# ui.input_select("plot_id", "Select Plot",{'scatter':'Scatter Plot','dist':'Distribution Plot'}))) | |
# , | |
# ui.panel_main(ui.output_plot("plot",height = "750px",width="1250px")), | |
# #ui.download_button('test','Download'), | |
# ) | |
app_ui = ui.page_fluid(ui.layout_sidebar( | |
# Available themes: | |
# cerulean, cosmo, cyborg, darkly, flatly, journal, litera, lumen, lux, | |
# materia, minty, morph, pulse, quartz, sandstone, simplex, sketchy, slate, | |
# solar, spacelab, superhero, united, vapor, yeti, zephyr | |
ui.panel_sidebar(ui.input_date("x", "Date input",value=exit_velo_df_codes.date.min()), | |
ui.input_select("stat_id", "Select Stat",plot_dict_small_this_one,width=1), | |
ui.input_select("level_id", "Select Level",level_dict,width=1,multiple=True,selected='MLB',selectize=True), | |
ui.input_select("team_id", "Select Team",team_list,width=1,size=1,multiple=True,selected='All',selectize=True), | |
ui.input_select("sort_id", "Sort By",sort_list,width=1,size=1,selected='Timeframe Stat'), | |
ui.input_numeric("n", "Minimum PA", value=50), | |
ui.input_numeric("n_top", "Show top 'n'", value=0), | |
ui.input_switch("sort_order", "Ascending?"),), | |
ui.panel_main(ui.tags.h2("Batter Season Average vs Timeframe Average"), | |
ui.tags.h6("Created By: @TJStats, Data: MLB"), | |
ui.output_text("txt"), | |
ui.output_table("result")), | |
)) | |
# ui.row( | |
# ui.column( | |
# 3, | |
# ui.input_date("x", "Date input"),), | |
# ui.column( | |
# 1, | |
# ui.input_select("level_id", "Select Level",level_dict,width=1)), | |
# ui.column( | |
# 3, | |
# ui.input_select("stat_id", "Select Stat",plot_dict_small,width=1)), | |
# ui.column( | |
# 2, | |
# ui.input_numeric("n", "Rolling Window Size", value=50)), | |
# ), | |
# ui.output_table("result_batters")), | |
# ui.nav( | |
# "Pitchers", | |
# ui.row( | |
# ui.column( | |
# 3, | |
# ui.input_select("id_pitch", "Select Pitcher",pitcher_dict,width=1,selected=675911), | |
# ), | |
# ui.column( | |
# 1, | |
# ui.input_select("level_id_pitch", "Select Level",level_dict,width=1)), | |
# ui.column( | |
# 3, | |
# ui.input_select("stat_id_pitch", "Select Stat",plot_dict_small_pitch,width=1)), | |
# ui.column( | |
# 2, | |
# ui.input_numeric("n_pitch", "Rolling Window Size", value=50)), | |
# ), | |
# ui.output_table("result_pitchers")), | |
# ) | |
# ) | |
# ) | |
from urllib.request import Request, urlopen | |
# importing OpenCV(cv2) module | |
def server(input, output, session): | |
def txt(): | |
return f'Since: {input.x()} (min. {input.n()} PA)' | |
def result(): | |
exit_velo_df_codes_copy = exit_velo_df_codes.copy() | |
print(input.x()) | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_copy[exit_velo_df_codes_copy.date >= input.x()].groupby(['batter_id','batter','level']).agg( | |
pa = ('pa','sum'), | |
k = ('k','sum'), | |
bb = ('bb','sum'), | |
bb_minus_k = ('bb_minus_k','sum'), | |
csw = ('csw','sum'), | |
bip = ('bip','sum'), | |
tb = ('tb','sum'), | |
woba = ('woba','sum'), | |
woba_codes = ('woba_codes','sum'), | |
hard_hit = ('hard_hit','sum'), | |
barrel = ('barrel','sum'), | |
sweet_spot = ('sweet_spot','sum'), | |
max_launch_speed = ('launch_speed','max'), | |
launch_speed_90 = ('launch_speed',percentile(90)), | |
launch_speed = ('launch_speed','mean'), | |
launch_angle = ('launch_angle','mean'), | |
pitches = ('pitches','sum'), | |
swings = ('swings','sum'), | |
in_zone = ('in_zone','sum'), | |
out_zone = ('out_zone','sum'), | |
whiffs = ('whiffs','sum'), | |
zone_swing = ('zone_swing','sum'), | |
zone_contact = ('zone_contact','sum'), | |
ozone_swing = ('ozone_swing','sum'), | |
ozone_contact = ('ozone_contact','sum'), | |
).reset_index() | |
#exit_velo_df_codes_summ_time['out_zone'] = ~exit_velo_df_codes_summ_time.in_zone | |
#bip_min_input = int(input()) | |
#bip_min = min(bip_min_input,50) | |
#exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time[exit_velo_df_codes_summ_time.balls_in_play>=bip_min] | |
exit_velo_df_codes_summ_time['k_percent'] = [exit_velo_df_codes_summ_time.k[x]/exit_velo_df_codes_summ_time.pa[x] if exit_velo_df_codes_summ_time.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['bb_percent'] = [exit_velo_df_codes_summ_time.bb[x]/exit_velo_df_codes_summ_time.pa[x] if exit_velo_df_codes_summ_time.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['bb_minus_k_percent'] =[exit_velo_df_codes_summ_time.bb_minus_k[x]/exit_velo_df_codes_summ_time.pa[x] if exit_velo_df_codes_summ_time.pa[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['bb_over_obp'] = [exit_velo_df_codes_summ_time.bb[x]/exit_velo_df_codes_summ_time.k[x] if exit_velo_df_codes_summ_time.k[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['sweet_spot_percent'] = [exit_velo_df_codes_summ_time.sweet_spot[x]/exit_velo_df_codes_summ_time.bip[x] if exit_velo_df_codes_summ_time.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['woba_percent'] = [exit_velo_df_codes_summ_time.woba[x]/exit_velo_df_codes_summ_time.woba_codes[x] if exit_velo_df_codes_summ_time.woba_codes[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['hard_hit_percent'] = [exit_velo_df_codes_summ_time.hard_hit[x]/exit_velo_df_codes_summ_time.bip[x] if exit_velo_df_codes_summ_time.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['csw_percent'] = [exit_velo_df_codes_summ_time.csw[x]/exit_velo_df_codes_summ_time.pitches[x] if exit_velo_df_codes_summ_time.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['barrel_percent'] = exit_velo_df_codes_summ_time.barrel = [exit_velo_df_codes_summ_time.barrel[x]/exit_velo_df_codes_summ_time.bip[x] if exit_velo_df_codes_summ_time.bip[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['zone_contact_percent'] = [exit_velo_df_codes_summ_time.zone_contact[x]/exit_velo_df_codes_summ_time.zone_swing[x] if exit_velo_df_codes_summ_time.zone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['zone_swing_percent'] = [exit_velo_df_codes_summ_time.zone_swing[x]/exit_velo_df_codes_summ_time.in_zone[x] if exit_velo_df_codes_summ_time.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['zone_percent'] = [exit_velo_df_codes_summ_time.in_zone[x]/exit_velo_df_codes_summ_time.pitches[x] if exit_velo_df_codes_summ_time.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['chase_percent'] = [exit_velo_df_codes_summ_time.ozone_swing[x]/(exit_velo_df_codes_summ_time.pitches[x] - exit_velo_df_codes_summ_time.in_zone[x]) if (exit_velo_df_codes_summ_time.pitches[x]- exit_velo_df_codes_summ_time.in_zone[x]) != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['chase_contact'] = [exit_velo_df_codes_summ_time.ozone_contact[x]/exit_velo_df_codes_summ_time.ozone_swing[x] if exit_velo_df_codes_summ_time.ozone_swing[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['swing_percent'] = [exit_velo_df_codes_summ_time.swings[x]/exit_velo_df_codes_summ_time.pitches[x] if exit_velo_df_codes_summ_time.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['whiff_rate'] = [exit_velo_df_codes_summ_time.whiffs[x]/exit_velo_df_codes_summ_time.swings[x] if exit_velo_df_codes_summ_time.swings[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time['swstr_rate'] = [exit_velo_df_codes_summ_time.whiffs[x]/exit_velo_df_codes_summ_time.pitches[x] if exit_velo_df_codes_summ_time.pitches[x] != 0 else np.nan for x in range(len(exit_velo_df_codes_summ_time))] | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.dropna(subset=['bip']) | |
#exit_velo_df_codes_summ_time.columns = exit_velo_df_codes_summ_time.columns | |
#exit_velo_df_codes_summ_time['bb_minus_k_percent'] = exit_velo_df_codes_summ_time['bb_minus_k_percent'] | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_batter.merge(right = exit_velo_df_codes_summ_time, left_on=['batter_id','level'],right_on=['batter_id','level'],suffixes=['','_time'],how='left') | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time[exit_velo_df_codes_summ_time.level.isin(input.level_id())] | |
if not 'All' in input.team_id(): | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time[exit_velo_df_codes_summ_time.parent_org_abb.isin(input.team_id())] | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time[exit_velo_df_codes_summ_time.pa_time >= (input.n())] | |
# print(plot_dict_small_all[input.stat_id()]) | |
# print(pitcher_dict_stat[plot_dict_small_all[input.stat_id()]]['decimal_format']) | |
print(input.stat_id()) | |
print(plot_dict_small_all_input[input.stat_id()]) | |
exit_velo_df_codes_summ_time['Difference'] = exit_velo_df_codes_summ_time[input.stat_id()+'_time'] - exit_velo_df_codes_summ_time[input.stat_id()] | |
# print(format_column) | |
format_column = plot_dict_small_this_format[input.stat_id()] | |
format_column_diff = plot_dict_small_this_format_diff[input.stat_id()] | |
print('Difference',format_column) | |
if input.sort_id() == 'Difference': | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.sort_values(by='Difference',ascending=input.sort_order()) | |
exit_velo_df_codes_summ_time['Rank'] = exit_velo_df_codes_summ_time['Difference'].rank(ascending=input.sort_order(),method='min') | |
if input.sort_id() == 'Season Stat': | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.sort_values(by=input.stat_id(),ascending=input.sort_order()) | |
exit_velo_df_codes_summ_time['Rank'] = exit_velo_df_codes_summ_time[input.stat_id()].rank(ascending=input.sort_order(),method='min') | |
if input.sort_id() == 'Timeframe Stat': | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.sort_values(by=input.stat_id()+'_time',ascending=input.sort_order()) | |
exit_velo_df_codes_summ_time['Rank'] = exit_velo_df_codes_summ_time[input.stat_id()+'_time'].rank(ascending=input.sort_order(),method='min') | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.round(3) | |
exit_velo_df_codes_summ_time.pa = exit_velo_df_codes_summ_time.pa.astype(int) | |
exit_velo_df_codes_summ_time.pa_time = exit_velo_df_codes_summ_time.pa_time.astype(int) | |
exit_velo_df_codes_summ_time.Rank = exit_velo_df_codes_summ_time.Rank.astype(int) | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.rename(columns={'batter_id':'Batter ID','parent_org_abb':'Team','batter':'Batter','pa':'PA','level':'Level',input.stat_id():plot_dict_small_this_one[input.stat_id()], | |
'pa_time':'PA Since',input.stat_id()+'_time':plot_dict_small_this_one[input.stat_id()]+' Since'}) | |
exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.drop_duplicates(subset=['Batter ID','Level']) | |
print(plot_dict_small_this_one[input.stat_id()]+' Since') | |
# exit_velo_df_codes_summ_time = exit_velo_df_codes_summ_time.to_string(formatters={ | |
# 'PA': '{:,.0f}'.format, | |
# 'PA Since': '{:,.0f}'.format, | |
# plot_dict_small[input.stat_id()]: format_column.format, | |
# plot_dict_small[input.stat_id()]+' Since': format_column.format, | |
# 'Difference': format_column.format | |
# }) | |
# exit_velo_df_codes_summ_time[plot_dict_small_this_one[input.stat_id()]] = exit_velo_df_codes_summ_time[plot_dict_small_this_one[input.stat_id()]].map(format_column.format) | |
# exit_velo_df_codes_summ_time[plot_dict_small_this_one[input.stat_id()]+' Since'] = exit_velo_df_codes_summ_time[plot_dict_small_this_one[input.stat_id()]+' Since'].map(format_column.format) | |
# exit_velo_df_codes_summ_time['Difference'] = exit_velo_df_codes_summ_time['Difference'].map(format_column_diff.format) | |
exit_velo_df_codes_summ_time_style_setting = exit_velo_df_codes_summ_time[['Rank','Batter ID','Batter','Team','Level','PA',plot_dict_small_this_one[input.stat_id()], | |
'PA Since',plot_dict_small_this_one[input.stat_id()]+' Since', | |
'Difference']] | |
df_min_max = exit_velo_df_codes_summ_time_style_setting.copy() | |
if int(input.n_top()) > 0: | |
exit_velo_df_codes_summ_time_style_setting = exit_velo_df_codes_summ_time_style_setting.head(int(input.n_top())) | |
# exit_velo_df_codes_summ_time_style = exit_velo_df_codes_summ_time[['Rank','Pitcher ID','Pitcher','Team','Level','PA',plot_dict_small_this_one[input.stat_id()], | |
# 'PA Since',plot_dict_small_this_one[input.stat_id()]+' Since', | |
# 'Difference']] | |
#exit_velo_df_codes_summ_time_style = exit_velo_df_codes_summ_time.copy() | |
exit_velo_df_codes_summ_time_style_set = exit_velo_df_codes_summ_time_style_setting.style.set_properties(**{'border': '1 px'},overwrite=False).set_table_styles([{ | |
'selector': 'caption', | |
'props': [ | |
('color', ''), | |
('fontname', 'Century Gothic'), | |
('font-size', '16px'), | |
('font-style', 'italic'), | |
('font-weight', ''), | |
('text-align', 'centre'), | |
] | |
},{'selector' :'th', 'props':[('text-align', 'center'),('Height','24px'),('border', '1 px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '16px')]}],overwrite=False).set_table_styles( | |
[{'selector': 'tr', 'props': [('line-height', '1px')]}],overwrite=False).set_properties( | |
**{'Height': '28px'},**{'text-align': 'center'},overwrite=False).hide_index().format( | |
{ | |
plot_dict_small_this_one[input.stat_id()]: format_column, | |
plot_dict_small_this_one[input.stat_id()]+' Since': format_column, | |
"Difference":format_column_diff, | |
}) | |
if plot_dict_small_this_format_sorted[input.stat_id()]: | |
cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#4285f4","#FFFFFF","#F0E442"]) | |
else: | |
cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#F0E442","#FFFFFF","#4285f4"]) | |
exit_velo_df_codes_summ_time_style_set = exit_velo_df_codes_summ_time_style_set.background_gradient(cmap=cmap_sum,subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:]),exit_velo_df_codes_summ_time_style_set.columns[-1])),vmin=df_min_max[df_min_max.columns[-1]].min(),vmax=df_min_max[df_min_max.columns[-1]].max()) | |
exit_velo_df_codes_summ_time_style_set = exit_velo_df_codes_summ_time_style_set.background_gradient(cmap=cmap_sum,subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:]),exit_velo_df_codes_summ_time_style_set.columns[-2])),vmin=df_min_max[df_min_max.columns[-2]].min(),vmax=df_min_max[df_min_max.columns[-2]].max()) | |
exit_velo_df_codes_summ_time_style_set = exit_velo_df_codes_summ_time_style_set.background_gradient(cmap=cmap_sum,subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:]),exit_velo_df_codes_summ_time_style_set.columns[-4])),vmin=df_min_max[df_min_max.columns[-4]].min(),vmax=df_min_max[df_min_max.columns[-4]].max()) | |
exit_velo_df_codes_summ_time_style_set = exit_velo_df_codes_summ_time_style_set.set_properties( | |
**{'border': '1px black solid !important'},subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:-1]),exit_velo_df_codes_summ_time_style_set.columns[:]))).set_properties( | |
#**{'font-weight': 'bold'},subset = ((list(exit_velo_df_codes_summ_time_style.index[:]),exit_velo_df_codes_summ_time_style.columns[:4]))).set_properties( | |
**{'min-width':'100px'},subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:-1]),exit_velo_df_codes_summ_time_style_set.columns[1])),overwrite=False).set_properties( | |
**{'min-width':'150px'},subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:-1]),exit_velo_df_codes_summ_time_style_set.columns[2])),overwrite=False).set_properties( | |
**{'min-width':'85px'},subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:-1]),exit_velo_df_codes_summ_time_style_set.columns[3:])),overwrite=False).set_properties( | |
**{'border': '1px black solid !important'},subset = ((list(exit_velo_df_codes_summ_time_style_set.index[:]),exit_velo_df_codes_summ_time_style_set.columns[:]))) | |
return exit_velo_df_codes_summ_time_style_set | |
# @output | |
# @render.plot(alt="A histogram") | |
# def plot_pitch(): | |
# p | |
app = App(app_ui, server) |