Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -206,25 +206,6 @@ team_abb_df = pd.DataFrame({'mlb_team':team_abb_list,'yahoo_team':team_abb_list_
|
|
| 206 |
from shiny import App, ui, render
|
| 207 |
import pandas as pd
|
| 208 |
|
| 209 |
-
# Create sample data for the tables
|
| 210 |
-
data1 = pd.DataFrame({
|
| 211 |
-
'Name': ['Alice', 'Bob', 'Charlie'],
|
| 212 |
-
'Age': [25, 30, 35],
|
| 213 |
-
'City': ['New York', 'London', 'Paris']
|
| 214 |
-
})
|
| 215 |
-
|
| 216 |
-
data2 = pd.DataFrame({
|
| 217 |
-
'Product': ['Laptop', 'Phone', 'Tablet'],
|
| 218 |
-
'Price': [1200, 800, 500],
|
| 219 |
-
'Stock': [50, 100, 75]
|
| 220 |
-
})
|
| 221 |
-
|
| 222 |
-
data3 = pd.DataFrame({
|
| 223 |
-
'Country': ['USA', 'UK', 'France'],
|
| 224 |
-
'Population': ['331M', '67M', '67M'],
|
| 225 |
-
'Language': ['English', 'English', 'French']
|
| 226 |
-
})
|
| 227 |
-
|
| 228 |
app_ui = ui.page_sidebar(
|
| 229 |
|
| 230 |
ui.sidebar(
|
|
@@ -234,6 +215,7 @@ app_ui = ui.page_sidebar(
|
|
| 234 |
"Select Team",
|
| 235 |
choices=teams_name_dict
|
| 236 |
),
|
|
|
|
| 237 |
# ui.hr(), # Add a horizontal line for separation
|
| 238 |
ui.div(
|
| 239 |
|
|
@@ -284,13 +266,32 @@ app_ui = ui.page_sidebar(
|
|
| 284 |
"Fantasy Eligibility",
|
| 285 |
ui.div({"style": "font-size:1.7em;"}, ui.output_text("fantasy_title")),
|
| 286 |
ui.output_table("table3")
|
| 287 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 288 |
)
|
| 289 |
)
|
| 290 |
)
|
| 291 |
|
| 292 |
def server(input, output, session):
|
| 293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
@render.text
|
| 295 |
def lineup_title():
|
| 296 |
|
|
@@ -306,6 +307,11 @@ def server(input, output, session):
|
|
| 306 |
|
| 307 |
return f"{teams_name_dict[int(input.team_id())]} Spring Training Position Eligibility Tracker - Yahoo"
|
| 308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
|
| 310 |
@reactive.calc
|
| 311 |
def cached_data():
|
|
@@ -913,4 +919,140 @@ def server(input, output, session):
|
|
| 913 |
)
|
| 914 |
return df_yahoo_style
|
| 915 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 916 |
app = App(app_ui, server)
|
|
|
|
| 206 |
from shiny import App, ui, render
|
| 207 |
import pandas as pd
|
| 208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
app_ui = ui.page_sidebar(
|
| 210 |
|
| 211 |
ui.sidebar(
|
|
|
|
| 215 |
"Select Team",
|
| 216 |
choices=teams_name_dict
|
| 217 |
),
|
| 218 |
+
ui.output_ui("player_select"),
|
| 219 |
# ui.hr(), # Add a horizontal line for separation
|
| 220 |
ui.div(
|
| 221 |
|
|
|
|
| 266 |
"Fantasy Eligibility",
|
| 267 |
ui.div({"style": "font-size:1.7em;"}, ui.output_text("fantasy_title")),
|
| 268 |
ui.output_table("table3")
|
| 269 |
+
),
|
| 270 |
+
ui.nav_panel(
|
| 271 |
+
"Player Teammates",
|
| 272 |
+
ui.div({"style": "font-size:1.7em;"}, ui.output_text("player_title")),
|
| 273 |
+
ui.output_table("table4")
|
| 274 |
+
)
|
| 275 |
)
|
| 276 |
)
|
| 277 |
)
|
| 278 |
|
| 279 |
def server(input, output, session):
|
| 280 |
|
| 281 |
+
@render.ui
|
| 282 |
+
def player_select():
|
| 283 |
+
df,batting_order_full_opp,statcast_dict = cached_data()
|
| 284 |
+
df = df.sort(['Player'])
|
| 285 |
+
player_dict = dict(zip(df['Player ID'],df['Player']))
|
| 286 |
+
|
| 287 |
+
return ui.input_select(
|
| 288 |
+
"player_select",
|
| 289 |
+
f"Select Player",
|
| 290 |
+
choices=player_dict
|
| 291 |
+
)
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
|
| 295 |
@render.text
|
| 296 |
def lineup_title():
|
| 297 |
|
|
|
|
| 307 |
|
| 308 |
return f"{teams_name_dict[int(input.team_id())]} Spring Training Position Eligibility Tracker - Yahoo"
|
| 309 |
|
| 310 |
+
@render.text
|
| 311 |
+
def player_title():
|
| 312 |
+
|
| 313 |
+
return f"{teams_name_dict[int(input.team_id())]} Spring Training Teammate Summary"
|
| 314 |
+
|
| 315 |
|
| 316 |
@reactive.calc
|
| 317 |
def cached_data():
|
|
|
|
| 919 |
)
|
| 920 |
return df_yahoo_style
|
| 921 |
|
| 922 |
+
|
| 923 |
+
|
| 924 |
+
@output
|
| 925 |
+
@render.table
|
| 926 |
+
def table4():
|
| 927 |
+
df_test_merge_small,batting_order_full_opp,statcast_dict = cached_data()
|
| 928 |
+
player_dict = dict(zip(df_test_merge_small['Player ID'],df_test_merge_small['Player']))
|
| 929 |
+
|
| 930 |
+
import polars as pl
|
| 931 |
+
|
| 932 |
+
df_test_merge_small = df_test_merge_small.with_columns(
|
| 933 |
+
pl.col("Home").replace({"home": "H", "away": "A"})
|
| 934 |
+
)
|
| 935 |
+
print(df_test_merge_small)
|
| 936 |
+
if df_test_merge_small is None:
|
| 937 |
+
return pd.DataFrame({"Message": ["No Games as of this time"]})
|
| 938 |
+
|
| 939 |
+
df_selected_player_games = df_test_merge_small.filter(pl.col('Player ID') == input.player_select())['Game ID'].unique()
|
| 940 |
+
|
| 941 |
+
df_test_merge_small = df_test_merge_small.filter(pl.col('Game ID').is_in(df_selected_player_games))
|
| 942 |
+
|
| 943 |
+
|
| 944 |
+
|
| 945 |
+
df_test_merge_small = df_test_merge_small.with_columns(
|
| 946 |
+
pl.lit(input.player_select()).alias('Selected Player ID'),
|
| 947 |
+
pl.lit(player_dict[input.player_select()]).alias('Selected Player')
|
| 948 |
+
)
|
| 949 |
+
|
| 950 |
+
df_pivot_sum = df_test_merge_small.group_by(['Selected Player ID','Selected Player', 'Player']).agg([
|
| 951 |
+
pl.sum('count').alias('GP')]).sort('GP',descending=True)
|
| 952 |
+
|
| 953 |
+
# df_pivot_sum = df_pivot_sum.filter(pl.col('Player') != pl.col('Selected Player'))
|
| 954 |
+
|
| 955 |
+
df_pivot_sum = df_pivot_sum.with_columns(
|
| 956 |
+
pl.when(pl.col('Player') == pl.col('Selected Player'))
|
| 957 |
+
.then(pl.lit(1))
|
| 958 |
+
.otherwise(pl.lit(0))
|
| 959 |
+
.alias('is_selected')
|
| 960 |
+
).sort(['is_selected', 'GP'], descending=[True, True]).drop('is_selected')
|
| 961 |
+
|
| 962 |
+
df_pivot_sum = df_pivot_sum.with_columns(pl.col('GP').cast(pl.Float64))
|
| 963 |
+
|
| 964 |
+
|
| 965 |
+
df_pivot_sum_pd = df_pivot_sum.to_pandas()
|
| 966 |
+
|
| 967 |
+
df_pivot_sum_pd.iloc[1:, 0] = ''
|
| 968 |
+
df_pivot_sum_pd.iloc[1:, 1] = ''
|
| 969 |
+
|
| 970 |
+
|
| 971 |
+
|
| 972 |
+
|
| 973 |
+
norm = plt.Normalize(vmin=0, vmax=df_pivot_sum_pd['GP'].max())
|
| 974 |
+
def apply_gradient(val):
|
| 975 |
+
if isinstance(val, float): # Check if the value is an integer
|
| 976 |
+
# Normalize the integer for the gradient
|
| 977 |
+
return f'background-color: {mcolors.to_hex(cmap_up(norm(val)))}'
|
| 978 |
+
return '' # No background for non-integer values
|
| 979 |
+
def add_bottom_border(s):
|
| 980 |
+
return ['border-bottom: 1px solid black' if i == len(s) - 1 else '' for i in range(len(s))]
|
| 981 |
+
|
| 982 |
+
df_yahoo_style = (df_pivot_sum_pd.style.set_precision(0)
|
| 983 |
+
.set_table_styles(
|
| 984 |
+
[
|
| 985 |
+
|
| 986 |
+
# {"selector": "td:nth-child(2)", "props": [("border-right", "3px solid black")]}, # Thick right border for the 3rd column
|
| 987 |
+
# {"selector": "td:nth-child(4)", "props": [("border-right", "3px solid black")]},
|
| 988 |
+
# {"selector": "td:nth-child(14)", "props": [("border-right", "3px solid black")]},
|
| 989 |
+
|
| 990 |
+
# {'selector': 'thead th:nth-child(5)', 'props': [('border-right', '3px solid black')]},
|
| 991 |
+
# {'selector': 'thead th:nth-child(6)', 'props': [('border-right', '3px solid black')]}, # Thick right border for the 3rd header
|
| 992 |
+
# {'selector': 'thead th:nth-child(14)', 'props': [('border-right', '3px solid black')]}, # Thick right border for the 3rd header
|
| 993 |
+
|
| 994 |
+
# {'selector': 'th.col_heading.level0', 'props': [('border-right', '3px solid black')]},
|
| 995 |
+
|
| 996 |
+
|
| 997 |
+
{'selector':'th', 'props' : [('border', '1px solid black')]},
|
| 998 |
+
|
| 999 |
+
],overwrite=False)
|
| 1000 |
+
.set_properties(**{'border': '3 px'}, overwrite=False)
|
| 1001 |
+
.set_table_styles([{
|
| 1002 |
+
'selector': 'caption',
|
| 1003 |
+
'props': [
|
| 1004 |
+
('color', ''),
|
| 1005 |
+
('fontname', 'Century Gothic'),
|
| 1006 |
+
('font-size', '16px'),
|
| 1007 |
+
('font-style', 'italic'),
|
| 1008 |
+
('font-weight', ''),
|
| 1009 |
+
('text-align', 'centre'),
|
| 1010 |
+
]
|
| 1011 |
+
},
|
| 1012 |
+
{
|
| 1013 |
+
'selector': 'th',
|
| 1014 |
+
'props': [('font-size', '16px'), ('text-align', 'center'), ('Height', 'px'), ('color', 'black')]
|
| 1015 |
+
},
|
| 1016 |
+
{
|
| 1017 |
+
'selector': 'td',
|
| 1018 |
+
'props': [('text-align', 'center'), ('font-size', '16px'), ('color', 'black')]
|
| 1019 |
+
}], overwrite=False)
|
| 1020 |
+
|
| 1021 |
+
.set_properties(**{'background-color': 'White', 'index': 'White', 'min-width': '35px'}, overwrite=False)
|
| 1022 |
+
.set_table_styles([{'selector': 'th:first-child', 'props': [('background-color', 'white')]}], overwrite=False)
|
| 1023 |
+
|
| 1024 |
+
.set_table_styles([{'selector': 'th.col_heading.level0', 'props': [('background-color', '#b6b6b6')]}], overwrite=False)
|
| 1025 |
+
.set_table_styles([{'selector': 'th.col_heading.level1', 'props': [('background-color', '#a3a3a3')]}], overwrite=False)
|
| 1026 |
+
.set_table_styles([{'selector': 'tr', 'props': [('line-height', '20px')]}], overwrite=False)
|
| 1027 |
+
.set_properties(**{'Height': '8px'}, **{'text-align': 'center'}, overwrite=False)
|
| 1028 |
+
.hide_index()
|
| 1029 |
+
.set_properties(**{'border': '1px black solid'})
|
| 1030 |
+
|
| 1031 |
+
.set_table_styles([{'selector': 'thead th:nth-child(1)', 'props': [('min-width', '150px')]}], overwrite=False)
|
| 1032 |
+
.set_table_styles([{'selector': 'thead th:nth-child(2)', 'props': [('min-width', '225px')]}], overwrite=False)
|
| 1033 |
+
.set_table_styles([{'selector': 'thead th:nth-child(3)', 'props': [('min-width', '225px')]}], overwrite=False)
|
| 1034 |
+
.set_table_styles([{'selector': 'thead th:nth-child(4)', 'props': [('min-width', '50px')]}], overwrite=False)
|
| 1035 |
+
# .set_table_styles([{'selector': 'thead th:nth-child(5)', 'props': [('min-width', '150px')]}], overwrite=False)
|
| 1036 |
+
# .set_table_styles([{'selector': 'thead th:nth-child(2)', 'props': [('min-width', '250px')]}], overwrite=False)
|
| 1037 |
+
.set_table_styles([{'selector': 'thead th', 'props': [('height', '30px')]}], overwrite=False)
|
| 1038 |
+
.apply(highlight_alternate_rows, axis=0, subset=df_pivot_sum_pd.columns[2:])
|
| 1039 |
+
.applymap(apply_gradient)
|
| 1040 |
+
.set_properties(
|
| 1041 |
+
**{'border-top': 'none', 'border-bottom': 'none'},
|
| 1042 |
+
subset=df_pivot_sum_pd.columns[0:2] # Apply only to column 1
|
| 1043 |
+
).apply(add_bottom_border, axis=0)
|
| 1044 |
+
)
|
| 1045 |
+
return df_yahoo_style
|
| 1046 |
+
|
| 1047 |
+
|
| 1048 |
+
|
| 1049 |
+
|
| 1050 |
+
|
| 1051 |
+
|
| 1052 |
+
|
| 1053 |
+
|
| 1054 |
+
return df_pivot_sum_pd
|
| 1055 |
+
|
| 1056 |
+
|
| 1057 |
+
|
| 1058 |
app = App(app_ui, server)
|