Pragya Jatav commited on
Commit
f4e26b8
·
1 Parent(s): 734939d

aesthetic changes 1

Browse files
Model_Result_Overview.py CHANGED
@@ -29,6 +29,7 @@ st.set_page_config(layout='wide')
29
  load_local_css('styles.css')
30
  set_header()
31
 
 
32
 
33
  def get_random_effects(media_data, panel_col, mdf):
34
  random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
@@ -107,19 +108,22 @@ if auth_status:
107
  a=1
108
 
109
  # st.header("")
110
- st.markdown("<h5 style='font-weight: normal;'>MMM Readout for Selected Period</h5>", unsafe_allow_html=True)
111
  #### Input Select Start and End Date
112
 
113
  # Create two columns for start date and end date input
114
  col1, col2 = st.columns(2)
115
-
 
 
 
116
  with col1:
117
  default_date = datetime(2024, 1, 28)
118
  start_date = st.date_input("Start Date: ",value=default_date)
119
 
120
  with col2:
121
  default_date = datetime(2024, 2, 24)
122
- end_date = st.date_input("End Date: ",value=default_date)
123
 
124
  # col1, col2 = st.columns(2)
125
  # with col1:
@@ -141,7 +145,26 @@ if auth_status:
141
  with col1:
142
  selected_option = st.selectbox('Select a comparison', options)
143
  with col2:
144
- st.write("")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  # Waterfall chart
146
  fig = sf.waterfall(start_date,end_date,selected_option)
147
  st.plotly_chart(fig,use_container_width=True)
@@ -152,6 +175,7 @@ if auth_status:
152
 
153
  ## Channel Contribution Bar Chart
154
  st.plotly_chart(sf.channel_contribution(start_date,end_date),use_container_width=True)
 
155
  # Format first three rows in percentage format
156
  # styled_df = sf.shares_table_func(shares_df)
157
  # # styled_df = styled_df.round(0).astype(int)
@@ -162,8 +186,8 @@ if auth_status:
162
 
163
  # st.table(styled_df)
164
  st.dataframe(sf.shares_table_func(shares_df),use_container_width=True)
165
-
166
- st.dataframe(sf.eff_table_func(shares_df),use_container_width=True)
167
 
168
  ### CPP CHART
169
  st.plotly_chart(sf.cpp(start_date,end_date),use_container_width=True)
 
29
  load_local_css('styles.css')
30
  set_header()
31
 
32
+ st.title("Model Result Overview")
33
 
34
  def get_random_effects(media_data, panel_col, mdf):
35
  random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
 
108
  a=1
109
 
110
  # st.header("")
111
+ # st.markdown("<h5 style='font-weight: normal;'>MMM Readout for Selected Period</h5>", unsafe_allow_html=True)
112
  #### Input Select Start and End Date
113
 
114
  # Create two columns for start date and end date input
115
  col1, col2 = st.columns(2)
116
+
117
+ # now = datetime.now()
118
+ # us_format = now.strftime("%m/%d/%Y")
119
+
120
  with col1:
121
  default_date = datetime(2024, 1, 28)
122
  start_date = st.date_input("Start Date: ",value=default_date)
123
 
124
  with col2:
125
  default_date = datetime(2024, 2, 24)
126
+ end_date = st.date_input("End Date: ",value = default_date)
127
 
128
  # col1, col2 = st.columns(2)
129
  # with col1:
 
145
  with col1:
146
  selected_option = st.selectbox('Select a comparison', options)
147
  with col2:
148
+ st.markdown("""</br>""",unsafe_allow_html=True)
149
+ if selected_option == "Month on Month" :
150
+
151
+ st.markdown(
152
+ f"""
153
+ <div style="padding: 5px; border-radius: 5px; background-color: #FFFFE0; width: fit-content; display: inline-block;">
154
+ <strong> Comparision of current month spends to previous month spends</strong>
155
+ </div>
156
+ """,
157
+ unsafe_allow_html=True
158
+ )
159
+ else :
160
+ st.markdown(
161
+ f"""
162
+ <div style="padding: 5px; border-radius: 5px; background-color: #FFFFE0; width: fit-content; display: inline-block;">
163
+ <strong> Comparision of current month spends to the same month in previous year</strong>
164
+ </div>
165
+ """,
166
+ unsafe_allow_html=True
167
+ )
168
  # Waterfall chart
169
  fig = sf.waterfall(start_date,end_date,selected_option)
170
  st.plotly_chart(fig,use_container_width=True)
 
175
 
176
  ## Channel Contribution Bar Chart
177
  st.plotly_chart(sf.channel_contribution(start_date,end_date),use_container_width=True)
178
+ st.plotly_chart(sf.chanel_spends(start_date,end_date),use_container_width=True)
179
  # Format first three rows in percentage format
180
  # styled_df = sf.shares_table_func(shares_df)
181
  # # styled_df = styled_df.round(0).astype(int)
 
186
 
187
  # st.table(styled_df)
188
  st.dataframe(sf.shares_table_func(shares_df),use_container_width=True)
189
+
190
+ st.dataframe(sf.eff_table_func(shares_df).style.format({"TOTAL SPEND": "{:,.0f}", "TOTAL SUPPORT": "{:,.0f}", "TOTAL CONTRIBUTION": "{:,.0f}"}),use_container_width=True)
191
 
