Amber Tanaka commited on
Commit
fed35d4
·
unverified ·
1 Parent(s): 9c18850

Scatterplot hover (#21)

Browse files
Files changed (2) hide show
  1. leaderboard_transformer.py +55 -1
  2. ui_components.py +1 -12
leaderboard_transformer.py CHANGED
@@ -337,6 +337,7 @@ def _plot_scatter_plotly(
337
 
338
  x_col_to_use = x
339
  y_col_to_use = y
 
340
 
341
  # --- Section 2: Data Preparation---
342
  required_cols = [y_col_to_use, agent_col, "Openness", "Agent Tooling"]
@@ -414,9 +415,46 @@ def _plot_scatter_plotly(
414
  ))
415
 
416
  # --- Section 5: Prepare for Marker Plotting ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  # Pre-generate hover text and shapes for each point
418
  data_plot['hover_text'] = data_plot.apply(
419
- lambda row: f"<b>{row[agent_col]}</b><br>{x_axis_label}: ${row[x_col_to_use]:.2f}<br>{y_col_to_use}: {row[y_col_to_use]:.2f}",
 
 
 
 
 
 
420
  axis=1
421
  )
422
  data_plot['shape_symbol'] = data_plot['Agent Tooling'].map(shape_map).fillna(default_shape)
@@ -494,6 +532,12 @@ def _plot_scatter_plotly(
494
  yaxis=dict(title="Score", rangemode="tozero"),
495
  legend=dict(
496
  bgcolor='#FAF2E9',
 
 
 
 
 
 
497
  )
498
  )
499
  fig.add_layout_image(
@@ -615,4 +659,14 @@ def svg_to_data_uri(path: str) -> str:
615
  logger.warning(f"SVG file not found at: {path}")
616
  return None
617
 
 
 
 
 
 
 
 
 
618
 
 
 
 
337
 
338
  x_col_to_use = x
339
  y_col_to_use = y
340
+ llm_base = data["LLM Base"] if "LLM Base" in data.columns else "LLM Base"
341
 
342
  # --- Section 2: Data Preparation---
343
  required_cols = [y_col_to_use, agent_col, "Openness", "Agent Tooling"]
 
415
  ))
416
 
417
  # --- Section 5: Prepare for Marker Plotting ---
418
+ def format_hover_text(row, agent_col, x_axis_label, x_col, y_col):
419
+ """
420
+ Builds the complete HTML string for the plot's hover tooltip.
421
+ Formats the 'LLM Base' column as a bulleted list if multiple.
422
+ """
423
+ h_pad = " "
424
+ parts = ["<br>"]
425
+ parts.append(f"{h_pad}<b>{row[agent_col]}</b>{h_pad}<br>")
426
+ parts.append(f"{h_pad}Score: <b>{row[y_col]:.2f}</b>{h_pad}<br>")
427
+ parts.append(f"{h_pad}{x_axis_label}: <b>${row[x_col]:.2f}</b>{h_pad}<br>")
428
+ parts.append(f"{h_pad}Openness: <b>{row['Openness']}</b>{h_pad}<br>")
429
+ parts.append(f"{h_pad}Tooling: <b>{row['Agent Tooling']}</b>{h_pad}")
430
+
431
+ # Add extra vertical space (line spacing) before the next section
432
+ parts.append("<br>")
433
+ # Clean and format LLM Base column
434
+ llm_base_value = row['LLM Base']
435
+ llm_base_value = clean_llm_base_list(llm_base_value)
436
+ if isinstance(llm_base_value, list) and llm_base_value:
437
+ parts.append(f"{h_pad}LLM Base:{h_pad}<br>")
438
+ # Create a list of padded bullet points
439
+ list_items = [f"{h_pad} • <b>{item}</b>{h_pad}" for item in llm_base_value]
440
+ # Join them with line breaks
441
+ parts.append('<br>'.join(list_items))
442
+ else:
443
+ # Handle the non-list case with padding
444
+ parts.append(f"{h_pad}LLM Base: <b>{llm_base_value}</b>{h_pad}")
445
+ # Add a final line break for bottom "padding"
446
+ parts.append("<br>")
447
+ # Join all the parts together into the final HTML string
448
+ return ''.join(parts)
449
  # Pre-generate hover text and shapes for each point
450
  data_plot['hover_text'] = data_plot.apply(
451
+ lambda row: format_hover_text(
452
+ row,
453
+ agent_col=agent_col,
454
+ x_axis_label=x_axis_label,
455
+ x_col=x_col_to_use,
456
+ y_col=y_col_to_use
457
+ ),
458
  axis=1
459
  )
460
  data_plot['shape_symbol'] = data_plot['Agent Tooling'].map(shape_map).fillna(default_shape)
 
532
  yaxis=dict(title="Score", rangemode="tozero"),
533
  legend=dict(
534
  bgcolor='#FAF2E9',
535
+ ),
536
+ hoverlabel=dict(
537
+ bgcolor="#105257",
538
+ font_size=12,
539
+ font_family="Manrope",
540
+ font_color="#d3dedc",
541
  )
542
  )
543
  fig.add_layout_image(
 
659
  logger.warning(f"SVG file not found at: {path}")
660
  return None
661
 
662
+ def clean_llm_base_list(model_list):
663
+ """
664
+ Cleans a list of model strings by keeping only the text after the last '/'.
665
+ For example: "models/gemini-2.5-flash-preview-05-20" becomes "gemini-2.5-flash-preview-05-20".
666
+ """
667
+ # Return the original value if it's not a list, to avoid errors.
668
+ if not isinstance(model_list, list):
669
+ return model_list
670
 
671
+ # Use a list comprehension for a clean and efficient transformation.
672
+ return [str(item).split('/')[-1] for item in model_list]
ui_components.py CHANGED
@@ -17,6 +17,7 @@ from leaderboard_transformer import (
17
  format_cost_column,
18
  format_score_column,
19
  get_pareto_df,
 
20
  )
21
  from content import (
22
  SCATTER_DISCLAIMER,
@@ -581,18 +582,6 @@ def create_sub_navigation_bar(tag_map: dict, category_name: str):
581
  # Return the entire navigation bar as one single Gradio HTML component
582
  return gr.HTML(full_html)
583
 
584
- def clean_llm_base_list(model_list):
585
- """
586
- Cleans a list of model strings by keeping only the text after the last '/'.
587
- For example: "models/gemini-2.5-flash-preview-05-20" becomes "gemini-2.5-flash-preview-05-20".
588
- """
589
- # Return the original value if it's not a list, to avoid errors.
590
- if not isinstance(model_list, list):
591
- return model_list
592
-
593
- # Use a list comprehension for a clean and efficient transformation.
594
- return [str(item).split('/')[-1] for item in model_list]
595
-
596
  def format_llm_base_with_html(value):
597
  """
598
  Formats the 'LLM Base' cell value.
 
17
  format_cost_column,
18
  format_score_column,
19
  get_pareto_df,
20
+ clean_llm_base_list,
21
  )
22
  from content import (
23
  SCATTER_DISCLAIMER,
 
582
  # Return the entire navigation bar as one single Gradio HTML component
583
  return gr.HTML(full_html)
584
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  def format_llm_base_with_html(value):
586
  """
587
  Formats the 'LLM Base' cell value.