DOoM-lb / src /plots.py
Anonumous's picture
Refactor project structure and update project version
0d67035
"""
Visualization functions for DeathMath Leaderboard analytics.
Provides bar charts and radar plots for model comparison.
"""
import itertools as it
import random
import matplotlib.pyplot as plt
import numpy as np
import plotly.graph_objects as go
from matplotlib.figure import Figure
from src.leaderboard import build_leaderboard_df
def create_plot(selected_models: list[str]) -> Figure:
"""
Create bar chart visualization comparing selected models.
Args:
selected_models: List of model names to display
Returns:
Matplotlib figure with bar chart comparing metrics across models
"""
models_df = build_leaderboard_df()
if not selected_models or models_df.empty:
fig, ax = plt.subplots(figsize=(10, 6))
ax.text(
0.5,
0.5,
"Нет данных для отображения",
horizontalalignment="center",
verticalalignment="center",
transform=ax.transAxes,
fontsize=14,
)
ax.set_axis_off()
return fig
models_to_show = models_df[models_df["model"].isin(selected_models)]
if models_to_show.empty:
fig, ax = plt.subplots(figsize=(10, 6))
ax.text(
0.5,
0.5,
"Выбранные модели не найдены в данных",
horizontalalignment="center",
verticalalignment="center",
transform=ax.transAxes,
fontsize=14,
)
ax.set_axis_off()
return fig
fig, ax = plt.subplots(figsize=(12, 8))
bar_width = 0.25
models_count = len(models_to_show)
indices = np.arange(models_count)
colors = ["#1f77b4", "#ff7f0e", "#2ca02c"]
ax.bar(indices - bar_width, models_to_show["math_score"], bar_width, label="RussianMath Score", color=colors[0])
ax.bar(indices, models_to_show["physics_score"], bar_width, label="RussianPhysics Score", color=colors[1])
ax.bar(indices + bar_width, models_to_show["score"], bar_width, label="Combined Score", color=colors[2])
ax.set_xlabel("Модели")
ax.set_ylabel("Баллы")
ax.set_title("Сравнение производительности моделей на DeathMath benchmark")
ax.set_xticks(indices)
ax.set_xticklabels(models_to_show["model"], rotation=45, ha="right")
ax.legend()
ax.set_ylim(0, 1.0)
ax.grid(axis="y", linestyle="--", alpha=0.7)
plt.tight_layout()
return fig
def create_radar_plot(selected_models: list[str]) -> go.Figure:
"""
Create radar chart visualization comparing selected models.
Args:
selected_models: List of model names to display
Returns:
Plotly figure with interactive radar chart
"""
models = build_leaderboard_df()
metrics = ["math_score", "physics_score", "score"]
metric_labels = ["RussianMath", "RussianPhysics", "Combined"]
min_colour_distance_between_models = 100
seed = 42
def generate_colours(min_distance: int, seed: int) -> dict[str, tuple[int, int, int]]:
"""Generate distinct colors for each model."""
colour_mapping = {}
all_models = selected_models
for i in it.count():
min_colour_distance = min_distance - i
retries_left = 10 * len(all_models)
for model_id in all_models:
random.seed(hash(model_id) + i + seed)
r, g, b = 0, 0, 0
too_bright, similar_to_other_model = True, True
while (too_bright or similar_to_other_model) and retries_left > 0:
r, g, b = tuple(random.randint(0, 255) for _ in range(3))
too_bright = np.min([r, g, b]) > 200
similar_to_other_model = any(
np.abs(np.array(colour) - np.array([r, g, b])).sum() < min_colour_distance
for colour in colour_mapping.values()
)
retries_left -= 1
colour_mapping[model_id] = (r, g, b)
if len(colour_mapping) == len(all_models):
break
return colour_mapping
colour_mapping = generate_colours(min_colour_distance_between_models, seed)
fig = go.Figure()
for _, model_data in models.iterrows():
model_name = model_data["model"]
if model_name not in selected_models:
continue
values = [model_data[metric] for metric in metrics]
color = f"rgb{colour_mapping[model_name]}"
fig.add_trace(
go.Scatterpolar(
r=values,
theta=metric_labels,
name=model_name,
fill="toself",
fillcolor=f"rgba{colour_mapping[model_name] + (0.6,)}",
line={"color": color},
)
)
fig.update_layout(
polar={"radialaxis": {"visible": True, "range": [0, 1]}},
showlegend=True,
title="Сравнение моделей на DeathMath",
template="plotly_dark",
)
return fig