James McCool commited on
Commit
8e39e09
·
1 Parent(s): 68d9ccc

Add custom styling and segmented control for tab navigation in streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +57 -10
src/streamlit_app.py CHANGED
@@ -11,6 +11,43 @@ from database import props_db, dfs_db
11
  game_format = {'Win%': '{:.2%}', 'Vegas': '{:.2%}', 'Win% Diff': '{:.2%}'}
12
  american_format = {'First Inning Lead Percentage': '{:.2%}', 'Fifth Inning Lead Percentage': '{:.2%}'}
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def calculate_poisson(row):
15
  mean_val = row['Mean_Outcome']
16
  threshold = row['Prop']
@@ -88,6 +125,9 @@ def calculate_no_vig(row):
88
 
89
  return no_vig_prob
90
 
 
 
 
91
  game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()
92
  qb_stats = overall_stats[overall_stats['Position'] == 'QB']
93
  qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])
@@ -107,10 +147,17 @@ sim_all_hold = pd.DataFrame(columns=['Player', 'Team', 'Book', 'Prop Type', 'Pro
107
 
108
  tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs(["Game Betting Model", 'Prop Market', "QB Projections", "RB/WR/TE Projections", "Player Prop Trends", "Player Prop Simulations", "Stat Specific Simulations"])
109
 
110
- def convert_df_to_csv(df):
111
- return df.to_csv().encode('utf-8')
112
-
113
- with tab1:
 
 
 
 
 
 
 
114
  st.info(t_stamp)
115
  if st.button("Reset Data", key='reset1'):
116
  st.cache_data.clear()
@@ -143,7 +190,7 @@ with tab1:
143
  key='team_export',
144
  )
145
 
146
- with tab2:
147
  st.info(t_stamp)
148
  if st.button("Reset Data", key='reset4'):
149
  st.cache_data.clear()
@@ -183,7 +230,7 @@ with tab2:
183
  mime='text/csv',
184
  )
185
 
186
- with tab3:
187
  st.info(t_stamp)
188
  if st.button("Reset Data", key='reset2'):
189
  st.cache_data.clear()
@@ -211,7 +258,7 @@ with tab3:
211
  key='NFL_qb_stats_export',
212
  )
213
 
214
- with tab4:
215
  st.info(t_stamp)
216
  if st.button("Reset Data", key='reset3'):
217
  st.cache_data.clear()
@@ -239,7 +286,7 @@ with tab4:
239
  key='NFL_nonqb_stats_export',
240
  )
241
 
242
- with tab5:
243
  st.info(t_stamp)
244
  if st.button("Reset Data", key='reset5'):
245
  st.cache_data.clear()
@@ -270,7 +317,7 @@ with tab5:
270
  mime='text/csv',
271
  )
272
 
273
- with tab6:
274
  st.info(t_stamp)
275
  if st.button("Reset Data", key='reset6'):
276
  st.cache_data.clear()
@@ -420,7 +467,7 @@ with tab6:
420
  plot_hold_container = st.empty()
421
  st.plotly_chart(fig, use_container_width=True)
422
 
423
- with tab7:
424
  st.info(t_stamp)
425
  st.info('The Over and Under percentages are a compositve percentage based on simulations, historical performance, and implied probabilities, and may be different than you would expect based purely on the median projection. Likewise, the Edge of a bet is not the only indicator of if you should make the bet or not as the suggestion is using a base acceptable threshold to determine how much edge you should have for each stat category.')
426
  if st.button("Reset Data/Load Data", key='reset7'):
 
11
  game_format = {'Win%': '{:.2%}', 'Vegas': '{:.2%}', 'Win% Diff': '{:.2%}'}
12
  american_format = {'First Inning Lead Percentage': '{:.2%}', 'Fifth Inning Lead Percentage': '{:.2%}'}
13
 