192
  ### CPP CHART
193
  st.plotly_chart(sf.cpp(start_date,end_date),use_container_width=True)
Streamlit_functions.py CHANGED
@@ -142,7 +142,7 @@ def pie_charts(start_date,end_date):
142
  # title = "Distribution of Contributions"
143
  ), 1, 2)
144
  fig.update_layout(
145
- title="Distribution of Spends and Contributions"
146
  )
147
 
148
  return fig
@@ -167,7 +167,7 @@ def pie_spend(start_date,end_date):
167
 
168
  # Customize the layout
169
  fig.update_layout(
170
- title="Distribution of Spends"
171
  )
172
 
173
  # Show the figure
@@ -194,7 +194,7 @@ def pie_contributions(start_date,end_date):
194
  # fig.add_annotation(showarrow=False)
195
  # Customize the layout
196
  fig.update_layout(
197
- title="Distribution of Contributions",
198
  # margin=dict(t=0, b=0, l=0, r=0)
199
  )
200
 
@@ -268,8 +268,8 @@ def waterfall(start_date,end_date,btn_chart):
268
  x=[labels[i]],
269
  y=[cumulative[i+1] - cumulative[i]],
270
  base=[cumulative[i]],
271
- text=[f"{abs(values[i])}"],
272
- textposition='outside',
273
  hovertemplate=hover_text,
274
  marker=dict(color=color),
275
  showlegend=False
@@ -281,7 +281,7 @@ def waterfall(start_date,end_date,btn_chart):
281
  # Updating layout for black background and gray gridlines
282
  if btn_chart == "Month on Month":
283
  fig.update_layout(
284
- title=f"Change in MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%Y-%m-%d')} to {end_date_prev.strftime('%Y-%m-%d')} vs. {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}"
285
  ,showlegend=False,
286
  # plot_bgcolor='black',
287
  # paper_bgcolor='black',
@@ -295,13 +295,20 @@ def waterfall(start_date,end_date,btn_chart):
295
  showgrid=True,
296
  gridcolor='gray', # Setting y-axis gridline color to gray
297
  zeroline=False, # Hiding the y-axis zero line
298
- range=[18000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
299
  )
300
-
301
- )
 
 
 
 
 
 
 
302
  else :
303
  fig.update_layout(
304
- title=f"Change in MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%Y-%m-%d')} to {end_date_prev.strftime('%Y-%m-%d')} vs. {start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}"
305
  ,showlegend=False,
306
  # plot_bgcolor='black',
307
  # paper_bgcolor='black',
@@ -315,7 +322,7 @@ def waterfall(start_date,end_date,btn_chart):
315
  showgrid=True,
316
  gridcolor='gray', # Setting y-axis gridline color to gray
317
  zeroline=False, # Hiding the y-axis zero line
318
- range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
319
  )
320
 
321
  )
@@ -418,13 +425,13 @@ def channel_contribution(start_date,end_date):
418
  x=channel_df['channels'],
419
  y=round(channel_df['contributions']),
420
  marker=dict(color='rgb(74, 136, 217)'), # Blue color for all bars
421
- text=round(channel_df['contributions']),
422
  textposition='outside'
423
  )])
424
 
425
  # Updating layout for better visualization
426
  fig.update_layout(
427
- title=f"Media Contribution <br> {cur_data['Date'].min().strftime('%Y-%m-%d')} to {cur_data['Date'].max().strftime('%Y-%m-%d')}",
428
  # plot_bgcolor='black',
429
  # paper_bgcolor='black',
430
  # font=dict(color='white'), # Changing font color to white for better contrast
@@ -442,6 +449,54 @@ def channel_contribution(start_date,end_date):
442
  )
443
 
444
  return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  def shares_table_func(shares_df):
446
 
447
  # if pd.isnull(start_date) == True :
@@ -488,7 +543,7 @@ def eff_table_func(shares_df):
488
  media_df.index = media_df["MEDIA"]
489
  media_df.drop(columns = ["MEDIA"],inplace = True)
490
  for c in ["TOTAL SPEND","TOTAL SUPPORT","TOTAL CONTRIBUTION"]:
491
- media_df[c] = media_df[c].astype(int).astype(str)
492
  for c in ["SPEND SHARE","SUPPORT SHARE","CONTRIBUTION SHARE"]:
493
  media_df[c] = media_df[c].astype(int)
494
  media_df[c] = media_df[c].astype(str)+'%'
@@ -535,7 +590,7 @@ def cpp(start_date,end_date):
535
 
536
  # Update layout for better visualization
