entropy25 commited on
Commit
e26889f
·
verified ·
1 Parent(s): 7ecef08

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -23
app.py CHANGED
@@ -398,22 +398,54 @@ class VisualizationEngine:
398
  return fig
399
 
400
  @staticmethod
401
- def create_revenue_trend(df: pd.DataFrame):
402
- """Create revenue trend visualization"""
403
  df_copy = df.copy()
404
- df_copy['order_month'] = df_copy['order_date'].dt.to_period('M')
405
- monthly_revenue = df_copy.groupby('order_month')['amount'].sum().reset_index()
406
- monthly_revenue['order_month'] = monthly_revenue['order_month'].astype(str)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
 
408
  fig = px.line(
409
- monthly_revenue,
410
- x='order_month',
411
  y='amount',
412
- title='Monthly Revenue Trends',
413
- labels={'amount': 'Revenue ($)', 'order_month': 'Month'}
414
  )
415
  fig.update_traces(line_color=COLORS['primary'], line_width=3)
416
  fig.update_layout(height=400, title={'x': 0.5, 'xanchor': 'center'})
 
417
  return fig
418
 
419
  @staticmethod
@@ -582,6 +614,21 @@ class B2BCustomerAnalytics:
582
 
583
  return segment_chart, rfm_chart, churn_chart, revenue_chart
584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  def get_customer_table(self) -> Optional[pd.DataFrame]:
586
  """Get formatted customer table"""
587
  if self.customer_metrics is None:
@@ -800,6 +847,22 @@ class B2BCustomerAnalytics:
800
 
801
  return " • ".join(recommendations) if recommendations else "Continue monitoring customer engagement patterns."
802
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
  def create_gradio_interface():
804
  """Create the enhanced Gradio interface"""
805
 
@@ -832,7 +895,7 @@ def create_gradio_interface():
832
 
833
  with gr.Tabs():
834
 
835
- with gr.Tab("📊 Data Upload & Dashboard"):
836
  with gr.Row():
837
  with gr.Column():
838
  file_input = gr.File(
@@ -854,7 +917,7 @@ def create_gradio_interface():
854
  summary_display = gr.HTML()
855
  data_preview = gr.DataFrame(label="Data Preview (First 20 Rows)")
856
 
857
- with gr.Tab("🎯 Customer Segmentation"):
858
  with gr.Row():
859
  with gr.Column():
860
  segment_chart = gr.Plot(label="Customer Segments Distribution")
@@ -875,7 +938,7 @@ def create_gradio_interface():
875
  </div>
876
  """)
877
 
878
- with gr.Tab("🤖 Churn Prediction"):
879
  train_btn = gr.Button(
880
  "Train Churn Prediction Model",
881
  variant="primary",
@@ -899,19 +962,36 @@ def create_gradio_interface():
899
  </div>
900
  """)
901
 
902
- with gr.Tab("📈 Revenue Analytics"):
903
- revenue_chart = gr.Plot(label="Monthly Revenue Trends")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
 
 
905
  gr.HTML("""
906
  <div style="background: #ecfdf5; padding: 1rem; border-radius: 8px; border-left: 4px solid #10b981; margin-top: 1rem;">
907
- <h4 style="color: #065f46; margin: 0 0 0.5rem 0;">Revenue Insights</h4>
908
  <p style="margin: 0; color: #1f2937; font-size: 0.9rem;">
909
- Track revenue trends over time to identify seasonal patterns, growth trajectories, and potential business impact of customer segments.
 
910
  </p>
911
  </div>
912
  """)
913
 
914
- with gr.Tab("👤 Customer Insights"):
915
  with gr.Row():
