Spaces:
Running
Running
| """ | |
| 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 | |