MudabbirAI / visuals.py
youssefleb's picture
Create visuals.py
18d97d0 verified
raw
history blame
3.49 kB
# visuals.py
# Handles all data visualization logic for MudabbirAI
import pandas as pd
import plotly.graph_objects as go
def create_progress_chart(log_data):
"""
Generates a Radar Chart comparing the initial draft scores vs. the final scores.
"""
if not log_data or "trace" not in log_data:
return None
# Filter for "attempt" steps to get the scores
attempts = [step for step in log_data["trace"] if step["step_type"] == "attempt"]
if not attempts:
return None
# Define the standard criteria
categories = ["Novelty", "Usefulness_Feasibility", "Flexibility", "Elaboration", "Cultural_Appropriateness"]
fig = go.Figure()
for i, attempt in enumerate(attempts):
scores = attempt.get("scores", {})
# Handle cases where scores might be missing (default to 0)
values = [scores.get(cat, 0) for cat in categories]
# Close the loop for radar chart (repeat first value at the end)
values += [values[0]]
radar_categories = categories + [categories[0]]
name = f"Initial Draft" if i == 0 else f"Improved Draft (Loop {i})"
color = "red" if i == 0 else "green"
fig.add_trace(go.Scatterpolar(
r=values,
theta=radar_categories,
fill='toself',
name=name,
line_color=color
))
fig.update_layout(
polar=dict(
radialaxis=dict(
visible=True,
range=[0, 5] # Scores are always 0-5
)),
showlegend=True,
title="Evolution of Solution Quality"
)
return fig
def create_calibration_table(log_data):
"""
Generates a Pandas DataFrame showing the 'Audition Scores' for the calibration phase.
"""
if not log_data or "trace" not in log_data:
return None
# Find the calibration step in the log
calibration_step = next((step for step in log_data["trace"] if step["step_type"] == "calibration"), None)
# If no calibration happened (e.g. Single Agent mode), return None
if not calibration_step or "details" not in calibration_step:
return None
# details is a list of dicts: {'role': 'Plant', 'llm': 'Gemini', 'score': {...}}
details = calibration_step["details"]
data = []
for item in details:
role = item["role"]
model = item["llm"]
# The 'score' field contains the full evaluation object.
# We need to extract the specific numeric score relevant to that Role.
# Plant -> Novelty, Implementer -> Feasibility, Monitor -> Cultural
score_data = item.get("score", {})
score = 0
if isinstance(score_data, dict):
if role == "Plant":
score = score_data.get("Novelty", {}).get("score", 0)
elif role == "Implementer":
score = score_data.get("Usefulness_Feasibility", {}).get("score", 0)
elif role == "Monitor":
score = score_data.get("Cultural_Appropriateness", {}).get("score", 0)
data.append({"Role": role, "Model": model, "Score": score})
if not data:
return None
df = pd.DataFrame(data)
# Pivot the table: Rows = Roles, Columns = Models, Values = Scores
# This creates a nice comparison matrix
pivot_df = df.pivot(index="Role", columns="Model", values="Score").reset_index()
return pivot_df