gauravlochab commited on
Commit
044e2c9
·
1 Parent(s): 9408331

feat: enhance combined time series graph with fixed y-axis range and improved marker handling

Browse files
Files changed (1) hide show
  1. app.py +143 -65
app.py CHANGED
@@ -531,16 +531,17 @@ def create_combined_time_series_graph(df):
531
 
532
  logger.info("Generated detailed graph data report")
533
 
534
- # Create Plotly figure
 
535
  fig = go.Figure()
536
 
537
  # Get unique agents
538
  unique_agents = df['agent_id'].unique()
539
  colors = px.colors.qualitative.Plotly[:len(unique_agents)]
540
 
541
- # IMPORTANT: Calculate min/max values for proper axis scaling
542
- min_apr = min(df['apr'].min(), -100) # Ensure we see at least down to -100
543
- max_apr = max(df['apr'].max(), 100) # Ensure we see at least up to 100
544
 
545
  # Add background shapes for APR and Performance regions
546
  min_time = df['timestamp'].min()
@@ -574,6 +575,7 @@ def create_combined_time_series_graph(df):
574
  x0=min_time, x1=max_time
575
  )
576
 
 
577
  # Add data for each agent
578
  for i, agent_id in enumerate(unique_agents):
579
  agent_data = df[df['agent_id'] == agent_id].copy()
@@ -588,7 +590,67 @@ def create_combined_time_series_graph(df):
588
  for idx, row in agent_data.iterrows():
589
  logger.info(f" Point {idx}: timestamp={row['timestamp']}, apr={row['apr']}, type={row['metric_type']}")
590
 
591
- # Add the combined line for both APR and Performance
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592
  fig.add_trace(
593
  go.Scatter(
594
  x=agent_data['timestamp'],
@@ -600,50 +662,8 @@ def create_combined_time_series_graph(df):
600
  hovertemplate='Time: %{x}<br>Value: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
601
  )
602
  )
603
-
604
- # Add scatter points for APR values
605
- apr_data = agent_data[agent_data['metric_type'] == 'APR']
606
- if not apr_data.empty:
607
- logger.info(f" Adding {len(apr_data)} APR markers for {agent_name}")
608
- for idx, row in apr_data.iterrows():
609
- logger.info(f" APR marker: timestamp={row['timestamp']}, apr={row['apr']}")
610
-
611
- fig.add_trace(
612
- go.Scatter(
613
- x=apr_data['timestamp'],
614
- y=apr_data['apr'],
615
- mode='markers',
616
- marker=dict(color=color, symbol='circle', size=10),
617
- name=f'{agent_name} APR',
618
- legendgroup=agent_name,
619
- showlegend=False,
620
- hovertemplate='Time: %{x}<br>APR: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>',
621
- visible=True # Explicitly set visibility
622
- )
623
- )
624
-
625
- # Add scatter points for Performance values
626
- perf_data = agent_data[agent_data['metric_type'] == 'Performance']
627
- if not perf_data.empty:
628
- logger.info(f" Adding {len(perf_data)} Performance markers for {agent_name}")
629
- for idx, row in perf_data.iterrows():
630
- logger.info(f" Performance marker: timestamp={row['timestamp']}, apr={row['apr']}")
631
-
632
- fig.add_trace(
633
- go.Scatter(
634
- x=perf_data['timestamp'],
635
- y=perf_data['apr'],
636
- mode='markers',
637
- marker=dict(color=color, symbol='square', size=10),
638
- name=f'{agent_name} Perf',
639
- legendgroup=agent_name,
640
- showlegend=False,
641
- hovertemplate='Time: %{x}<br>Performance: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>',
642
- visible=True # Explicitly set visibility
643
- )
644
- )
645
 
646
- # Update layout
647
  fig.update_layout(
648
  title="APR and Performance Values for All Agents",
649
  xaxis_title="Time",
@@ -663,33 +683,91 @@ def create_combined_time_series_graph(df):
663
  hovermode="closest"
664
  )
665
 
666
- # Force y-axis range to include all data points with padding
667
- y_padding = (max_apr - min_apr) * 0.1 # 10% padding
668
  fig.update_yaxes(
669
  showgrid=True,
670
  gridwidth=1,
671
  gridcolor='rgba(0,0,0,0.1)',
672
- range=[min_apr - y_padding, max_apr + y_padding] # Force range to include all points
 
 
 
673
  )