537
  fig.update_layout(
538
- title=f"CPP distribution <br>{cur_data['Date'].min().strftime('%Y-%m-%d')} to {cur_data['Date'].max().strftime('%Y-%m-%d')}"
539
  ,
540
  # plot_bgcolor='black',
541
  # paper_bgcolor='black',
@@ -572,8 +627,8 @@ def base_decomp():
572
 
573
  # Update layout for better visualization
574
  fig.update_layout(
575
- title=f"Base decomposition"
576
- # <br>{cur_data['Date'].min().strftime('%Y-%m-%d')} to {cur_data['Date'].max().strftime('%Y-%m-%d')}"
577
  ,
578
  # plot_bgcolor='black',
579
  # paper_bgcolor='black',
@@ -664,7 +719,7 @@ def media_decomp():
664
 
665
  # Updating layout for better visualization
666
  fig.update_layout(
667
- title=f"Media decomposition",# <br>{cur_data['Date'].min().strftime('%Y-%m-%d')} to {cur_data['Date'].max().strftime('%Y-%m-%d')}",
668
  # plot_bgcolor='black',
669
  # paper_bgcolor='black',
670
  # font=dict(color='white'), # Changing font color to white for better contrast
@@ -753,12 +808,14 @@ def elasticity(media_df):
753
  x=media_df['coeff'],
754
  y=media_df['category'],
755
  orientation='h', # Setting the orientation to horizontal
756
- marker_color='rgba(75, 136, 257, 1)' # Color for the bars
 
 
757
  ))
758
 
759
  # Updating layout for better visualization
760
  fig.update_layout(
761
- title="Media and Baseline Elasticity",
762
  xaxis=dict(
763
  title="Elasticity (coefficient)",
764
  showgrid=True,
@@ -790,7 +847,9 @@ def half_life(media_df):
790
  x=media_df[media_df['half_life'].isnull()==False]['half_life'],
791
  y=media_df[media_df['half_life'].isnull()==False]['category'],
792
  orientation='h', # Setting the orientation to horizontal
793
- marker_color='rgba(75, 136, 257, 1)' # Color for the bars
 
 
794
  ))
795
 
796
  # Updating layout for better visualization
@@ -856,8 +915,15 @@ def model_metrics_table_func():
856
  calculate_bic(df["Y"], df["Y_hat"])])
857
  model_metrics_df.index = ["R-squared","Adjusted R-squared","MAPE","AIC","BIC"]
858
  model_metrics_df = model_metrics_df.transpose()
859
- model_metrics_df.index = ['']
860
- return model_metrics_df.round(2)
 
 
 
 
 
 
 
861
 
862
 
863
  def scenario_spend_forecasting(delta_df,start_date,end_date):
 
142
  # title = "Distribution of Contributions"
143
  ), 1, 2)
144
  fig.update_layout(
145
+ title="Distribution Of Spends And Contributions"
146
  )
147
 
148
  return fig
 
167
 
168
  # Customize the layout
169
  fig.update_layout(
170
+ title="Distribution Of Spends"
171
  )
172
 
173
  # Show the figure
 
194
  # fig.add_annotation(showarrow=False)
195
  # Customize the layout
196
  fig.update_layout(
197
+ title="Distribution Of Contributions",
198
  # margin=dict(t=0, b=0, l=0, r=0)
199
  )
200
 
 
268
  x=[labels[i]],
269
  y=[cumulative[i+1] - cumulative[i]],
270
  base=[cumulative[i]],
271
+ text=[f"{abs(values[i]):,}"],
272
+ textposition='auto',
273
  hovertemplate=hover_text,
274
  marker=dict(color=color),
275
  showlegend=False
 
281
  # Updating layout for black background and gray gridlines
282
  if btn_chart == "Month on Month":
283
  fig.update_layout(
284
+ title=f"Change In MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}"
285
  ,showlegend=False,
286
  # plot_bgcolor='black',
287
  # paper_bgcolor='black',
 
295
  showgrid=True,
296
  gridcolor='gray', # Setting y-axis gridline color to gray
297
  zeroline=False, # Hiding the y-axis zero line
298
+ # range=[18000, max(max(cumulative), max(values)) + 1000] # Setting the y-axis range from 19k to slightly above the maximum value
299
  )
300
+ )
301
+ # fig.update_xaxes(
302
+ # tickmode="array",
303
+ # # categoryorder="total ascending",
304
+ # tickvals=[f"{abs(values[i])}"],
305
+ # ticktext=[f"{abs(values[i])}"],
306
+ # ticklabelposition="outside",
307
+ # tickfont=dict(color="white"),
308
+ # )
309
  else :
310
  fig.update_layout(
311
+ title=f"Change In MMM Estimated Prospect Contribution <br>{start_date_prev.strftime('%m-%d-%Y')} to {end_date_prev.strftime('%m-%d-%Y')} vs. {start_date.strftime('%m-%d-%Y')} to {end_date.strftime('%m-%d-%Y')}"
312
  ,showlegend=False,
313
  # plot_bgcolor='black',
314
  # paper_bgcolor='black',
 
322
  showgrid=True,
323
  gridcolor='gray', # Setting y-axis gridline color to gray
324
  zeroline=False, # Hiding the y-axis zero line
325
+ # range=[10000, max(cumulative)+1000] # Setting the y-axis range from 19k to slightly above the maximum value
326
  )
327
 
328
  )
 
425
  x=channel_df['channels'],
426
  y=round(channel_df['contributions']),
427
  marker=dict(color='rgb(74, 136, 217)'), # Blue color for all bars
428
+ text=(channel_df['contributions']).astype(int).apply(lambda x: f"{x:,}"),
429
  textposition='outside'
430
  )])
431
 
432
  # Updating layout for better visualization
433
  fig.update_layout(
434
+ title=f"Media Contribution <br> {cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
435
  # plot_bgcolor='black',
436
  # paper_bgcolor='black',
437
  # font=dict(color='white'), # Changing font color to white for better contrast
 
449
  )
450
 
451
  return fig
