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 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 datetime import date
datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y')
# Configure Notebook
#%matplotlib inline
plt.style.use('fivethirtyeight')
sns.set_context("notebook")
import warnings
warnings.filterwarnings('ignore')
#from urllib.request import urlopen
import json
from datetime import date, timedelta
#import dataframe_image as dfi
#from os import listdir
#from os.path import isfile, join
import datetime
import seaborn as sns
import os
import calendar
#from IPython.display import display, HTML
import matplotlib.image as mpimg
#from skimage import io
#import difflib
from datetime import datetime
import pytz
datetime.now(pytz.timezone('US/Pacific')).strftime('%B %d, %Y')
# Configure Notebook
#%matplotlib inline
plt.style.use('fivethirtyeight')
sns.set_context("notebook")
import warnings
warnings.filterwarnings('ignore')
# import yfpy
# from yfpy.query import YahooFantasySportsQuery
# import yahoo_oauth
import json
#import openpyxl
#from sklearn import preprocessing
from PIL import Image
import logging
import matplotlib.patches as patches
from matplotlib.patches import Rectangle
from matplotlib.font_manager import FontProperties
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import requests
#import pickle
import pandas as pd
# # Loop over the counter and format the API call
r = requests.get('https://statsapi.web.nhl.com/api/v1/schedule?startDate=2023-10-01&endDate=2024-06-01')
schedule = r.json()
def flatten(t):
return [item for sublist in t for item in sublist]
game_id = flatten([[x['gamePk'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
game_date = flatten([[x['gameDate'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
game_home = flatten([[x['teams']['home']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
game_away = flatten([[x['teams']['away']['team']['name'] for x in schedule['dates'][y]['games']] for y in range(0,len(schedule['dates']))])
schedule_df = pd.DataFrame(data={'game_id': game_id, 'game_date' : game_date, 'game_home' : game_home, 'game_away' : game_away})
schedule_df.game_date = pd.to_datetime(schedule_df['game_date']).dt.tz_convert(tz='US/Eastern').dt.date
schedule_df = schedule_df.replace('Montréal Canadiens','Montreal Canadiens')
schedule_df.head()
team_abv = pd.read_csv('team_abv.csv')
yahoo_weeks = pd.read_csv('yahoo_weeks.csv')
#yahoo_weeks['Number'] = yahoo_weeks['Number'].astype(int)
yahoo_weeks['Start'] = pd.to_datetime(yahoo_weeks['Start'])
yahoo_weeks['End'] = pd.to_datetime(yahoo_weeks['End'])
yahoo_weeks.head(5)
def highlight_cols(s):
color = '#C2FEE9'
return 'background-color: %s' % color
def highlight_cells(val):
color = 'white' if val == ' ' else ''
return 'background-color: {}'.format(color)
import matplotlib.pyplot as plt
import matplotlib.colors
cmap_total = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#56B4E9","#FFFFFF","#F0E442"])
cmap_off = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"])
cmap_back = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#56B4E9"])
cmap_sum = matplotlib.colors.LinearSegmentedColormap.from_list("", ["#FFFFFF","#F0E442"])
schedule_df = schedule_df.merge(right=team_abv,left_on='game_away',right_on='team_name',how='inner',suffixes=['','_away'])
schedule_df = schedule_df.merge(right=team_abv,left_on='game_home',right_on='team_name',how='inner',suffixes=['','_home'])
schedule_df['away_sym'] = '@'
schedule_df['home_sym'] = 'vs'
if not os.path.isfile('standings/standings_'+str(date.today())+'.csv'):
standings_df_old = pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[0].append(pd.read_html('https://www.hockey-reference.com/leagues/NHL_2023_standings.html')[1])
standings_df_old.to_csv('standings/standings_'+str(date.today())+'.csv')
standings_df_old = pd.read_csv('standings/standings_'+str(date.today())+'.csv',index_col=[0])
standings_df = standings_df_old[standings_df_old['Unnamed: 0'].str[-8:] != 'Division'].sort_values('Unnamed: 0').reset_index(drop=True).rename(columns={'Unnamed: 0':'Team'})#.drop(columns='Unnamed: 0')
#standings_df = standings_df.replace('St. Louis Blues','St Louis Blues')
standings_df['GF/GP'] = standings_df['GF'].astype(int)/standings_df['GP'].astype(int)
standings_df['GA/GP'] = standings_df['GA'].astype(int)/standings_df['GP'].astype(int)
standings_df['GF_Rank'] = standings_df['GF/GP'].rank(ascending=True,method='first')/10-1.65
standings_df['GA_Rank'] = standings_df['GA/GP'].rank(ascending=False,method='first')/10-1.65
standings_df.Team = standings_df.Team.str.strip('*')
standings_df = standings_df.merge(right=team_abv,left_on='Team',right_on='team_name')
schedule_stack = pd.DataFrame()
schedule_stack['date'] = pd.to_datetime(list(schedule_df['game_date'])+list(schedule_df['game_date']))
schedule_stack['team'] = list(schedule_df['team_name'])+list(schedule_df['team_name_home'])
schedule_stack['team_abv'] = list(schedule_df['team_abv'])+list(schedule_df['team_abv_home'])
schedule_stack['symbol'] = list(schedule_df['away_sym'])+list(schedule_df['home_sym'])
schedule_stack['team_opponent'] = list(schedule_df['team_name_home'])+list(schedule_df['team_name'])
schedule_stack['team_abv_home'] = list(schedule_df['team_abv_home'])+list(schedule_df['team_abv'])
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y'))
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y'))
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GF_Rank']],left_on='team_abv',right_on='team_abv',how='inner',suffixes=("",'_y'))
schedule_stack = schedule_stack.merge(right=standings_df[['team_abv','GA_Rank']],left_on='team_abv_home',right_on='team_abv',how='inner',suffixes=("",'_y'))
list_o = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True)
new_list = [x - y for x, y in zip(list_o['date'][1:], list_o['date'])]
b2b_list = [0] + [x.days for x in new_list]
b2b_list = [1 if x==1 else 0 for x in b2b_list]
test = list(schedule_stack.groupby(by='date').count()['team'])
offnight = [1 if x<15 else 0 for x in test]
offnight_df = pd.DataFrame({'date':schedule_stack.sort_values('date').date.unique(),'offnight':offnight}).sort_values('date').reset_index(drop=True)
schedule_stack = schedule_stack.merge(right=offnight_df,left_on='date',right_on='date',how='right')
schedule_stack = schedule_stack.sort_values(['team','date'],ascending=[True,True]).reset_index(drop=True)
schedule_stack['b2b'] = b2b_list
schedule_stack.date = pd.to_datetime(schedule_stack.date)
away_b2b = []
home_b2b = []
for i in range(0,len(schedule_stack)):
away_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team_opponent[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0])
home_b2b.append(schedule_stack[(schedule_stack.date[i]==schedule_stack.date)&(schedule_stack.team[i]==schedule_stack.team)].reset_index(drop=True)['b2b'][0])
schedule_stack['away_b2b'] = away_b2b
schedule_stack['home_b2b'] = home_b2b
schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(1,' 😴')
schedule_stack['away_b2b'] = schedule_stack['away_b2b'].replace(0,'')
schedule_stack.head()
FontProperties(fname='/System/Library/Fonts/Apple Color Emoji.ttc')
data_r = requests.get("https://pub-api-ro.fantasysports.yahoo.com/fantasy/v2/league/427.l.public;out=settings/players;position=ALL;start=0;count=3000;sort=rank_season;search=;out=percent_owned;out=auction_values,ranks;ranks=season;ranks_by_position=season;out=expert_ranks;expert_ranks.rank_type=projected_season_remaining/draft_analysis;cut_types=diamond;slices=last7days?format=json_f").json()
total_list = []
for x in data_r['fantasy_content']['league']['players']:
single_list = []
single_list.append(int(x['player']['player_id']))
single_list.append(int(x['player']['player_ranks'][0]['player_rank']['rank_value']))
single_list.append(x['player']['name']['full'])
single_list.append(x['player']['name']['first'])
single_list.append(x['player']['name']['last'])
single_list.append(x['player']['draft_analysis']['average_pick'])
single_list.append(x['player']['average_auction_cost'])
single_list.append(x['player']['display_position'])
single_list.append(x['player']['editorial_team_abbr'])
if 'value' in x['player']['percent_owned']:
single_list.append(x['player']['percent_owned']['value']/100)
else:
single_list.append(0)
total_list.append(single_list)
df_2023 = pd.DataFrame(data=total_list,columns=['player_id','rank_value','full','first','last','average_pick', 'average_cost','display_position','editorial_team_abbr','percent_owned'])
week_dict = yahoo_weeks.set_index('Number')['Week'].sort_index().to_dict()
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_select("week_id", "Select Week (Set as Season for Custom Date Range)",week_dict,width=1),
ui.input_select("sort_id", "Sort Column",['Score','Team','Total','Off-Night','B2B'],width=1),
ui.input_switch("a_d_id", "Ascending?"),
#ui.input_select("date_id", "Select Date",yahoo_weeks['Week'],width=1),
ui.input_date_range("date_range_id", "Date range input",start = datetime.today().date(), end = datetime.today().date() + timedelta(days=6)),
ui.output_table("result"),width=3),
ui.panel_main(ui.tags.h3(""),
ui.div({"style": "font-size:2em;"},ui.output_text("txt_title")),
#ui.tags.h2("Fantasy Hockey Schedule Summary"),
ui.tags.h5("Created By: @TJStats, Data: NHL"),
ui.div({"style": "font-size:1.2em;"},ui.output_text("txt")),
ui.output_table("schedule_result"),
ui.tags.h5('Legend'),
ui.output_table("schedule_result_legend"),
ui.tags.h6('An Off Night is defined as a day in which less than half the teams in the NHL are playing'),
ui.tags.h6('The scores are determined by using games played, off-nights, B2B, and strength of opponents') )
))
# 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():
week_set = int(input.week_id())
if week_set != 0:
if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['Start'].values[0]).year != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]['End'].values[0]).year:
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d, %Y")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}'
else:
if pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).month != pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).month:
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%B %d, %Y")}'
else:
return f'{pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["Start"].values[0]).strftime("%B %d")} to {pd.to_datetime(yahoo_weeks[yahoo_weeks.Number == week_set]["End"].values[0]).strftime("%d, %Y")}'
else:
if input.date_range_id()[0].year != input.date_range_id()[1].year:
return f'{input.date_range_id()[0].strftime("%B %d, %Y")} to {input.date_range_id()[1].strftime("%B %d, %Y")}'
else:
if input.date_range_id()[0].month != input.date_range_id()[1].month:
return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%B %d, %Y")}'
else:
return f'{input.date_range_id()[0].strftime("%B %d")} to {input.date_range_id()[1].strftime("%d, %Y")}'
@output
@render.text
def txt_title():
week_set = int(input.week_id())
if week_set != 0:
return f'Fantasy Hockey Schedule Summary - Yahoo - Week {input.week_id()}'
else:
return f'Fantasy Hockey Schedule Summary'
@output
@render.table
def result():
#print(yahoo_weeks)
return yahoo_weeks
@output
@render.table
def schedule_result():
week_set = int(input.week_id())
print(week_set)
if week_set == 0:
start_point = input.date_range_id()[0]
end_point = input.date_range_id()[1]
else:
start_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['Start'][0]
end_point = yahoo_weeks[yahoo_weeks.Number==week_set].reset_index(drop=True)['End'][0]
sort_value='Score'
ascend=False
weekly_stack = schedule_stack[(schedule_stack['date'].dt.date>=start_point)&(schedule_stack['date'].dt.date<=end_point)]
date_list = pd.date_range(start_point,end_point,freq='d')
test_list = [[]] * len(date_list)
for i in range(0,len(date_list)):
test_list[i] = team_abv.merge(right=weekly_stack[weekly_stack['date']==date_list[i]],left_on='team_abv',right_on='team_abv',how='left')
test_list[i] = test_list[i].fillna("")
test_list[i]['new_text'] = test_list[i]['symbol'] + ' '+ test_list[i]['team_abv_home'] + test_list[i]['away_b2b']
test_df = pd.DataFrame()
test_df['Team'] = list(team_abv['team_abv'])
test_df['Total'] = test_df.merge(right=weekly_stack.groupby('team_abv')['team_abv'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['team_abv']
test_df['Off-Night'] = test_df.merge(right=weekly_stack.groupby('team_abv').sum()['offnight'],left_on=['Team'],right_index=True,how='left').fillna(0)['offnight']
test_df['B2B']= test_df.merge(right=weekly_stack.groupby('team_abv').sum()['b2b'],left_on=['Team'],right_index=True,how='left').fillna(0)['b2b']
gf_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GF_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GF_Rank'])
ga_rank = np.array(test_df.merge(right=weekly_stack.groupby('team_abv').mean()['GA_Rank'],left_on=['Team'],right_index=True,how='left').fillna(0)['GA_Rank'])
#games_vs_tired = np.array([float(i)*0.4 for i in list(weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()))])
games_vs_tired = 0.4*np.array(test_df.merge(right=weekly_stack.groupby('team_abv')['away_b2b'].apply(lambda x: x[x != ''].count()),left_on=['Team'],right_index=True,how='left').fillna(0)['away_b2b'])
team_score = test_df['Total']+test_df['Off-Night']*0.5+test_df['B2B']*-0.2+games_vs_tired*0.3+gf_rank*0.1+ga_rank*0.1
test_df['Score'] = team_score
cols = test_df.columns.tolist();
L = len(cols)
test_df = test_df[cols[4:]+cols[0:4]]
#return test_df#[cols[4:]+cols[0:4]]
test_df = test_df.sort_values(by=[sort_value,'Score'],ascending = ascend)
for i in range(0,len(date_list)):
test_df[calendar.day_name[date_list[i].weekday()]+'
'+str(date_list[i].month)+'-'+'{:02d}'.format(date_list[i].day)] = test_list[i]['new_text']
row = ['']*L
for x in test_df[test_df.columns[L:]]:
row.append(int(sum(test_df[x]!=" ")/2))
test_df = test_df.sort_values(by=input.sort_id(),ascending=input.a_d_id())
test_df.loc[32] = row
#test_df_html = HTML( test_df.to_html().replace("\\n","
") )
offnight_list = [True if x <8 else False for x in test_df.iloc[-1][L:]]
test_df.style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list])))
test_df_style = test_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{
'selector': 'caption',
'props': [
('color', ''),
('fontname', 'Century Gothic'),
('font-size', '20px'),
('font-style', 'italic'),
('font-weight', ''),
('text-align', 'centre'),
]
},{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),('border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties(
**{'background-color':'White','index':'White','min-width':'75px'},overwrite=False).set_properties(
**{'background-color':'White','index':'White','min-width':'100px'},overwrite=False,subset = ((list(test_df.index[:]),test_df.columns[5:]))).set_table_styles(
[{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
[{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
[{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties(
**{'Height': '8px'},**{'text-align': 'center'},overwrite=False).hide_index()
test_df_style = test_df_style.applymap(highlight_cols,subset = ((list(test_df.index[:-1]),test_df.columns[L:][offnight_list])))
test_df_style = test_df_style.applymap(highlight_cells)
test_df_style = test_df_style.background_gradient(cmap=cmap_total,subset = ((list(test_df.index[:-1]),test_df.columns[0])))
test_df_style = test_df_style.background_gradient(cmap=cmap_total,vmin=0,vmax=np.max(test_df.Total[:len(test_df)-1]),subset = ((list(test_df.index[:-1]),test_df.columns[2])))
test_df_style = test_df_style.background_gradient(cmap=cmap_off,subset = ((list(test_df.index[:-1]),test_df.columns[3])))
test_df_style = test_df_style.background_gradient(cmap=cmap_back,subset = ((list(test_df.index[:-1]),test_df.columns[4])))
test_df_style = test_df_style.background_gradient(cmap=cmap_sum,subset = ((list(test_df.index[-1:]),test_df.columns[L:])),axis=1)
test_df_style = test_df_style.set_properties(
**{'border': '1px black solid !important'},subset = ((list(test_df.index[:-1]),test_df.columns[:]))).set_properties(
**{'min-width':'85px'},subset = ((list(test_df.index[:-1]),test_df.columns[L:])),overwrite=False).set_properties(**{
'color': 'black'},overwrite=False).set_properties(
**{'border': '1px black solid !important'},subset = ((list(test_df.index[:]),test_df.columns[L:])))
test_df_style = test_df_style.format(
'{:.0f}',subset=(test_df.index[:-1],test_df.columns[2:L]))
test_df_style = test_df_style.format(
'{:.1f}',subset=(test_df.index[:-1],test_df.columns[0]))
print('made it to teh end')
return test_df_style
#return exit_velo_df_codes_summ_time_style_set
# @output
# @render.plot(alt="A histogram")
# def plot_pitch():
# p
@output
@render.table
def schedule_result_legend():
off_b2b_df = pd.DataFrame(data={'off':'Off-Night','b2b':'Tired Opp. 😴'},index=[0])
#off_b2b_df.style.applymap(highlight_cols,subset = ((list(off_b2b_df.index[:-1]),off_b2b_df.columns[0])))
off_b2b_df_style = off_b2b_df.style.set_properties(**{'border': '3 px'},overwrite=False).set_table_styles([{
'selector': 'caption',
'props': [
('color', ''),
('fontname', 'Century Gothic'),
('font-size', '20px'),
('font-style', 'italic'),
('font-weight', ''),
('text-align', 'centre'),
]
},{'selector' :'th', 'props':[('text-align', 'center'),('Height','px'),('color','black'),(
'border', '1px black solid !important')]},{'selector' :'td', 'props':[('text-align', 'center'),('font-size', '18px'),('color','black')]}],overwrite=False).set_properties(
**{'background-color':'White','index':'White','min-width':'150px'},overwrite=False).set_table_styles(
[{'selector': 'th:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
[{'selector': 'tr:first-child', 'props': [('background-color', 'white')]}],overwrite=False).set_table_styles(
[{'selector': 'tr', 'props': [('line-height', '20px')]}],overwrite=False).set_properties(
**{'Height': '8px'},**{'text-align': 'center'},overwrite=False).set_properties(
**{'background-color':'#C2FEE9'},subset=off_b2b_df.columns[0]).set_properties(
**{'color':'black'},subset=off_b2b_df.columns[:]).hide_index().set_table_styles([
{'selector': 'thead', 'props': [('display', 'none')]}
]).set_properties(**{'border': '3 px','color':'black'},overwrite=False).set_properties(
**{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:]))).set_properties(
**{'min-width':'130'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:])),overwrite=False).set_properties(**{
'color': 'black'},overwrite=False).set_properties(
**{'border': '1px black solid !important'},subset = ((list(off_b2b_df.index[:]),off_b2b_df.columns[:])))
return off_b2b_df_style
app = App(app_ui, server)