916
  customer_id_input = gr.Textbox(
917
  label="Customer ID",
@@ -926,7 +1006,7 @@ def create_gradio_interface():
926
 
927
  customer_insights = gr.HTML()
928
 
929
- with gr.Tab("📋 Reports"):
930
  with gr.Row():
931
  with gr.Column():
932
  gr.HTML("""
@@ -953,20 +1033,23 @@ def create_gradio_interface():
953
  def safe_load_data(analytics_instance, file):
954
  try:
955
  if file is None:
956
- return analytics_instance, "Please upload a CSV file", "", None, None, None, None, None, None
957
 
958
  status, dashboard, preview = analytics_instance.load_data(file)
959
 
960
  if "successfully" in status:
961
  charts = analytics_instance.get_visualizations()
962
  table = analytics_instance.get_customer_table()
963
- return analytics_instance, status, dashboard, preview, *charts, table
 
 
 
964
  else:
965
- return analytics_instance, status, "", None, None, None, None, None, None
966
 
967
  except Exception as e:
968
  error_msg = f"Error loading data: {str(e)}"
969
- return analytics_instance, error_msg, "", None, None, None, None, None, None
970
 
971
  def safe_train_model(analytics_instance):
972
  try:
@@ -1006,7 +1089,27 @@ def create_gradio_interface():
1006
  fn=safe_load_data,
1007
  inputs=[analytics, file_input],
1008
  outputs=[analytics, load_status, summary_display, data_preview,
1009
- segment_chart, rfm_chart, churn_distribution_chart, revenue_chart, customer_table]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1010
  )
1011
 
1012
  train_btn.click(
 
398
  return fig
399
 
400
  @staticmethod
401
+ def create_revenue_trend(df: pd.DataFrame, time_granularity='month', customer_filter='all'):
402
+ """Create revenue trend visualization with filters"""
403
  df_copy = df.copy()
404
+
405
+ # Filter by customer if specified
406
+ if customer_filter != 'all' and customer_filter:
407
+ df_copy = df_copy[df_copy['customer_id'] == customer_filter]
408
+ if df_copy.empty:
409
+ # Return empty chart with message
410
+ fig = go.Figure()
411
+ fig.add_annotation(text=f"No data found for customer {customer_filter}",
412
+ xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False)
413
+ fig.update_layout(title=f"Revenue Trend - {customer_filter}", height=400)
414
+ return fig
415
+
416
+ # Group by time granularity
417
+ if time_granularity == 'day':
418
+ df_copy['time_period'] = df_copy['order_date'].dt.date
419
+ title_suffix = "Daily"
420
+ elif time_granularity == 'week':
421
+ df_copy['time_period'] = df_copy['order_date'].dt.to_period('W')
422
+ title_suffix = "Weekly"
423
+ elif time_granularity == 'year':
424
+ df_copy['time_period'] = df_copy['order_date'].dt.to_period('Y')
425
+ title_suffix = "Yearly"
426
+ else: # default to month
427
+ df_copy['time_period'] = df_copy['order_date'].dt.to_period('M')
428
+ title_suffix = "Monthly"
429
+
430
+ revenue_data = df_copy.groupby('time_period')['amount'].sum().reset_index()
431
+ revenue_data['time_period'] = revenue_data['time_period'].astype(str)
432
+
433
+ # Create title
434
+ if customer_filter == 'all':
435
+ title = f"{title_suffix} Revenue Trends - All Customers"
436
+ else:
437
+ title = f"{title_suffix} Revenue Trends - {customer_filter}"
438
 
439
  fig = px.line(
440
+ revenue_data,
441
+ x='time_period',
442
  y='amount',
443
+ title=title,
444
+ labels={'amount': 'Revenue ($)', 'time_period': 'Time Period'}
445
  )
446
  fig.update_traces(line_color=COLORS['primary'], line_width=3)
447
  fig.update_layout(height=400, title={'x': 0.5, 'xanchor': 'center'})
448
+
449
  return fig
450
 
451
  @staticmethod
 
614
 
615
  return segment_chart, rfm_chart, churn_chart, revenue_chart
616
 
617
+ def get_revenue_chart_with_filters(self, time_granularity='month', customer_filter='all'):
618
+ """Get revenue chart with time and customer filters"""
619
+ if self.raw_data is None:
620
+ return None
621
+
622
+ return VisualizationEngine.create_revenue_trend(
623
+ self.raw_data, time_granularity, customer_filter
624
+ )
625
+
626
+ def get_customer_list(self):
627
+ """Get list of customer IDs for dropdown"""
628
+ if self.raw_data is None:
629
+ return []
630
+ return ['all'] + sorted(self.raw_data['customer_id'].unique().tolist())
631
+
632
  def get_customer_table(self) -> Optional[pd.DataFrame]:
633
  """Get formatted customer table"""
634
  if self.customer_metrics is None:
 
847
 
848
  return " • ".join(recommendations) if recommendations else "Continue monitoring customer engagement patterns."
849
 
850
+ def update_revenue_chart(analytics_instance, time_gran, customer_id):
851
+ """Update revenue chart based on filters"""
852
+ try:
853
+ chart = analytics_instance.get_revenue_chart_with_filters(time_gran, customer_id)
854
+ return chart
855
+ except Exception as e:
856
+ return None
857
+
858
+ def update_customer_dropdown(analytics_instance):
859
+ """Update customer dropdown options"""
860
+ try:
861
+ customers = analytics_instance.get_customer_list()
862
+ return gr.Dropdown(choices=customers, value='all')
863
+ except:
864
+ return gr.Dropdown(choices=['all'], value='all')
865
+
866
  def create_gradio_interface():
867
  """Create the enhanced Gradio interface"""
868
 
 
895
 
896
  with gr.Tabs():
897
 
898
+ with gr.Tab("Data Upload & Dashboard"):
899
  with gr.Row():
900
  with gr.Column():
901
  file_input = gr.File(
 
917
  summary_display = gr.HTML()
918
  data_preview = gr.DataFrame(label="Data Preview (First 20 Rows)")
919
 
920
+ with gr.Tab("Customer Segmentation"):
921
  with gr.Row():
922
  with gr.Column():
923
  segment_chart = gr.Plot(label="Customer Segments Distribution")
 
938
  </div>
939
  """)
940
 
941
+ with gr.Tab("Churn Prediction"):
942
  train_btn = gr.Button(
943
  "Train Churn Prediction Model",
944
  variant="primary",
 
962
  </div>
963
  """)
964
 
965
+ with gr.Tab("Revenue Analytics"):
966
+ with gr.Row():
967
+ with gr.Column(scale=1):
968
+ time_granularity = gr.Radio(
969
+ choices=['day', 'week', 'month', 'year'],
970
+ value='month',
971
+ label="Time Granularity"
972
+ )
973
+ customer_filter = gr.Dropdown(
974
+ choices=[], # Will be populated dynamically
975
+ value='all',
976
+ label="Customer Filter"
977
+ )
978
+ update_chart_btn = gr.Button("Update Chart", variant="primary")
979
+
980
+ with gr.Column(scale=3):
981
+ revenue_chart = gr.Plot(label="Revenue Trends")
982
 
983
+ # Add the info box
984
  gr.HTML("""
985
  <div style="background: #ecfdf5; padding: 1rem; border-radius: 8px; border-left: 4px solid #10b981; margin-top: 1rem;">
986
+ <h4 style="color: #065f46; margin: 0 0 0.5rem 0;">Interactive Revenue Analysis</h4>
987
  <p style="margin: 0; color: #1f2937; font-size: 0.9rem;">
988
+ Select time granularity (day/week/month/year) and specific customers to analyze revenue patterns.
989
+ Use "all" to view aggregate trends across all customers.
990
  </p>
991
  </div>
992
  """)
993
 
994
+ with gr.Tab("Customer Insights"):
995
  with gr.Row():
996
  customer_id_input = gr.Textbox(
997
  label="Customer ID",
 
1006
 
1007
  customer_insights = gr.HTML()
1008
 
1009
+ with gr.Tab("Reports"):
1010
  with gr.Row():
1011
  with gr.Column():
1012
  gr.HTML("""
 
1033
  def safe_load_data(analytics_instance, file):
1034
  try:
1035
  if file is None:
1036
+ return analytics_instance, "Please upload a CSV file", "", None, None, None, None, None, None, gr.Dropdown(choices=['all'], value='all')
1037
 
1038
  status, dashboard, preview = analytics_instance.load_data(file)
1039
 
1040
  if "successfully" in status:
1041
  charts = analytics_instance.get_visualizations()
1042
  table = analytics_instance.get_customer_table()
1043
+ # Update customer dropdown
1044
+ customers = analytics_instance.get_customer_list()
1045
+ customer_dropdown = gr.Dropdown(choices=customers, value='all')
1046
+ return analytics_instance, status, dashboard, preview, *charts, table, customer_dropdown
1047
  else:
1048
+ return analytics_instance, status, "", None, None, None, None, None, None, gr.Dropdown(choices=['all'], value='all')
1049
 
1050
  except Exception as e:
1051
  error_msg = f"Error loading data: {str(e)}"
1052
+ return analytics_instance, error_msg, "", None, None, None, None, None, None, gr.Dropdown(choices=['all'], value='all')
1053
 
1054
  def safe_train_model(analytics_instance):
1055
  try:
 
1089
  fn=safe_load_data,
1090
  inputs=[analytics, file_input],
1091
  outputs=[analytics, load_status, summary_display, data_preview,
1092
+ segment_chart, rfm_chart, churn_distribution_chart, revenue_chart, customer_table, customer_filter]
1093
+ )
1094
+
1095
+ # Update chart when filters change
1096
+ update_chart_btn.click(
1097
+ fn=update_revenue_chart,
1098
+ inputs=[analytics, time_granularity, customer_filter],
1099
+ outputs=[revenue_chart]
1100
+ )
1101
+
1102
+ # Auto-update on filter change
1103
+ time_granularity.change(
1104
+ fn=update_revenue_chart,
1105
+ inputs=[analytics, time_granularity, customer_filter],
1106
+ outputs=[revenue_chart]
1107
+ )
1108
+
1109
+ customer_filter.change(
1110
+ fn=update_revenue_chart,
1111
+ inputs=[analytics, time_granularity, customer_filter],
1112
+ outputs=[revenue_chart]
1113
  )
1114
 
1115
  train_btn.click(