CP Legendre commited on
Commit
f1ae266
·
1 Parent(s): 48c3ff8

Scale dense charts with result count

Browse files
src/charts.py CHANGED
@@ -24,6 +24,13 @@ PlotBackground = Literal["Dark", "White"]
24
  DEFAULT_PALETTE: PaletteName = "Citrus"
25
  DEFAULT_BACKGROUND: PlotBackground = "Dark"
26
 
 
 
 
 
 
 
 
27
  # Separate categorical palettes for each grouping dimension.
28
  # Model and harness colors intentionally start from different hue families so
29
  # switching "Color by" remains visually obvious.
@@ -260,8 +267,9 @@ def apply_plot_theme(fig: Figure, background_name: str | None = DEFAULT_BACKGROU
260
  "itemdoubleclick": False,
261
  },
262
  )
263
- # Remove fixed dimensions so Gradio/Plotly can size to the browser/container.
264
- fig.update_layout(width=None, height=None)
 
265
  fig.update_xaxes(
266
  automargin=True,
267
  color=theme["text_muted"],
@@ -651,6 +659,17 @@ def create_token_pareto_frontier_plot(
651
  )
652
 
653
 
 
 
 
 
 
 
 
 
 
 
 
654
  def create_ranking_plot(
655
  dataframe: pd.DataFrame,
656
  metric_column: str,
@@ -726,9 +745,18 @@ def create_ranking_plot(
726
  "autorange": "reversed",
727
  "categoryorder": "array",
728
  "categoryarray": agent_order,
 
 
 
729
  },
730
  legend_title_text=color_by,
731
  barmode="group",
 
 
 
 
 
 
732
  )
733
  return apply_plot_theme(fig, background_name)
734
 
@@ -877,11 +905,23 @@ def create_matrix_plot(
877
  hoverongaps=False,
878
  )
879
  )
 
880
  fig.update_layout(
881
  title=title,
882
  xaxis={"title": "Benchmark"},
883
- yaxis={"title": "Model / Harness", "autorange": "reversed"},
884
- height=max(480, 28 * len(matrix.index) + 180),
 
 
 
 
 
 
 
 
 
 
 
885
  )
886
  return apply_plot_theme(fig, background_name)
887
 
@@ -910,10 +950,22 @@ def create_coverage_matrix_plot(
910
  hovertemplate="Agent: %{y}<br>Benchmark: %{x}<br>Status: %{text}<extra></extra>",
911
  )
912
  )
 
913
  fig.update_layout(
914
  title="Benchmark coverage",
915
  xaxis={"title": "Benchmark"},
916
- yaxis={"title": "Model / Harness", "autorange": "reversed"},
917
- height=max(480, 28 * len(display.index) + 180),
 
 
 
 
 
 
 
 
 
 
 
918
  )
919
  return apply_plot_theme(fig, background_name)
 
24
  DEFAULT_PALETTE: PaletteName = "Citrus"
25
  DEFAULT_BACKGROUND: PlotBackground = "Dark"
26
 
27
+ RANKING_MIN_HEIGHT_PX = 680
28
+ RANKING_ROW_HEIGHT_PX = 44
29
+ RANKING_VERTICAL_PADDING_PX = 280
30
+ MATRIX_MIN_HEIGHT_PX = 720
31
+ MATRIX_ROW_HEIGHT_PX = 36
32
+ MATRIX_VERTICAL_PADDING_PX = 260
33
+
34
  # Separate categorical palettes for each grouping dimension.
35
  # Model and harness colors intentionally start from different hue families so
36
  # switching "Color by" remains visually obvious.
 
267
  "itemdoubleclick": False,
268
  },
269
  )
270
+ # Width remains responsive. Preserve any explicit height set by dense
271
+ # categorical charts so Plotly has enough vertical room for every label.
272
+ fig.update_layout(width=None)
273
  fig.update_xaxes(
274
  automargin=True,
275
  color=theme["text_muted"],
 
659
  )
660
 
661
 
662
+ def _categorical_chart_height(
663
+ n_rows: int,
664
+ *,
665
+ min_height: int,
666
+ row_height: int,
667
+ vertical_padding: int,
668
+ ) -> int:
669
+ """Scale dense categorical charts vertically so labels remain readable."""
670
+ return max(min_height, row_height * max(n_rows, 0) + vertical_padding)
671
+
672
+
673
  def create_ranking_plot(
674
  dataframe: pd.DataFrame,
675
  metric_column: str,
 
745
  "autorange": "reversed",
746
  "categoryorder": "array",
747
  "categoryarray": agent_order,
748
+ "tickmode": "array",
749
+ "tickvals": agent_order,
750
+ "ticktext": agent_order,
751
  },
752
  legend_title_text=color_by,
753
  barmode="group",
754
+ height=_categorical_chart_height(
755
+ len(agent_order),
756
+ min_height=RANKING_MIN_HEIGHT_PX,
757
+ row_height=RANKING_ROW_HEIGHT_PX,
758
+ vertical_padding=RANKING_VERTICAL_PADDING_PX,
759
+ ),
760
  )
