|
|
|
|
|
"""
|
|
|
Edit Trace Visualizer Module
|
|
|
Interactive visualization of edit traces and backend performance
|
|
|
"""
|
|
|
import numpy as np
|
|
|
from typing import Dict, List, Optional
|
|
|
try:
|
|
|
import plotly.graph_objects as go
|
|
|
import plotly.express as px
|
|
|
from plotly.subplots import make_subplots
|
|
|
PLOTLY_AVAILABLE = True
|
|
|
except ImportError:
|
|
|
PLOTLY_AVAILABLE = False
|
|
|
print("⚠️ Plotly not available. Install with: pip install plotly")
|
|
|
|
|
|
|
|
|
class EditTraceVisualizer:
|
|
|
"""Visualize edit traces and performance"""
|
|
|
|
|
|
def __init__(self):
|
|
|
"""Initialize visualizer"""
|
|
|
self.figures = []
|
|
|
|
|
|
def create_dashboard(
|
|
|
self,
|
|
|
edit_logs: List[Dict],
|
|
|
backends: List[str] = None,
|
|
|
languages: List[str] = None
|
|
|
):
|
|
|
"""
|
|
|
Create interactive dashboard
|
|
|
|
|
|
Args:
|
|
|
edit_logs: List of edit logs
|
|
|
backends: Backends to visualize
|
|
|
languages: Languages to include
|
|
|
|
|
|
Returns:
|
|
|
Plotly figure or None
|
|
|
"""
|
|
|
if not PLOTLY_AVAILABLE:
|
|
|
print("⚠️ Plotly required for visualization")
|
|
|
return None
|
|
|
|
|
|
backends = backends or ['russian', 'ibm']
|
|
|
languages = languages or ['en', 'ru', 'es', 'fr', 'de']
|
|
|
|
|
|
|
|
|
fig = make_subplots(
|
|
|
rows=2, cols=2,
|
|
|
subplot_titles=(
|
|
|
'Backend Performance Comparison',
|
|
|
'Language-Specific Accuracy',
|
|
|
'Edit Type Distribution',
|
|
|
'Latency Distribution'
|
|
|
)
|
|
|
)
|
|
|
|
|
|
|
|
|
backend_data = self._aggregate_by_backend(edit_logs, backends)
|
|
|
fig.add_trace(
|
|
|
go.Bar(
|
|
|
x=list(backend_data.keys()),
|
|
|
y=[d['success_rate'] for d in backend_data.values()],
|
|
|
name='Success Rate'
|
|
|
),
|
|
|
row=1, col=1
|
|
|
)
|
|
|
|
|
|
|
|
|
lang_data = self._aggregate_by_language(edit_logs, languages)
|
|
|
fig.add_trace(
|
|
|
go.Bar(
|
|
|
x=list(lang_data.keys()),
|
|
|
y=[d['accuracy'] for d in lang_data.values()],
|
|
|
name='Accuracy'
|
|
|
),
|
|
|
row=1, col=2
|
|
|
)
|
|
|
|
|
|
|
|
|
type_data = self._aggregate_by_type(edit_logs)
|
|
|
fig.add_trace(
|
|
|
go.Pie(
|
|
|
labels=list(type_data.keys()),
|
|
|
values=list(type_data.values()),
|
|
|
name='Edit Types'
|
|
|
),
|
|
|
row=2, col=1
|
|
|
)
|
|
|
|
|
|
|
|
|
latencies = [log.get('latency_ms', 0) for log in edit_logs]
|
|
|
fig.add_trace(
|
|
|
go.Histogram(
|
|
|
x=latencies,
|
|
|
name='Latency'
|
|
|
),
|
|
|
row=2, col=2
|
|
|
)
|
|
|
|
|
|
fig.update_layout(
|
|
|
title_text="Quantum Backend Performance Dashboard",
|
|
|
showlegend=True,
|
|
|
height=800
|
|
|
)
|
|
|
|
|
|
self.figures.append(fig)
|
|
|
return fig
|
|
|
|
|
|
def create_heatmap(
|
|
|
self,
|
|
|
edit_logs: List[Dict],
|
|
|
x_axis: str = 'language',
|
|
|
y_axis: str = 'domain'
|
|
|
):
|
|
|
"""Create performance heatmap"""
|
|
|
if not PLOTLY_AVAILABLE:
|
|
|
return None
|
|
|
|
|
|
|
|
|
matrix = self._create_matrix(edit_logs, x_axis, y_axis)
|
|
|
|
|
|
fig = go.Figure(data=go.Heatmap(
|
|
|
z=matrix['values'],
|
|
|
x=matrix['x_labels'],
|
|
|
y=matrix['y_labels'],
|
|
|
colorscale='Viridis'
|
|
|
))
|
|
|
|
|
|
fig.update_layout(
|
|
|
title=f'Performance Heatmap: {y_axis.title()} vs {x_axis.title()}',
|
|
|
xaxis_title=x_axis.title(),
|
|
|
yaxis_title=y_axis.title()
|
|
|
)
|
|
|
|
|
|
self.figures.append(fig)
|
|
|
return fig
|
|
|
|
|
|
def show_dashboard(self):
|
|
|
"""Display all created figures"""
|
|
|
if not self.figures:
|
|
|
print("⚠️ No figures to display. Create dashboard first.")
|
|
|
return
|
|
|
|
|
|
for fig in self.figures:
|
|
|
if fig:
|
|
|
fig.show()
|
|
|
|
|
|
def _aggregate_by_backend(
|
|
|
self,
|
|
|
logs: List[Dict],
|
|
|
backends: List[str]
|
|
|
) -> Dict:
|
|
|
"""Aggregate metrics by backend"""
|
|
|
data = {}
|
|
|
for backend in backends:
|
|
|
backend_logs = [l for l in logs if l.get('backend') == backend]
|
|
|
if backend_logs:
|
|
|
success = sum(1 for l in backend_logs if l.get('success', False))
|
|
|
data[backend] = {
|
|
|
'success_rate': success / len(backend_logs),
|
|
|
'count': len(backend_logs)
|
|
|
}
|
|
|
return data
|
|
|
|
|
|
def _aggregate_by_language(
|
|
|
self,
|
|
|
logs: List[Dict],
|
|
|
languages: List[str]
|
|
|
) -> Dict:
|
|
|
"""Aggregate metrics by language"""
|
|
|
data = {}
|
|
|
for lang in languages:
|
|
|
lang_logs = [l for l in logs if l.get('lang') == lang]
|
|
|
if lang_logs:
|
|
|
success = sum(1 for l in lang_logs if l.get('success', False))
|
|
|
data[lang] = {
|
|
|
'accuracy': success / len(lang_logs),
|
|
|
'count': len(lang_logs)
|
|
|
}
|
|
|
return data
|
|
|
|
|
|
def _aggregate_by_type(self, logs: List[Dict]) -> Dict:
|
|
|
"""Aggregate by edit type"""
|
|
|
types = {}
|
|
|
for log in logs:
|
|
|
edit_type = log.get('type', 'unknown')
|
|
|
types[edit_type] = types.get(edit_type, 0) + 1
|
|
|
return types
|
|
|
|
|
|
def _create_matrix(
|
|
|
self,
|
|
|
logs: List[Dict],
|
|
|
x_axis: str,
|
|
|
y_axis: str
|
|
|
) -> Dict:
|
|
|
"""Create matrix for heatmap"""
|
|
|
|
|
|
x_values = sorted(set(log.get(x_axis, 'unknown') for log in logs))
|
|
|
y_values = sorted(set(log.get(y_axis, 'unknown') for log in logs))
|
|
|
|
|
|
|
|
|
matrix = np.zeros((len(y_values), len(x_values)))
|
|
|
|
|
|
for i, y_val in enumerate(y_values):
|
|
|
for j, x_val in enumerate(x_values):
|
|
|
matching = [
|
|
|
l for l in logs
|
|
|
if l.get(x_axis) == x_val and l.get(y_axis) == y_val
|
|
|
]
|
|
|
if matching:
|
|
|
success = sum(1 for l in matching if l.get('success', False))
|
|
|
matrix[i, j] = success / len(matching)
|
|
|
|
|
|
return {
|
|
|
'values': matrix.tolist(),
|
|
|
'x_labels': x_values,
|
|
|
'y_labels': y_values
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def quick_visualize(edit_logs: List[Dict]):
|
|
|
"""Quick visualization"""
|
|
|
viz = EditTraceVisualizer()
|
|
|
dashboard = viz.create_dashboard(edit_logs)
|
|
|
if dashboard:
|
|
|
dashboard.show()
|
|
|
|