452
+
453
+ def chanel_spends(start_date,end_date):
454
+
455
+ # if pd.isnull(start_date) == True :
456
+ # start_date = datetime(2024, 1, 28)
457
+ # if pd.isnull(end_date) == True :
458
+ # end_date = datetime(2024, 2, 24)
459
+
460
+ start_date = pd.to_datetime(start_date)
461
+ end_date = pd.to_datetime(end_date)
462
+
463
+ cur_data = df[(df['Date'] >= start_date) & (df['Date'] <= end_date)]
464
+
465
+ channel_df = pd.DataFrame(cur_data[spend_cols].sum()).reset_index()
466
+ channel_df.columns = ["channels","spends"]
467
+ channel_df["channels"] = channels
468
+
469
+ # Creating the bar chart
470
+ fig = go.Figure(data=[go.Bar(
471
+ x=channel_df['channels'],
472
+ y=round(channel_df['spends']),
473
+ marker=dict(color='rgb(74, 136, 217)'), # Blue color for all bars
474
+ text=channel_df['spends'].apply(numerize),
475
+ # text = (channel_df['spends']).astype(int).apply(lambda x: f"{x:,}"),
476
+ textposition='outside'
477
+ )])
478
+
479
+ # Updating layout for better visualization
480
+ fig.update_layout(
481
+ title=f"Media Spends <br> {cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
482
+ # plot_bgcolor='black',
483
+ # paper_bgcolor='black',
484
+ # font=dict(color='white'), # Changing font color to white for better contrast
485
+ xaxis=dict(
486
+ showgrid=False,
487
+ gridcolor='gray', # Setting x-axis gridline color to gray
488
+ zeroline=False, # Hiding the x-axis zero line
489
+ ),
490
+ yaxis=dict(
491
+ title="Spends ($)",
492
+ showgrid=True,
493
+ gridcolor='gray', # Setting y-axis gridline color to gray
494
+ zeroline=False, # Hiding the y-axis zero line
495
+ )
496
+ )
497
+
498
+ return fig
499
+
500
  def shares_table_func(shares_df):
501
 
502
  # if pd.isnull(start_date) == True :
 
543
  media_df.index = media_df["MEDIA"]
544
  media_df.drop(columns = ["MEDIA"],inplace = True)
545
  for c in ["TOTAL SPEND","TOTAL SUPPORT","TOTAL CONTRIBUTION"]:
546
+ media_df[c] = media_df[c].astype(int)
547
  for c in ["SPEND SHARE","SUPPORT SHARE","CONTRIBUTION SHARE"]:
548
  media_df[c] = media_df[c].astype(int)
549
  media_df[c] = media_df[c].astype(str)+'%'
 
590
 
591
  # Update layout for better visualization
592
  fig.update_layout(
593
+ title=f"CPP Distribution <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}"
594
  ,
595
  # plot_bgcolor='black',
596
  # paper_bgcolor='black',
 
627
 
628
  # Update layout for better visualization
629
  fig.update_layout(
630
+ title=f"Base Decomposition"
631
+ # <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}"
632
  ,
633
  # plot_bgcolor='black',
634
  # paper_bgcolor='black',
 
719
 
720
  # Updating layout for better visualization
721
  fig.update_layout(
722
+ title=f"Media Decomposition",# <br>{cur_data['Date'].min().strftime('%m-%d-%Y')} to {cur_data['Date'].max().strftime('%m-%d-%Y')}",
723
  # plot_bgcolor='black',
724
  # paper_bgcolor='black',
725
  # font=dict(color='white'), # Changing font color to white for better contrast
 
808
  x=media_df['coeff'],
809
  y=media_df['category'],
810
  orientation='h', # Setting the orientation to horizontal
811
+ marker_color='rgba(75, 136, 257, 1)',
812
+ text= media_df['coeff'].round(2),
813
+ textposition="outside"
814
  ))
815
 
816
  # Updating layout for better visualization
817
  fig.update_layout(
818
+ title="Media And Baseline Elasticity",
819
  xaxis=dict(
820
  title="Elasticity (coefficient)",
821
  showgrid=True,
 
847
  x=media_df[media_df['half_life'].isnull()==False]['half_life'],
848
  y=media_df[media_df['half_life'].isnull()==False]['category'],
849
  orientation='h', # Setting the orientation to horizontal
850
+ marker_color='rgba(75, 136, 257, 1)',
851
+ text= media_df['coeff'].round(2),
852
+ textposition="outside"
853
  ))
854
 
855
  # Updating layout for better visualization
 
915
  calculate_bic(df["Y"], df["Y_hat"])])
916
  model_metrics_df.index = ["R-squared","Adjusted R-squared","MAPE","AIC","BIC"]
917
  model_metrics_df = model_metrics_df.transpose()
918
+ # model_metrics_df.index = model_metrics_df["R-squared"]
919
+ # model_metrics_df = model_metrics_df.drop(columns=["R-squared"])
920
+ model_metrics_df2 = pd.DataFrame(model_metrics_df.values,columns=["R-squared","Adjusted R-squared","MAPE","AIC","BIC"] )
921
+ model_metrics_df2 = model_metrics_df2.round(2)
922
+ model_metrics_df2["AIC"] = model_metrics_df2["AIC"].round(0)
923
+ model_metrics_df2["BIC"] = model_metrics_df2["BIC"].round(0)
924
+ model_metrics_df2.index = [" "]
925
+ # model_metrics_df2 = model_metrics_df2.reset_index(drop = True)
926
+ return model_metrics_df2
927
 