761
  return apply_plot_theme(fig, background_name)
762
 
 
905
  hoverongaps=False,
906
  )
907
  )
908
+ row_labels = [str(value) for value in matrix.index]
909
  fig.update_layout(
910
  title=title,
911
  xaxis={"title": "Benchmark"},
912
+ yaxis={
913
+ "title": "Model / Harness",
914
+ "autorange": "reversed",
915
+ "tickmode": "array",
916
+ "tickvals": row_labels,
917
+ "ticktext": row_labels,
918
+ },
919
+ height=_categorical_chart_height(
920
+ len(row_labels),
921
+ min_height=MATRIX_MIN_HEIGHT_PX,
922
+ row_height=MATRIX_ROW_HEIGHT_PX,
923
+ vertical_padding=MATRIX_VERTICAL_PADDING_PX,
924
+ ),
925
  )
926
  return apply_plot_theme(fig, background_name)
927
 
 
950
  hovertemplate="Agent: %{y}<br>Benchmark: %{x}<br>Status: %{text}<extra></extra>",
951
  )
952
  )
953
+ row_labels = [str(value) for value in display.index]
954
  fig.update_layout(
955
  title="Benchmark coverage",
956
  xaxis={"title": "Benchmark"},
957
+ yaxis={
958
+ "title": "Model / Harness",
959
+ "autorange": "reversed",
960
+ "tickmode": "array",
961
+ "tickvals": row_labels,
962
+ "ticktext": row_labels,
963
+ },
964
+ height=_categorical_chart_height(
965
+ len(row_labels),
966
+ min_height=MATRIX_MIN_HEIGHT_PX,
967
+ row_height=MATRIX_ROW_HEIGHT_PX,
968
+ vertical_padding=MATRIX_VERTICAL_PADDING_PX,
969
+ ),
970
  )
971
  return apply_plot_theme(fig, background_name)
tests/test_pr2_analytics.py CHANGED
@@ -203,3 +203,18 @@ def test_ranking_plot_order_can_be_value_or_alphabetical():
203
  assert list(largest.layout.yaxis.categoryarray) == ["c / h", "b / h", "a / h"]
204
  assert list(lowest.layout.yaxis.categoryarray) == ["a / h", "b / h", "c / h"]
205
  assert list(alpha.layout.yaxis.categoryarray) == ["a / h", "b / h", "c / h"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  assert list(largest.layout.yaxis.categoryarray) == ["c / h", "b / h", "a / h"]
204
  assert list(lowest.layout.yaxis.categoryarray) == ["a / h", "b / h", "c / h"]
205
  assert list(alpha.layout.yaxis.categoryarray) == ["a / h", "b / h", "c / h"]
206
+
207
+
208
+ def test_matrix_height_scales_with_rows_and_keeps_all_y_labels():
209
+ rows = 18
210
+ matrix = pd.DataFrame(
211
+ {"bench-a": range(rows), "bench-b": range(rows)},
212
+ index=[f"model-{i} / harness" for i in range(rows)],
213
+ )
214
+
215
+ figure = create_matrix_plot(matrix, "Dense matrix", "Score (%)")
216
+
217
+ assert figure.layout.height >= 900
218
+ assert figure.layout.yaxis.tickmode == "array"
219
+ assert len(figure.layout.yaxis.tickvals) == rows
220
+ assert len(figure.layout.yaxis.ticktext) == rows
tests/test_ranking_refinements.py CHANGED
@@ -71,3 +71,22 @@ def test_rankings_page_places_paired_comparisons_first_and_has_no_score_all_benc
71
  assert 'ranking_sections = [("Score", "Score", BENCHMARK_NAMES, DEFAULT_BENCHMARK)]' in rankings
72
  assert '"Best first"' in rankings
73
  assert '"Best last"' in rankings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  assert 'ranking_sections = [("Score", "Score", BENCHMARK_NAMES, DEFAULT_BENCHMARK)]' in rankings
72
  assert '"Best first"' in rankings
73
  assert '"Best last"' in rankings
74
+
75
+
76
+ def test_ranking_plot_height_scales_with_agents_and_keeps_all_y_labels():
77
+ rows = 16
78
+ df = pd.DataFrame(
79
+ {
80
+ "Model": [f"model-{i}" for i in range(rows)],
81
+ "Harness": ["h"] * rows,
82
+ "Benchmark": ["bench"] * rows,
83
+ "Score (%)": list(range(rows)),
84
+ }
85
+ )
86
+
87
+ figure = create_ranking_plot(df, "Score (%)", "Score", True, sort_order="Best first")
88
+
89
+ assert figure.layout.height >= 900
90
+ assert figure.layout.yaxis.tickmode == "array"
91
+ assert len(figure.layout.yaxis.tickvals) == rows
92
+ assert len(figure.layout.yaxis.ticktext) == rows