nesticot's picture
Update app.py
66f7ba6
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):
@output
@render.text
def txt():
return f'Since: {input.x()} (min. {input.n()} PA)'
@output
@render.table
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)