928
 
929
  def scenario_spend_forecasting(delta_df,start_date,end_date):
__pycache__/Streamlit_functions.cpython-310.pyc CHANGED
Binary files a/__pycache__/Streamlit_functions.cpython-310.pyc and b/__pycache__/Streamlit_functions.cpython-310.pyc differ
 
__pycache__/classes.cpython-310.pyc CHANGED
Binary files a/__pycache__/classes.cpython-310.pyc and b/__pycache__/classes.cpython-310.pyc differ
 
__pycache__/response_curves_model_quality.cpython-310.pyc CHANGED
Binary files a/__pycache__/response_curves_model_quality.cpython-310.pyc and b/__pycache__/response_curves_model_quality.cpython-310.pyc differ
 
__pycache__/response_curves_model_quality_base.cpython-310.pyc CHANGED
Binary files a/__pycache__/response_curves_model_quality_base.cpython-310.pyc and b/__pycache__/response_curves_model_quality_base.cpython-310.pyc differ
 
__pycache__/utilities.cpython-310.pyc CHANGED
Binary files a/__pycache__/utilities.cpython-310.pyc and b/__pycache__/utilities.cpython-310.pyc differ
 
__pycache__/utilities_with_panel.cpython-310.pyc CHANGED
Binary files a/__pycache__/utilities_with_panel.cpython-310.pyc and b/__pycache__/utilities_with_panel.cpython-310.pyc differ
 
