CP Legendre
Reduce ranking row height
38eb34d
Raw
History Blame Contribute Delete
36.2 kB
from __future__ import annotations
import hashlib
import re
from typing import Literal
import pandas as pd
import plotly.colors as pc
import plotly.graph_objects as go
from plotly.graph_objs._figure import Figure
ColorBy = Literal["Model", "Harness"]
PaletteName = Literal[
"Citrus",
"Okabe-Ito",
"High contrast",
"Rainbow",
"Grayscale",
"Viridis",
"Plasma",
"Cividis",
]
PlotBackground = Literal["Dark", "White"]
DEFAULT_PALETTE: PaletteName = "Citrus"
DEFAULT_BACKGROUND: PlotBackground = "Dark"
RANKING_MIN_HEIGHT_PX = 340
RANKING_ROW_HEIGHT_PX = 22
RANKING_VERTICAL_PADDING_PX = 280
MATRIX_MIN_HEIGHT_PX = 720
MATRIX_ROW_HEIGHT_PX = 36
MATRIX_VERTICAL_PADDING_PX = 260
# Separate categorical palettes for each grouping dimension.
# Model and harness colors intentionally start from different hue families so
# switching "Color by" remains visually obvious.
MODEL_COLORS: dict[str, str] = {
"GPT 5.5 - high": "#F8FAFC", # white
"Opus 4.8": "#FEF3C7", # cream
"RedHatAI/Qwen3.6-35B-A3B-NVFP4": "#F97316", # orange
"Sonnet 4.6": "#DC2626", # red
}
HARNESS_COLORS: dict[str, str] = {
"Claude Code": "#06B6D4", # cyan
"Codex": "#3B82F6", # blue
"OpenCode": "#8B5CF6", # violet
"OpenClaw": "#EC4899", # pink
"Pi": "#14B8A6", # teal
"Qwen Code": "#F43F5E", # rose
"internal": "#94A3B8",
}
MODEL_FALLBACK_PALETTE = [
"#F8FAFC", # white
"#FEF3C7", # cream
"#FACC15", # yellow
"#FB923C", # orange
"#DC2626", # red
"#93C5FD", # blue fallback
"#22C55E", # green fallback
"#C084FC", # violet fallback
"#F472B6", # pink fallback
"#14B8A6", # teal fallback
]
HARNESS_FALLBACK_PALETTE = [
"#06B6D4", # cyan
"#3B82F6", # blue
"#8B5CF6", # violet
"#EC4899", # pink
"#14B8A6", # teal
"#F43F5E", # rose
"#6366F1", # indigo
"#10B981", # emerald
"#A855F7", # purple
"#94A3B8", # slate
]
DARK_PAPER = "#15110F"
DARK_PLOT = "#1F1A17"
DARK_CARD = "#27211E"
TEXT_PRIMARY = "#F8FAFC"
TEXT_MUTED = "#CBD5E1"
GRID_COLOR = "rgba(248,250,252,0.14)"
ZERO_LINE_COLOR = "rgba(248,250,252,0.24)"
PLOT_BACKGROUNDS: dict[PlotBackground, dict[str, str]] = {
"Dark": {
"template": "plotly_dark",
"paper_bgcolor": DARK_CARD,
"plot_bgcolor": DARK_PLOT,
"text_primary": TEXT_PRIMARY,
"text_muted": TEXT_MUTED,
"grid_color": GRID_COLOR,
"zero_line_color": ZERO_LINE_COLOR,
"marker_line_color": DARK_PAPER,
},
"White": {
"template": "plotly_white",
"paper_bgcolor": "#FFFFFF",
"plot_bgcolor": "#FFFFFF",
"text_primary": "#0F172A",
"text_muted": "#475569",
"grid_color": "rgba(15,23,42,0.12)",
"zero_line_color": "rgba(15,23,42,0.25)",
"marker_line_color": "#334155",
},
}
def clean_markdown_link(value: object) -> str:
"""Return human-readable text from Markdown links used in leaderboard tables."""
text = str(value).replace("<sup>*</sup>", "")
match = re.match(r"\[(.*?)\]\((.*?)\)", text)
if match:
return match.group(1)
return text
COLOR_PALETTES: dict[PaletteName, list[str]] = {
"Citrus": MODEL_FALLBACK_PALETTE,
"Okabe-Ito": [
"#E69F00",
"#56B4E9",
"#009E73",
"#F0E442",
"#0072B2",
"#D55E00",
"#CC79A7",
"#999999",
],
"High contrast": ["#FFD166", "#06D6A0", "#118AB2", "#EF476F", "#A78BFA", "#F97316", "#22D3EE", "#E5E7EB"],
"Rainbow": ["#E6194B", "#F58231", "#FFE119", "#3CB44B", "#42D4F4", "#4363D8", "#911EB4", "#F032E6", "#469990", "#9A6324"],
# Near-white and near-black endpoints remain visible against both supported backgrounds.
"Grayscale": ["#E2E8F0", "#CBD5E1", "#94A3B8", "#64748B", "#475569", "#334155", "#1E293B", "#111827"],
"Viridis": list(pc.sequential.Viridis),
"Plasma": list(pc.sequential.Plasma),
"Cividis": list(pc.sequential.Cividis),
}
# Harness categories use the same central registry, with the default palette retaining
# its established cyan/blue/violet identity.
HARNESS_PALETTES: dict[PaletteName, list[str]] = {
**COLOR_PALETTES,
"Citrus": HARNESS_FALLBACK_PALETTE,
}
MODEL_PALETTES = COLOR_PALETTES
def get_color_palette(name: str | None) -> list[str]:
"""Return a copy of the requested palette, falling back to Citrus."""
palette_name = normalize_palette_name(name)
return list(COLOR_PALETTES[palette_name])
def normalize_palette_name(palette_name: str | None) -> PaletteName:
if palette_name in MODEL_PALETTES:
return palette_name # type: ignore[return-value]
return DEFAULT_PALETTE
def normalize_background_name(background_name: str | None) -> PlotBackground:
if background_name == "Current":
return "Dark"
if background_name in PLOT_BACKGROUNDS:
return background_name # type: ignore[return-value]
return DEFAULT_BACKGROUND
def get_plot_background(background_name: str | None = DEFAULT_BACKGROUND) -> dict[str, str]:
return PLOT_BACKGROUNDS[normalize_background_name(background_name)]
def stable_color(name: str, color_by: ColorBy, palette_name: str | None = DEFAULT_PALETTE) -> str:
palette_key = normalize_palette_name(palette_name)
palettes = MODEL_PALETTES if color_by == "Model" else HARNESS_PALETTES
palette = palettes[palette_key]
digest = hashlib.sha256(f"{palette_key}:{color_by}:{name}".encode("utf-8")).hexdigest()
return palette[int(digest[:8], 16) % len(palette)]
def get_color(name: str, color_by: ColorBy, palette_name: str | None = DEFAULT_PALETTE) -> str:
palette_key = normalize_palette_name(palette_name)
if palette_key == "Citrus":
palette = MODEL_COLORS if color_by == "Model" else HARNESS_COLORS
if name in palette:
return palette[name]
return stable_color(name, color_by, palette_key)
def palette_colors_for(color_by: ColorBy, palette_name: str | None = DEFAULT_PALETTE) -> list[str]:
palette_key = normalize_palette_name(palette_name)
palettes = MODEL_PALETTES if color_by == "Model" else HARNESS_PALETTES
return list(palettes[palette_key])
def color_map_for(
values: pd.Series,
color_by: ColorBy,
palette_name: str | None = DEFAULT_PALETTE,
) -> dict[str, str]:
unique_values = [str(value) for value in sorted(values.dropna().unique())]
palette_key = normalize_palette_name(palette_name)
# For the default Citrus palette, preserve hand-picked colors for known labels.
# Unknown labels still get sequential fallback colors to avoid hash collisions.
if palette_key == "Citrus":
named_colors = MODEL_COLORS if color_by == "Model" else HARNESS_COLORS
fallback_colors = palette_colors_for(color_by, palette_key)
color_map: dict[str, str] = {}
fallback_index = 0
for value in unique_values:
if value in named_colors:
color_map[value] = named_colors[value]
else:
color_map[value] = fallback_colors[fallback_index % len(fallback_colors)]
fallback_index += 1
return color_map
# Non-default palettes are assigned sequentially rather than by hash. Hashing can
# map multiple visible categories to the same color, which made the high-contrast
# harness palette look like only gray/blue/purple buckets.
palette = palette_colors_for(color_by, palette_key)
return {
value: palette[index % len(palette)]
for index, value in enumerate(unique_values)
}
def empty_figure(message: str, background_name: str | None = DEFAULT_BACKGROUND) -> Figure:
theme = get_plot_background(background_name)
fig = go.Figure()
fig.add_annotation(
text=message,
showarrow=False,
x=0.5,
y=0.5,
xref="paper",
yref="paper",
font={"size": 14, "color": theme["text_muted"]},
)
return apply_plot_theme(fig, background_name)
def apply_plot_theme(fig: Figure, background_name: str | None = DEFAULT_BACKGROUND) -> Figure:
theme = get_plot_background(background_name)
fig.update_layout(
template=theme["template"],
autosize=True,
paper_bgcolor=theme["paper_bgcolor"],
plot_bgcolor=theme["plot_bgcolor"],
font={"color": theme["text_primary"]},
title={"font": {"color": theme["text_primary"]}},
showlegend=True,
margin={"t": 60, "b": 0, "l": 0, "r": 0},
legend={
"orientation": "h",
"yanchor": "top",
"y": 1,
"yref": "container",
"xanchor": "center",
"x": 0.5,
"font": {"color": theme["text_muted"]},
"itemclick": False,
"itemdoubleclick": False,
},
)
# Width remains responsive. Preserve any explicit height set by dense
# categorical charts so Plotly has enough vertical room for every label.
fig.update_layout(width=None)
fig.update_xaxes(
automargin=True,
color=theme["text_muted"],
gridcolor=theme["grid_color"],
zerolinecolor=theme["zero_line_color"],
linecolor=theme["grid_color"],
title_font={"color": theme["text_muted"]},
tickfont={"color": theme["text_muted"]},
)
fig.update_yaxes(
automargin=True,
color=theme["text_muted"],
gridcolor=theme["grid_color"],
zerolinecolor=theme["zero_line_color"],
linecolor=theme["grid_color"],
title_font={"color": theme["text_muted"]},
tickfont={"color": theme["text_muted"]},
)
return fig
def prepare_benchmark_run_plot_df(dataframe: pd.DataFrame) -> pd.DataFrame:
plot_df = dataframe.copy()
plot_df["Model Label"] = plot_df["Model"].map(clean_markdown_link)
plot_df["Harness Label"] = plot_df["Harness"].map(clean_markdown_link)
plot_df["Benchmark Label"] = plot_df["Benchmark"].map(clean_markdown_link)
plot_df["Run Label"] = plot_df["Model Label"] + "<br>" + plot_df["Harness Label"]
plot_df["Score"] = pd.to_numeric(plot_df["Score"], errors="coerce")
return plot_df
def create_leaderboard_benchmark_plot(
dataframe: pd.DataFrame,
benchmark_name: str,
color_by: ColorBy = "Model",
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
if dataframe is None or dataframe.empty:
return empty_figure("No benchmark data available.", background_name)
plot_df = prepare_benchmark_run_plot_df(dataframe)
plot_df = plot_df[plot_df["Benchmark Label"] == benchmark_name].dropna(subset=["Score"])
plot_df = plot_df.sort_values("Score", ascending=False)
if plot_df.empty:
return empty_figure(f"No results available for {benchmark_name}.", background_name)
color_source = "Model Label" if color_by == "Model" else "Harness Label"
colors = color_map_for(plot_df[color_source], color_by, palette_name)
theme = get_plot_background(background_name)
fig = go.Figure()
for group, group_df in plot_df.groupby(color_source, sort=True):
fig.add_trace(
go.Bar(
x=group_df["Run Label"],
y=group_df["Score"],
name=str(group),
marker={
"color": colors[str(group)],
"line": {"width": 1, "color": theme["marker_line_color"]},
},
text=group_df["Score"].map(lambda score: f"{score:.1f}"),
textposition="outside",
customdata=group_df[["Model Label", "Harness Label", "Score"]],
hovertemplate=(
"<b>%{customdata[0]}</b><br>"
"Harness: %{customdata[1]}<br>"
"Score: %{customdata[2]:.1f}%"
"<extra></extra>"
),
)
)
fig.update_layout(
title=None,
xaxis={"title": "Model / Harness", "categoryorder": "total descending"},
yaxis={"title": "Score (%)", "range": [0, plot_df["Score"].max() * 1.12]},
legend_title_text=color_by,
bargap=0.28,
)
fig.update_xaxes(tickangle=-28)
fig = apply_plot_theme(fig, background_name)
return fig
def scatter_label_kwargs(
dataframe: pd.DataFrame,
show_labels: bool,
preferred_columns: tuple[str, ...] = ("Run Label", "Label"),
) -> dict[str, object]:
"""Return consistent Plotly scatter label arguments without affecting hover data."""
if not show_labels:
return {"mode": "markers", "text": None, "textposition": "top center"}
label_column = next((column for column in preferred_columns if column in dataframe.columns), None)
labels = dataframe[label_column] if label_column else None
return {"mode": "markers+text", "text": labels, "textposition": "top center"}
def create_score_vs_cost_plot(
dataframe: pd.DataFrame,
benchmark_name: str | None,
color_by: ColorBy = "Model",
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
if dataframe is None or dataframe.empty:
return empty_figure("No cost data available.", background_name)
if not benchmark_name:
return empty_figure("Select a benchmark to view cost data.", background_name)
plot_df = dataframe.copy()
plot_df = plot_df[plot_df["Benchmark"] == benchmark_name]
plot_df["Score"] = pd.to_numeric(plot_df["Score"], errors="coerce")
plot_df["Cost Per Task (USD)"] = pd.to_numeric(plot_df["Cost Per Task (USD)"], errors="coerce")
plot_df = plot_df.dropna(subset=["Score", "Cost Per Task (USD)"])
if plot_df.empty:
return empty_figure(f"No cost data available for {benchmark_name}.", background_name)
colors = color_map_for(plot_df[color_by], color_by, palette_name)
theme = get_plot_background(background_name)
fig = go.Figure()
for group, group_df in plot_df.groupby(color_by, sort=True):
label_kwargs = scatter_label_kwargs(group_df, show_labels)
fig.add_trace(
go.Scatter(
x=group_df["Cost Per Task (USD)"],
y=group_df["Score"],
name=str(group),
**label_kwargs,
marker={
"size": 15,
"color": colors[str(group)],
"line": {"width": 1, "color": theme["marker_line_color"]},
},
customdata=group_df[["Model", "Harness", "Benchmark", "Score", "Cost Per Task (USD)"]],
hovertemplate=(
"<b>%{customdata[0]}</b><br>"
"Harness: %{customdata[1]}<br>"
"Benchmark: %{customdata[2]}<br>"
"Score: %{customdata[3]:.1f}%<br>"
"Cost: $%{customdata[4]:.2f}/task"
"<extra></extra>"
),
)
)
fig.update_layout(
title=None,
xaxis={"title": "Cost per task (USD)", "tickprefix": "$", "tickformat": ".2f"},
yaxis={"title": "Score (%)", "range": [0, 105]},
legend_title_text=color_by,
)
return apply_plot_theme(fig, background_name)
RESOURCE_AXIS_CONFIG = {
"Total tokens": {
"column": "Total Tokens Per Task",
"axis_title": "Total tokens per task",
"hover_label": "Total tokens/task",
"hover_format": ",.0f",
},
"Cost per task": {
"column": "Cost Per Task",
"axis_title": "Cost per task (USD)",
"hover_label": "Cost/task",
"hover_format": ".4f",
"tickprefix": "$",
},
"Agent time per task": {
"column": "Agent Time Per Task",
"axis_title": "Agent time per task (seconds)",
"hover_label": "Agent time/task",
"hover_format": ",.1f",
"ticksuffix": "s",
},
}
def _resource_axis_config(resource_metric: str) -> dict[str, str]:
"""Return display metadata for a supported Efficiency resource metric."""
if resource_metric in RESOURCE_AXIS_CONFIG:
return RESOURCE_AXIS_CONFIG[resource_metric]
for config in RESOURCE_AXIS_CONFIG.values():
if resource_metric == config["column"]:
return config
raise ValueError(f"Unsupported efficiency resource metric: {resource_metric}")
def create_performance_vs_resource_plot(
dataframe: pd.DataFrame,
resource_metric: str = "Total tokens",
color_by: ColorBy = "Model",
x_scale: Literal["Linear", "Log"] = "Log",
show_pareto_frontier: bool = True,
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
"""Plot benchmark score against one positive resource metric.
Lower resource use and higher score define the optional Pareto frontier.
The caller is expected to provide rows for one benchmark only.
"""
from src.leaderboard import get_resource_pareto_frontier_df
try:
resource_config = _resource_axis_config(resource_metric)
except ValueError:
return empty_figure(f"Resource metric not available: {resource_metric}.", background_name)
resource_column = resource_config["column"]
if dataframe is None or dataframe.empty:
return empty_figure("No valid resource data available for this benchmark.", background_name)
if resource_column not in dataframe.columns:
return empty_figure(f"Resource metric not available: {resource_column}.", background_name)
if color_by not in ("Model", "Harness") or color_by not in dataframe.columns:
return empty_figure(f"Color dimension not available: {color_by}.", background_name)
plot_df = dataframe.copy()
if "Benchmark" in plot_df.columns and plot_df["Benchmark"].dropna().nunique() > 1:
return empty_figure("Select one benchmark for the Efficiency view.", background_name)
plot_df[resource_column] = pd.to_numeric(plot_df[resource_column], errors="coerce")
plot_df["Score (%)"] = pd.to_numeric(plot_df["Score (%)"], errors="coerce")
plot_df = plot_df.dropna(subset=[resource_column, "Score (%)"])
plot_df = plot_df[plot_df[resource_column] > 0]
if plot_df.empty:
return empty_figure("No valid resource data available for this benchmark.", background_name)
colors = color_map_for(plot_df[color_by], color_by, palette_name)
theme = get_plot_background(background_name)
fig = go.Figure()
hover_columns = [
"Model",
"Harness",
"Benchmark",
"Score (%)",
"Input Tokens Per Task",
"Output Tokens Per Task",
"Cache Tokens Per Task",
"Total Tokens Per Task",
"Cost Per Task",
"Total Time Per Task",
"Agent Time Per Task",
]
for column in hover_columns:
if column not in plot_df:
plot_df[column] = None
resource_hover = f"{resource_config['hover_label']}: %{{x:{resource_config['hover_format']}}}"
if resource_metric == "Cost per task" or resource_column == "Cost Per Task":
resource_hover = f"{resource_config['hover_label']}: $%{{x:{resource_config['hover_format']}}}"
elif resource_metric == "Agent time per task" or resource_column == "Agent Time Per Task":
resource_hover += "s"
for group, group_df in plot_df.groupby(color_by, sort=True):
label_kwargs = scatter_label_kwargs(group_df, show_labels)
fig.add_trace(
go.Scatter(
x=group_df[resource_column],
y=group_df["Score (%)"],
name=str(group),
**label_kwargs,
marker={
"size": 13,
"color": colors[str(group)],
"line": {"width": 1, "color": theme["marker_line_color"]},
},
customdata=group_df[hover_columns],
hovertemplate=(
"<b>%{customdata[0]}</b><br>"
"Harness: %{customdata[1]}<br>"
"Benchmark: %{customdata[2]}<br>"
"Score: %{customdata[3]:.1f}%<br>"
f"{resource_hover}<br>"
"Input tokens/task: %{customdata[4]:,.0f}<br>"
"Output tokens/task: %{customdata[5]:,.0f}<br>"
"Cache tokens/task: %{customdata[6]:,.0f}<br>"
"Total tokens/task: %{customdata[7]:,.0f}<br>"
"Cost/task: $%{customdata[8]:.4f}<br>"
"Total time/task: %{customdata[9]:,.1f}s<br>"
"Agent time/task: %{customdata[10]:,.1f}s"
"<extra></extra>"
),
)
)
if show_pareto_frontier:
frontier_df = get_resource_pareto_frontier_df(plot_df, resource_column)
if not frontier_df.empty:
frontier_hover = f"{resource_config['hover_label']}: %{{x:{resource_config['hover_format']}}}"
if resource_column == "Cost Per Task":
frontier_hover = f"{resource_config['hover_label']}: $%{{x:{resource_config['hover_format']}}}"
elif resource_column == "Agent Time Per Task":
frontier_hover += "s"
fig.add_trace(
go.Scatter(
x=frontier_df[resource_column],
y=frontier_df["Score (%)"],
mode="lines+markers",
name="Pareto frontier",
line={"width": 3, "dash": "dash", "color": theme["text_primary"]},
marker={
"size": 10,
"symbol": "diamond-open",
"color": theme["text_primary"],
"line": {"width": 2, "color": theme["text_primary"]},
},
customdata=frontier_df[["Run Label"]],
hovertemplate=(
"<b>Pareto frontier</b><br>"
"%{customdata[0]}<br>"
f"{frontier_hover}<br>"
"Score: %{y:.1f}%<extra></extra>"
),
)
)
xaxis = {
"title": resource_config["axis_title"],
"type": "log" if x_scale == "Log" else "linear",
}
if "tickprefix" in resource_config:
xaxis["tickprefix"] = resource_config["tickprefix"]
if "ticksuffix" in resource_config:
xaxis["ticksuffix"] = resource_config["ticksuffix"]
fig.update_layout(
title=None,
xaxis=xaxis,
yaxis={"title": "Score (%)", "range": [0, 105]},
legend_title_text=color_by,
)
return apply_plot_theme(fig, background_name)
def create_score_vs_tokens_plot(
dataframe: pd.DataFrame,
token_metric: str = "Total tokens",
color_by: ColorBy = "Model",
x_scale: Literal["Linear", "Log"] = "Log",
show_pareto_frontier: bool = True,
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
"""Backward-compatible wrapper around the performance-vs-resource chart."""
return create_performance_vs_resource_plot(
dataframe=dataframe,
resource_metric=token_metric,
color_by=color_by,
x_scale=x_scale,
show_pareto_frontier=show_pareto_frontier,
show_labels=show_labels,
palette_name=palette_name,
background_name=background_name,
)
def create_token_pareto_frontier_plot(
dataframe: pd.DataFrame,
token_metric: str = "Total tokens",
color_by: ColorBy = "Model",
x_scale: Literal["Linear", "Log"] = "Log",
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
"""Backward-compatible convenience wrapper with the Pareto frontier enabled."""
return create_performance_vs_resource_plot(
dataframe=dataframe,
resource_metric=token_metric,
color_by=color_by,
x_scale=x_scale,
show_pareto_frontier=True,
show_labels=show_labels,
palette_name=palette_name,
background_name=background_name,
)
def _categorical_chart_height(
n_rows: int,
*,
min_height: int,
row_height: int,
vertical_padding: int,
) -> int:
"""Scale dense categorical charts vertically so labels remain readable."""
return max(min_height, row_height * max(n_rows, 0) + vertical_padding)
def create_ranking_plot(
dataframe: pd.DataFrame,
metric_column: str,
metric_label: str,
higher_is_better: bool,
color_by: ColorBy = "Model",
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
sort_order: str = "Best first",
) -> Figure:
"""Generic horizontal ranking chart for any numeric metric."""
if dataframe is None or dataframe.empty or metric_column not in dataframe:
return empty_figure(f"No data available for {metric_label}.", background_name)
plot_df = dataframe.copy()
plot_df[metric_column] = pd.to_numeric(plot_df[metric_column], errors="coerce")
plot_df = plot_df.dropna(subset=[metric_column])
if plot_df.empty:
return empty_figure(f"No data available for {metric_label}.", background_name)
plot_df["Agent"] = plot_df["Model"].astype(str) + " / " + plot_df["Harness"].astype(str)
if sort_order == "Alphabetical (A–Z)":
plot_df = plot_df.sort_values(["Agent", metric_column], ascending=[True, False], kind="mergesort")
elif sort_order == "Alphabetical (Z–A)":
plot_df = plot_df.sort_values(["Agent", metric_column], ascending=[False, False], kind="mergesort")
elif sort_order in {"Best first", "Best last"}:
ascending = not higher_is_better
if sort_order == "Best last":
ascending = not ascending
plot_df = plot_df.sort_values(
[metric_column, "Agent"],
ascending=[ascending, True],
kind="mergesort",
)
elif sort_order == "Lowest value first":
plot_df = plot_df.sort_values(
[metric_column, "Agent"],
ascending=[True, True],
kind="mergesort",
)
else:
plot_df = plot_df.sort_values(
[metric_column, "Agent"],
ascending=[False, True],
kind="mergesort",
)
colors = color_map_for(plot_df[color_by], color_by, palette_name)
theme = get_plot_background(background_name)
fig = go.Figure()
for group, group_df in plot_df.groupby(color_by, sort=True):
fig.add_trace(
go.Bar(
x=group_df[metric_column],
y=group_df["Agent"],
orientation="h",
name=str(group),
marker={
"color": colors[str(group)],
"line": {"width": 1, "color": theme["marker_line_color"]},
},
customdata=group_df[["Benchmark", "Model", "Harness"]],
hovertemplate=(
"<b>%{customdata[1]}</b><br>"
"Harness: %{customdata[2]}<br>"
"Benchmark: %{customdata[0]}<br>"
f"{metric_label}: %{{x:.4g}}<extra></extra>"
),
)
)
agent_order = plot_df["Agent"].drop_duplicates().tolist()
fig.update_layout(
xaxis={"title": metric_label},
yaxis={
"title": None,
"autorange": "reversed",
"categoryorder": "array",
"categoryarray": agent_order,
"tickmode": "array",
"tickvals": agent_order,
"ticktext": agent_order,
},
legend_title_text=color_by,
barmode="group",
height=_categorical_chart_height(
len(agent_order),
min_height=RANKING_MIN_HEIGHT_PX,
row_height=RANKING_ROW_HEIGHT_PX,
vertical_padding=RANKING_VERTICAL_PADDING_PX,
),
)
return apply_plot_theme(fig, background_name)
def create_tradeoff_plot(
dataframe: pd.DataFrame,
x_column: str,
y_column: str,
x_label: str,
y_label: str,
color_by: ColorBy = "Model",
show_labels: bool = False,
palette_name: str | None = DEFAULT_PALETTE,
background_name: str | None = DEFAULT_BACKGROUND,
x_scale: Literal["Linear", "Log"] = "Linear",
y_scale: Literal["Linear", "Log"] = "Linear",
show_pareto_frontier: bool = False,
lower_x_is_better: bool = True,
higher_y_is_better: bool = True,
) -> Figure:
"""Generic two-metric scatter used by PR2 trade-off views."""
if dataframe is None or dataframe.empty:
return empty_figure("No trade-off data available.", background_name)
if x_column not in dataframe or y_column not in dataframe:
return empty_figure("Selected trade-off metric is unavailable.", background_name)
if color_by not in ("Model", "Harness") or color_by not in dataframe:
return empty_figure(f"Color dimension not available: {color_by}.", background_name)
plot_df = dataframe.copy()
plot_df[x_column] = pd.to_numeric(plot_df[x_column], errors="coerce")
plot_df[y_column] = pd.to_numeric(plot_df[y_column], errors="coerce")
plot_df = plot_df.dropna(subset=[x_column, y_column])
if x_scale == "Log":
plot_df = plot_df[plot_df[x_column] > 0]
if y_scale == "Log":
plot_df = plot_df[plot_df[y_column] > 0]
if plot_df.empty:
return empty_figure("No valid points for the selected trade-off.", background_name)
colors = color_map_for(plot_df[color_by], color_by, palette_name)
theme = get_plot_background(background_name)
fig = go.Figure()
for group, group_df in plot_df.groupby(color_by, sort=True):
label_kwargs = scatter_label_kwargs(group_df, show_labels)
fig.add_trace(
go.Scatter(
x=group_df[x_column],
y=group_df[y_column],
name=str(group),
**label_kwargs,
marker={
"size": 13,
"color": colors[str(group)],
"line": {"width": 1, "color": theme["marker_line_color"]},
},
customdata=group_df[["Model", "Harness", "Benchmark"]],
hovertemplate=(
"<b>%{customdata[0]}</b><br>"
"Harness: %{customdata[1]}<br>"
"Benchmark: %{customdata[2]}<br>"
f"{x_label}: %{{x:.4g}}<br>"
f"{y_label}: %{{y:.4g}}<extra></extra>"
),
)
)
if show_pareto_frontier:
from src.leaderboard import get_pareto_frontier_df
frontier = get_pareto_frontier_df(
plot_df,
x_column,
y_column,
lower_x_is_better=lower_x_is_better,
higher_y_is_better=higher_y_is_better,
)
if not frontier.empty:
fig.add_trace(
go.Scatter(
x=frontier[x_column],
y=frontier[y_column],
mode="lines+markers",
name="Pareto frontier",
line={"width": 3, "dash": "dash", "color": theme["text_primary"]},
marker={"size": 9, "symbol": "diamond-open"},
hovertemplate=f"{x_label}: %{{x:.4g}}<br>{y_label}: %{{y:.4g}}<extra></extra>",
)
)
fig.update_layout(
xaxis={"title": x_label, "type": "log" if x_scale == "Log" else "linear"},
yaxis={"title": y_label, "type": "log" if y_scale == "Log" else "linear"},
legend_title_text=color_by,
)
return apply_plot_theme(fig, background_name)
def create_matrix_plot(
matrix: pd.DataFrame,
title: str,
metric_label: str,
higher_is_better: bool = True,
show_values: bool = True,
reverse_scale: bool | None = None,
background_name: str | None = DEFAULT_BACKGROUND,
display_matrix: pd.DataFrame | None = None,
display_metric_label: str | None = None,
) -> Figure:
"""Render a reusable model/harness × benchmark matrix."""
if matrix is None or matrix.empty:
return empty_figure(f"No data available for {title}.", background_name)
reverse = (not higher_is_better) if reverse_scale is None else reverse_scale
colorscale = "Viridis_r" if reverse else "Viridis"
z = matrix.to_numpy(dtype=float)
text = None
texttemplate = None
display_values = matrix if display_matrix is None else display_matrix.reindex(
index=matrix.index, columns=matrix.columns
)
display_z = display_values.to_numpy(dtype=float)
if show_values:
text = [[("" if pd.isna(value) else f"{value:.4g}") for value in row] for row in display_z]
texttemplate = "%{text}"
hover_label = display_metric_label or metric_label
customdata = display_z if display_matrix is not None else None
hovertemplate = (
"Agent: %{y}<br>"
"Benchmark: %{x}<br>"
+ (
f"{hover_label}: %{{customdata:.4g}}<br>{metric_label}: %{{z:.4g}}<extra></extra>"
if display_matrix is not None
else f"{metric_label}: %{{z:.4g}}<extra></extra>"
)
)
fig = go.Figure(
go.Heatmap(
z=z,
x=[str(value) for value in matrix.columns],
y=[str(value) for value in matrix.index],
colorscale=colorscale,
colorbar={"title": metric_label},
text=text,
texttemplate=texttemplate,
customdata=customdata,
hovertemplate=hovertemplate,
hoverongaps=False,
)
)
row_labels = [str(value) for value in matrix.index]
fig.update_layout(
title=title,
xaxis={"title": "Benchmark"},
yaxis={
"title": "Model / Harness",
"autorange": "reversed",
"tickmode": "array",
"tickvals": row_labels,
"ticktext": row_labels,
},
height=_categorical_chart_height(
len(row_labels),
min_height=MATRIX_MIN_HEIGHT_PX,
row_height=MATRIX_ROW_HEIGHT_PX,
vertical_padding=MATRIX_VERTICAL_PADDING_PX,
),
)
return apply_plot_theme(fig, background_name)
def create_coverage_matrix_plot(
matrix: pd.DataFrame,
background_name: str | None = DEFAULT_BACKGROUND,
) -> Figure:
"""Render coverage as available/missing without converting missing data to score zero."""
if matrix is None or matrix.empty:
return empty_figure("No benchmark coverage data available.", background_name)
display = matrix.copy()
z = display.notna().astype(int).to_numpy()
text = [["Available" if value else "Missing" for value in row] for row in z]
fig = go.Figure(
go.Heatmap(
z=z,
x=[str(value) for value in display.columns],
y=[str(value) for value in display.index],
zmin=0,
zmax=1,
colorscale=[[0, "#475569"], [1, "#84cc16"]],
showscale=False,
text=text,
texttemplate="%{text}",
hovertemplate="Agent: %{y}<br>Benchmark: %{x}<br>Status: %{text}<extra></extra>",
)
)
row_labels = [str(value) for value in display.index]
fig.update_layout(
title="Benchmark coverage",
xaxis={"title": "Benchmark"},
yaxis={
"title": "Model / Harness",
"autorange": "reversed",
"tickmode": "array",
"tickvals": row_labels,
"ticktext": row_labels,
},
height=_categorical_chart_height(
len(row_labels),
min_height=MATRIX_MIN_HEIGHT_PX,
row_height=MATRIX_ROW_HEIGHT_PX,
vertical_padding=MATRIX_VERTICAL_PADDING_PX,
),
)
return apply_plot_theme(fig, background_name)