674
 
675
  # Update x-axis
676
- fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
677
-
678
- # Save the figure (still useful for reference)
679
- graph_file = "modius_apr_combined_graph.html"
680
- fig.write_html(graph_file, include_plotlyjs='cdn', full_html=False)
681
 
682
- # Also save as image for compatibility
683
- img_file = "modius_apr_combined_graph.png"
684
  try:
685
- fig.write_image(img_file)
686
- logger.info(f"Combined graph saved to {graph_file} and {img_file}")
 
 
 
 
 
 
 
 
 
 
 
 
 
687
  except Exception as e:
688
- logger.error(f"Error saving image: {e}")
689
- logger.info(f"Combined graph saved to {graph_file} only")
690
-
691
- # Return the figure object for direct use in Gradio
692
- return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693
 
694
  def save_to_csv(df):
695
  """Save the APR data DataFrame to a CSV file and return the file path"""
 
531
 
532
  logger.info("Generated detailed graph data report")
533
 
534
+ # ENSURE THERE ARE NO CONFLICTING AXES OR TRACES
535
+ # Create Plotly figure in a clean state
536
  fig = go.Figure()
537
 
538
  # Get unique agents
539
  unique_agents = df['agent_id'].unique()
540
  colors = px.colors.qualitative.Plotly[:len(unique_agents)]
541
 
542
+ # IMPORTANT: Fixed y-axis range that always includes -100
543
+ min_apr = -110 # Fixed minimum to ensure -100 is visible
544
+ max_apr = 110 # Fixed maximum to ensure data is visible
545
 
546
  # Add background shapes for APR and Performance regions
547
  min_time = df['timestamp'].min()
 
575
  x0=min_time, x1=max_time
576
  )
577
 
578
+ # MODIFIED: Changed order of trace addition - add markers first, then lines
579
  # Add data for each agent
580
  for i, agent_id in enumerate(unique_agents):
581
  agent_data = df[df['agent_id'] == agent_id].copy()
 
590
  for idx, row in agent_data.iterrows():
591
  logger.info(f" Point {idx}: timestamp={row['timestamp']}, apr={row['apr']}, type={row['metric_type']}")
592
 