pages/1_Model_Quality.py CHANGED
@@ -10,7 +10,7 @@ st.set_page_config(
10
 
11
 
12
  st.header("Model Quality")
13
- st.write("MMM Model Quality")
14
 
15
  st.plotly_chart(sf.mmm_model_quality(),use_container_width=True)
16
 
@@ -18,7 +18,7 @@ media_df = sf.media_data()
18
  # Create two columns for start date and end date input
19
  col1, col2 = st.columns(2)
20
 
21
- st.table(sf.model_metrics_table_func())
22
 
23
  with col1:
24
  st.plotly_chart(sf.elasticity(media_df))
@@ -48,10 +48,10 @@ options1 = [
48
  col1, col2 = st.columns(2)
49
  # Create a dropdown menu
50
  with col1:
51
- selected_option = st.selectbox('Select a media channel:', options)
52
- selected_option2 = st.selectbox('Select a Chart Type', options1)
53
  # Display the selected option
54
- st.plotly_chart(rc1.response_curves(selected_option,selected_option2))
55
  with col2:
56
  st.write("")
57
-
 
10
 
11
 
12
  st.header("Model Quality")
13
+ # st.write("MMM Model Quality")
14
 
15
  st.plotly_chart(sf.mmm_model_quality(),use_container_width=True)
16
 
 
18
  # Create two columns for start date and end date input
19
  col1, col2 = st.columns(2)
20
 
21
+ st.dataframe(sf.model_metrics_table_func(),hide_index = True,use_container_width=True)
22
 
23
  with col1:
24
  st.plotly_chart(sf.elasticity(media_df))
 
48
  col1, col2 = st.columns(2)
49
  # Create a dropdown menu
50
  with col1:
51
+ selected_option = st.selectbox('Select A Media Channel:', options)
52
+ selected_option2 = st.selectbox('Select A Chart Type', options1)
53
  # Display the selected option
54
+
55
  with col2:
56
  st.write("")
57
+ st.plotly_chart(rc1.response_curves(selected_option,selected_option2))
pages/3_Saved_Scenarios.py CHANGED
@@ -20,6 +20,7 @@ st.set_page_config(layout='wide')
20
  load_local_css('styles.css')
21
  set_header()
22
 
 
23
  # for k, v in st.session_state.items():
24
  # if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
25
  # st.session_state[k] = v
@@ -87,7 +88,14 @@ def comparison_scenarios_df():
87
  _df = _df.set_index('Channel')
88
  summary_df_prospect = summary_df_prospect.merge(_df, left_index=True, right_index=True)
89
  st.session_state['disable_download_button'] = False
90
- return summary_df_spend,summary_df_prospect
 
 
 
 
 
 
 
91
 
92
 
93
 
@@ -107,7 +115,7 @@ def plot_comparison_chart(df,metric):
107
 
108
  # Create the layout
109
  layout = go.Layout(
110
- title='Scenario comparison '+ metric,
111
  xaxis_title="Channels",
112
  yaxis_title=metric,
113
  barmode='group'
@@ -119,12 +127,13 @@ def plot_comparison_chart(df,metric):
119
  return fig
120
 
121
  def create_comparison_plots():
122
- comparison_scenarios_df()
123
- spends_df, prospects_df = comparison_scenarios_df()
124
-
125
  st.plotly_chart(plot_comparison_chart(spends_df,"Spends"),use_container_width=True)
126
  st.plotly_chart(plot_comparison_chart(prospects_df,"Contributions"),use_container_width=True)
127
-
 
128
  def create_scenario_summary(scenario_dict):
129
  summary_rows = []
130
  actual_total_spends = scenario_dict.get('actual_total_spends'),
@@ -137,6 +146,7 @@ def create_scenario_summary(scenario_dict):
137
  # st.write(actual_total_sales[0])
138
  # st.write(modified_total_spends[0])
139
  for channel_dict in scenario_dict['channels']:
 
140
  name_mod = channel_name_formating(channel_dict['name'])
141
  summary_rows.append([name_mod,
142
  channel_dict.get('actual_total_spends') * channel_dict.get('conversion_rate'),
@@ -170,35 +180,78 @@ def create_scenario_summary(scenario_dict):
170
  # scenario_dict.get('modified_total_spends') / scenario_dict.get('modified_total_sales')
171
  ])
172
 
173
- columns_index = pd.MultiIndex.from_product([[''],['Channel']], names=["first", "second"])
174
- columns_index = columns_index.append(pd.MultiIndex.from_product([['Spends','Prospects',"Efficiency"],['Actual','Simulated']], names=["first", "second"]))
175
 
176
- return pd.DataFrame(summary_rows, columns=columns_index)
 
 
 
 
 
 
 
177
 
178
 
179
 
180
  def summary_df_to_worksheet(df, ws):
181
- heading_fill = PatternFill(fill_type='solid',start_color='FF11B6BD',end_color='FF11B6BD')
 
 
 
 
 
 
 
 
 
182
  for j,header in enumerate(df.columns.values):
183
  col = j + 1
184
  for i in range(1,3):
185
- ws.cell(row=i, column=j + 1, value=header[i - 1]).font = Font(bold=True, color='FFFFFFFF')
186
  ws.cell(row=i,column=j+1).fill = heading_fill
 
187
  if col > 1 and (col - 6)%5==0:
188
  ws.merge_cells(start_row=1, end_row=1, start_column = col-3, end_column=col)
189
  ws.cell(row=1,column=col).alignment = Alignment(horizontal='center')
 
 
 
 
 
 
190
  for i,row in enumerate(df.itertuples()):
191
  for j,value in enumerate(row):
192
  if j == 0:
193
  continue
194
- elif (j-2)%4 == 0 or (j-3)%4 == 0:
195
- ws.cell(row=i+3, column = j, value=value)
196
- # .number_format = '$#,##0.0'
 
 
 
197
  else:
198
  ws.cell(row=i+3, column = j, value=value)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
  from openpyxl.utils import get_column_letter
201
  from openpyxl.styles import Font, PatternFill
 
202
  import logging
203
 
204
  def scenario_df_to_worksheet(df, ws):
@@ -274,8 +327,8 @@ def download_scenarios():
274
  scenario_df = pd.DataFrame(_spends).T
275
  scenario_df.columns = column_names
276
  ## write to sheet
277
- ws = wb.create_sheet(scenario_name)
278
- scenario_df_to_worksheet(scenario_df, ws)
279
  summary_rows.append(['Total',
280
  scenario_dict.get('modified_total_spends') ,
281
  scenario_dict.get('modified_total_sales'),
@@ -305,8 +358,8 @@ def disable_download_button():
305
  def transform(x):
306
  if x.name == ("",'Channel'):
307
  return x
308
- elif x.name[0] == 'ROI' or x.name[0] == 'MROI':
309
- return x.apply(lambda y : y if isinstance(y,str) else decimal_formater(format_numbers(y,include_indicator=False,n_decimals=4),n_decimals=4))
310
  else:
311
  return x.apply(lambda y : y if isinstance(y,str) else format_numbers(y))
312
 
@@ -376,28 +429,40 @@ if auth_status == True:
376
  column_1, column_2,column_3 = st.columns((6,1,1))
377
  with column_1:
378
  st.header(selected_scenario)
379
- with column_2:
380
- st.button('Delete scenarios', on_click=delete_scenario)
381
  with column_3:
382
- st.button('Load Scenario', on_click=load_scenario)
 
 
383
 
384
  selected_scenario_details = saved_scenarios[selected_scenario]
385
 
386
  pd.set_option('display.max_colwidth', 100)
387
-
388
- st.markdown(create_scenario_summary(selected_scenario_details).transform(transform).style.set_table_styles(
389
- [{
390
- 'selector': 'th',
391
- 'props': [('background-color', '#11B6BD')]
392
- },
393
- {
394
- 'selector' : 'tr:nth-child(even)',
395
- 'props' : [('background-color', '#11B6BD')]
396
- }
397
- ]).to_html(),unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
398
  st.markdown("<br><br>", unsafe_allow_html=True)
399
 
400
- with st.expander('Scenario comparison'):
401
  st.header("Scenario comparison")
402
  if len(scenarios_to_compare)== 0:
403
  st.write("")
 
20
  load_local_css('styles.css')
21
  set_header()
22
 
23
+ st.title("Saved Scenarios")
24
  # for k, v in st.session_state.items():
25
  # if k not in ['logout', 'login','config'] and not k.startswith('FormSubmitter'):
26
  # st.session_state[k] = v
 
88
  _df = _df.set_index('Channel')
89
  summary_df_prospect = summary_df_prospect.merge(_df, left_index=True, right_index=True)
90
  st.session_state['disable_download_button'] = False
91
+
92
+ efficiency_df = pd.DataFrame(index = summary_df_prospect.index)
93
+
94
+ for c in summary_df_spend.columns:
95
+ efficiency_df[c] = (summary_df_prospect[c]/summary_df_prospect[c].sum())/(summary_df_spend[c]/summary_df_spend[c].sum())
96
+ efficiency_df[c] = efficiency_df[c].round(2)
97
+
98
+ return summary_df_spend,summary_df_prospect,efficiency_df
99
 
100
 
101
 
 
115
 
116
  # Create the layout
117
  layout = go.Layout(
118
+ title='Comparing '+ metric,
119
  xaxis_title="Channels",
120
  yaxis_title=metric,
121
  barmode='group'
 
127
  return fig
128
 
129
  def create_comparison_plots():
130
+ # comparison_scenarios_df()
131
+ spends_df, prospects_df, efficiency_df = comparison_scenarios_df()
132
+ # st.dataframe(spends_df)
133
  st.plotly_chart(plot_comparison_chart(spends_df,"Spends"),use_container_width=True)
134
  st.plotly_chart(plot_comparison_chart(prospects_df,"Contributions"),use_container_width=True)
135
+ st.plotly_chart(plot_comparison_chart(efficiency_df,"Efficiency"),use_container_width=True)
136
+
137
  def create_scenario_summary(scenario_dict):
138
  summary_rows = []
139
  actual_total_spends = scenario_dict.get('actual_total_spends'),
 
146
  # st.write(actual_total_sales[0])
147
  # st.write(modified_total_spends[0])
148
  for channel_dict in scenario_dict['channels']:
149
+ # st.write(channel_dict['name'])
150
  name_mod = channel_name_formating(channel_dict['name'])
151
  summary_rows.append([name_mod,
152
  channel_dict.get('actual_total_spends') * channel_dict.get('conversion_rate'),
 
180
  # scenario_dict.get('modified_total_spends') / scenario_dict.get('modified_total_sales')
181
  ])
182
 
183
+ adf = pd.DataFrame(summary_rows)
184
+ # st.write(adf.columns)
185
 
186
+ adf.columns = ["1","2","3","4","5","6","7"]
187
+ adf.index = adf["1"].to_list() #["1","2","3","4","5","6","7","8","9","10","11","12","13","14"]
188
+ adf.drop(columns= ["1"],inplace= True)
189
+ # columns_index = pd.MultiIndex.from_product([[''],['Channel']], names=["",""])
190
+ # columns_index = columns_index.append(pd.MultiIndex.from_product([['Spends','Prospects',"Efficiency"],['Actual','Simulated']], names=["",""]))
191
+ columns_index = pd.MultiIndex.from_product([['Spends','Prospects',"Efficiency"],['Actual','Simulated']], names=["",""])
192
+ adf.columns = columns_index
193
+ return adf # pd.DataFrame(summary_rows, columns=columns_index)
194
 
195
 
196
 
197
  def summary_df_to_worksheet(df, ws):
198
+ heading_fill = PatternFill(fill_type='solid',start_color='FFFFFFFF',end_color='FFFFFFFF')
199
+
200
+ # Define border style
201
+ border_style = Border(
202
+ left=Side(border_style='thin', color='00000000'),
203
+ right=Side(border_style='thin', color='00000000'),
204
+ top=Side(border_style='thin', color='00000000'),
205
+ bottom=Side(border_style='thin', color='00000000')
206
+ )
207
+ number_format = '0.00'
208
  for j,header in enumerate(df.columns.values):
209
  col = j + 1
210
  for i in range(1,3):
211
+ ws.cell(row=i, column=j + 1, value=header[i - 1]).font = Font(bold=True, color='00000000')
212
  ws.cell(row=i,column=j+1).fill = heading_fill
213
+ # ws.cell.border = border_style
214
  if col > 1 and (col - 6)%5==0:
215
  ws.merge_cells(start_row=1, end_row=1, start_column = col-3, end_column=col)
216
  ws.cell(row=1,column=col).alignment = Alignment(horizontal='center')
217
+ # ws.cell.border = border_style
218
+ # Apply borders to all cells, including empty cells
219
+ for row in ws.iter_rows():
220
+ for cell in row:
221
+ cell.border = border_style
222
+
223
  for i,row in enumerate(df.itertuples()):
224
  for j,value in enumerate(row):
225
  if j == 0:
226
  continue
227
+ # elif (j-2)%4 == 0 or (j-3)%4 == 0:
228
+ # ws.cell(row=i+3, column = j, value=value)
229
+ # # cell.border = border_style
230
+ # # .number_format = '$#,##0.0'
231
+ # if isinstance(value, (int, float)):
232
+ # cell.number_format = number_format
233
  else:
234
  ws.cell(row=i+3, column = j, value=value)
235
+ # cell.border = border_style
236
+ if isinstance(value, (int, float)):
237
+ cell.number_format = '$#,##0.0'
238
+ # cell.number_format = number_format
239
+ # Auto-size columns
240
+ for col in ws.columns:
241
+ max_length = 15
242
+ column = col[0].column_letter
243
+ for cell in col:
244
+ try:
245
+ if len(str(cell.value)) > max_length:
246
+ max_length = len(cell.value)
247
+ except:
248
+ pass
249
+ adjusted_width = (max_length + 2)
250
+ ws.column_dimensions[column].width = adjusted_width
251
 
252
  from openpyxl.utils import get_column_letter
253
  from openpyxl.styles import Font, PatternFill
254
+ from openpyxl.styles import PatternFill, Font, Alignment, Border, Side
255
  import logging
256
 
257
  def scenario_df_to_worksheet(df, ws):
 
327
  scenario_df = pd.DataFrame(_spends).T
328
  scenario_df.columns = column_names
329
  ## write to sheet
330
+ # ws = wb.create_sheet(scenario_name)
331
+ # scenario_df_to_worksheet(scenario_df, ws)
332
  summary_rows.append(['Total',
333
  scenario_dict.get('modified_total_spends') ,
334
  scenario_dict.get('modified_total_sales'),
 
358
  def transform(x):
359
  if x.name == ("",'Channel'):
360
  return x
361
+ elif x.name[0] == 'Efficiency' or x.name[0] == 'MROI':
362
+ return x.apply(lambda y : y if isinstance(y,str) else decimal_formater(format_numbers(y,include_indicator=False,n_decimals=2),n_decimals=2))
363
  else:
364
  return x.apply(lambda y : y if isinstance(y,str) else format_numbers(y))
365
 
 
429
  column_1, column_2,column_3 = st.columns((6,1,1))
430
  with column_1:
431
  st.header(selected_scenario)
 
 
432
  with column_3:
433
+ st.button('Delete scenarios', on_click=delete_scenario)
434
+ # with column_3:
435
+ # st.button('Load Scenario', on_click=load_scenario)
436
 
437
  selected_scenario_details = saved_scenarios[selected_scenario]
438
 
439
  pd.set_option('display.max_colwidth', 100)
440
+ # st.table(create_scenario_summary(selected_scenario_details))
441
+ # st.table(create_scenario_summary(selected_scenario_details).transform(transform))
442
+ adf = create_scenario_summary(selected_scenario_details).transform(transform)
443
+ # adf1 = adf[('Spends', 'Actual'),
444
+ # ( 'Spends', 'Simulated'),
445
+ # ( 'Prospects','Actual'),
446
+ # ( 'Prospects', 'Simulated')].transform(transform)
447
+ # adf2 = adf[('Efficiency', 'Actual'),
448
+ # ('Efficiency', 'Simulated')].round(2)
449
+ # st.write(adf.columns)
450
+ # adf = adf.set_index([('', 'Channel')])#, inplace=True)
451
+ # st.table(adf)
452
+ st.markdown(adf.style.set_table_styles(
453
+ [
454
+ # {
455
+ # 'selector': 'th',
456
+ # 'props': [('background-color', '#1167bd')]
457
+ # },
458
+ # {
459
+ # 'selector' : 'tr:nth-child(even)',
460
+ # 'props' : [('background-color', '#11B6BD')]
461
+ # }
462
+ ]).to_html(),unsafe_allow_html=True)
463
  st.markdown("<br><br>", unsafe_allow_html=True)
464
 
465
+ with st.expander('Scenario comparison'):
466
  st.header("Scenario comparison")
467
  if len(scenarios_to_compare)== 0:
468
  st.write("")
response_curves_model_quality_base.py CHANGED
@@ -220,6 +220,7 @@ def response_curves(channel,chart_typ):
220
 
221
  # Update layout with titles
222
  fig.update_layout(
 
223
  title=channel+' Response Curve',
224
  xaxis_title='Weekly Spends',
225
  yaxis_title='Prospects'
 
220
 
221
  # Update layout with titles
222
  fig.update_layout(
223
+ width=700, height=500,
224
  title=channel+' Response Curve',
225
  xaxis_title='Weekly Spends',
226
  yaxis_title='Prospects'
summary_df.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:5edd69af2383d62f1f66e884c5dea34ee767b63b7a7498cc84d56f532b0bc309
3
  size 1822
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7eec7e117e96a7d10019a7e5cc889c769bdc4ae798cb0271c9870ee71e805b95
3
  size 1822
utilities.py CHANGED
@@ -957,7 +957,23 @@ def channel_name_formating(channel_name):
957
  name_mod = name_mod.replace("Imp", "Spend")
958
  elif name_mod.lower().endswith(" clicks"):
959
  name_mod = name_mod.replace("Clicks", "Spend")
960
- return name_mod
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
961
 
962
 
963
  def send_email(email, message):
 
957
  name_mod = name_mod.replace("Imp", "Spend")
958
  elif name_mod.lower().endswith(" clicks"):
959
  name_mod = name_mod.replace("Clicks", "Spend")
960
+ # st.write(channel_name)
961
+ key_dict = my_dict = {
962
+ "DisplayProspecting" :"Display Prospecting",
963
+ "CableTV" :"Cable TV",
964
+ "SocialProspecting": "Social Prospecting",
965
+ "Connected&OTTTV" :"Connected & OTTTV",
966
+ "SocialRetargeting" : "Social Retargeting",
967
+ "DigitalPartners" :"Digital Partners",
968
+ "Audio" :"Audio",
969
+ "BroadcastTV": "Broadcast TV",
970
+ "SearchNon-brand": "Search Non-brand",
971
+ "Email" :"Email" ,
972
+ "SearchBrand": "Search Brand",
973
+ "DisplayRetargeting" : "Display Retargeting" ,
974
+ "\xa0Video":"Video"
975
+ }
976
+ return key_dict[channel_name]
977
 
978
 
979
  def send_email(email, message):