14
+ st.markdown("""
15
+ <style>
16
+ /* Tab styling */
17
+ .stElementContainer [data-baseweb="button-group"] {
18
+ gap: 2.000rem;
19
+ padding: 4px;
20
+ }
21
+ .stElementContainer [kind="segmented_control"] {
22
+ height: 2.000rem;
23
+ white-space: pre-wrap;
24
+ background-color: #DAA520;
25
+ color: white;
26
+ border-radius: 20px;
27
+ gap: 1px;
28
+ padding: 10px 20px;
29
+ font-weight: bold;
30
+ transition: all 0.3s ease;
31
+ }
32
+ .stElementContainer [kind="segmented_controlActive"] {
33
+ height: 3.000rem;
34
+ background-color: #DAA520;
35
+ border: 3px solid #FFD700;
36
+ border-radius: 10px;
37
+ color: black;
38
+ }
39
+ .stElementContainer [kind="segmented_control"]:hover {
40
+ background-color: #FFD700;
41
+ cursor: pointer;
42
+ }
43
+
44
+ div[data-baseweb="select"] > div {
45
+ background-color: #DAA520;
46
+ color: white;
47
+ }
48
+
49
+ </style>""", unsafe_allow_html=True)
50
+
51
  def calculate_poisson(row):
52
  mean_val = row['Mean_Outcome']
53
  threshold = row['Prop']
 
125
 
126
  return no_vig_prob
127
 
128
+ def convert_df_to_csv(df):
129
+ return df.to_csv().encode('utf-8')
130
+
131
  game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()
132
  qb_stats = overall_stats[overall_stats['Position'] == 'QB']
133
  qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])
 
147
 
148
  tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs(["Game Betting Model", 'Prop Market', "QB Projections", "RB/WR/TE Projections", "Player Prop Trends", "Player Prop Simulations", "Stat Specific Simulations"])
149
 
150
+ selected_tab = st.segmented_control(
151
+ "Select Tab",
152
+ options=["Game Betting Model", 'Prop Market', "QB Projections", "RB/WR/TE Projections", "Player Prop Trends", "Player Prop Simulations", "Stat Specific Simulations"],
153
+ selection_mode='single',
154
+ default='Game Betting Model',
155
+ width='stretch',
156
+ label_visibility='collapsed',
157
+ key='tab_selector'
158
+ )
159
+
160
+ with selected_tab == 'Game Betting Model':
161
  st.info(t_stamp)
162
  if st.button("Reset Data", key='reset1'):
163
  st.cache_data.clear()
 
190
  key='team_export',
191
  )
192
 
193
+ with selected_tab == 'Prop Market':
194
  st.info(t_stamp)
195
  if st.button("Reset Data", key='reset4'):
196
  st.cache_data.clear()
 
230
  mime='text/csv',
231
  )
232
 
233
+ with selected_tab == 'QB Projections':
234
  st.info(t_stamp)
235
  if st.button("Reset Data", key='reset2'):
236
  st.cache_data.clear()
 
258
  key='NFL_qb_stats_export',
259
  )
260
 
261
+ with selected_tab == 'RB/WR/TE Projections':
262
  st.info(t_stamp)
263
  if st.button("Reset Data", key='reset3'):
264
  st.cache_data.clear()
 
286
  key='NFL_nonqb_stats_export',
287
  )
288
 
289
+ with selected_tab == 'Player Prop Trends':
290
  st.info(t_stamp)
291
  if st.button("Reset Data", key='reset5'):
292
  st.cache_data.clear()
 
317
  mime='text/csv',
318
  )
319
 
320
+ with selected_tab == 'Player Prop Simulations':
321
  st.info(t_stamp)
322
  if st.button("Reset Data", key='reset6'):
323
  st.cache_data.clear()
 
467
  plot_hold_container = st.empty()
468
  st.plotly_chart(fig, use_container_width=True)
469
 
470
+ with selected_tab == 'Stat Specific Simulations':
471
  st.info(t_stamp)
472
  st.info('The Over and Under percentages are a compositve percentage based on simulations, historical performance, and implied probabilities, and may be different than you would expect based purely on the median projection. Likewise, the Edge of a bet is not the only indicator of if you should make the bet or not as the suggestion is using a base acceptable threshold to determine how much edge you should have for each stat category.')
473
  if st.button("Reset Data/Load Data", key='reset7'):