593
+ # First add scatter points for Performance values
594
+ perf_data = agent_data[agent_data['metric_type'] == 'Performance']
595
+ if not perf_data.empty:
596
+ logger.info(f" Adding {len(perf_data)} Performance markers for {agent_name}")
597
+ for idx, row in perf_data.iterrows():
598
+ logger.info(f" Performance marker: timestamp={row['timestamp']}, apr={row['apr']}")
599
+
600
+ # Use explicit Python boolean for showlegend
601
+ is_first_point = bool(idx == perf_data.index[0])
602
+ fig.add_trace(
603
+ go.Scatter(
604
+ x=[row['timestamp']],
605
+ y=[row['apr']],
606
+ mode='markers',
607
+ marker=dict(
608
+ color='red', # Force consistent color
609
+ symbol='square',
610
+ size=16, # Make markers larger
611
+ line=dict(
612
+ width=2,
613
+ color='black'
614
+ )
615
+ ),
616
+ name=f'{agent_name} Perf',
617
+ legendgroup=agent_name,
618
+ showlegend=is_first_point, # Use native Python boolean
619
+ hovertemplate='Time: %{x}<br>Performance: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
620
+ )
621
+ )
622
+
623
+ # Now add scatter points for APR values
624
+ apr_data = agent_data[agent_data['metric_type'] == 'APR']
625
+ if not apr_data.empty:
626
+ logger.info(f" Adding {len(apr_data)} APR markers for {agent_name}")
627
+ for idx, row in apr_data.iterrows():
628
+ logger.info(f" APR marker: timestamp={row['timestamp']}, apr={row['apr']}")
629
+
630
+ # Use explicit Python boolean for showlegend
631
+ is_first_point = bool(idx == apr_data.index[0])
632
+ fig.add_trace(
633
+ go.Scatter(
634
+ x=[row['timestamp']],
635
+ y=[row['apr']],
636
+ mode='markers',
637
+ marker=dict(
638
+ color='blue', # Force consistent color
639
+ symbol='circle',
640
+ size=14, # Make markers larger
641
+ line=dict(
642
+ width=2,
643
+ color='black'
644
+ )
645
+ ),
646
+ name=f'{agent_name} APR',
647
+ legendgroup=agent_name,
648
+ showlegend=is_first_point, # Use native Python boolean
649
+ hovertemplate='Time: %{x}<br>APR: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
650
+ )
651
+ )
652
+
653
+ # Add the combined line AFTER markers for both APR and Performance
654
  fig.add_trace(
655
  go.Scatter(
656
  x=agent_data['timestamp'],
 
662
  hovertemplate='Time: %{x}<br>Value: %{y:.2f}<br>Agent: ' + agent_name + '<extra></extra>'
663
  )
664
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
665
 
666
+ # Update layout - use simple boolean values everywhere
667
  fig.update_layout(
668
  title="APR and Performance Values for All Agents",
669
  xaxis_title="Time",
 
683
  hovermode="closest"
684
  )
685
 
686
+ # FORCE FIXED Y-AXIS RANGE
 
687
  fig.update_yaxes(
688
  showgrid=True,
689
  gridwidth=1,
690
  gridcolor='rgba(0,0,0,0.1)',
691
+ range=[min_apr, max_apr], # Fixed range
692
+ tickmode='linear',
693
+ tick0=-100,
694
+ dtick=50
695
  )
696
 
697
  # Update x-axis
698
+ fig.update_xaxes(
699
+ showgrid=True,
700
+ gridwidth=1,
701
+ gridcolor='rgba(0,0,0,0.1)'
702
+ )
703
 
704
+ # SIMPLIFIED APPROACH: Do a direct plot without markers for comparison
705
+ # This creates a simple, reliable fallback plot if the advanced one fails
706
  try:
707
+ # Save the figure (still useful for reference)
708
+ graph_file = "modius_apr_combined_graph.html"
709
+ fig.write_html(graph_file, include_plotlyjs='cdn', full_html=False)
710
+
711
+ # Also save as image for compatibility
712
+ img_file = "modius_apr_combined_graph.png"
713
+ try:
714
+ fig.write_image(img_file)
715
+ logger.info(f"Combined graph saved to {graph_file} and {img_file}")
716
+ except Exception as e:
717
+ logger.error(f"Error saving image: {e}")
718
+ logger.info(f"Combined graph saved to {graph_file} only")
719
+
720
+ # Return the figure object for direct use in Gradio
721
+ return fig
722
  except Exception as e:
723
+ # If the complex graph approach fails, create a simpler one
724
+ logger.error(f"Error creating advanced graph: {e}")
725
+ logger.info("Falling back to simpler graph")
726
+
727
+ # Create a simpler graph as fallback
728
+ simple_fig = go.Figure()
729
+
730
+ # Add zero line
731
+ simple_fig.add_shape(
732
+ type="line",
733
+ line=dict(dash="solid", width=1.5, color="black"),
734
+ y0=0, y1=0,
735
+ x0=min_time, x1=max_time
736
+ )
737
+
738
+ # Simply plot each agent's data as a line with markers
739
+ for i, agent_id in enumerate(unique_agents):
740
+ agent_data = df[df['agent_id'] == agent_id].copy()
741
+ agent_name = agent_data['agent_name'].iloc[0]
742
+ color = colors[i % len(colors)]
743
+
744
+ # Sort by timestamp
745
+ agent_data = agent_data.sort_values('timestamp')
746
+
747
+ # Add a single trace with markers+lines
748
+ simple_fig.add_trace(
749
+ go.Scatter(
750
+ x=agent_data['timestamp'],
751
+ y=agent_data['apr'],
752
+ mode='lines+markers',
753
+ name=agent_name,
754
+ marker=dict(size=10),
755
+ line=dict(width=2)
756
+ )
757
+ )
758
+
759
+ # Simplified layout
760
+ simple_fig.update_layout(
761
+ title="APR and Performance Values (Simplified View)",
762
+ xaxis_title="Time",
763
+ yaxis_title="Value",
764
+ yaxis=dict(range=[-110, 110]),
765
+ height=600,
766
+ width=1000
767
+ )
768
+
769
+ # Return the simple figure
770
+ return simple_fig
771
 
772
  def save_to_csv(df):
773
  """Save the APR data DataFrame to a CSV file and return the file path"""