transformers-ci-dashboard / time_series.py
badaoui's picture
badaoui HF Staff
Add historical data visualization features
5309153
raw
history blame
15.1 kB
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from datetime import datetime
from data import extract_model_data
COLORS = {
'passed': '#4CAF50',
'failed': '#E53E3E',
'skipped': '#FFD54F',
'error': '#8B0000',
'amd': '#ED1C24',
'nvidia': '#76B900'
}
FIGURE_WIDTH = 20
FIGURE_HEIGHT = 12
BLACK = '#000000'
LABEL_COLOR = '#CCCCCC'
TITLE_COLOR = '#FFFFFF'
GRID_COLOR = '#333333'
TITLE_FONT_SIZE = 24
LABEL_FONT_SIZE = 14
LEGEND_FONT_SIZE = 12
def create_time_series_summary(historical_df: pd.DataFrame) -> plt.Figure:
if historical_df.empty or 'date' not in historical_df.columns:
fig, ax = plt.subplots(figsize=(FIGURE_WIDTH, FIGURE_HEIGHT), facecolor=BLACK)
ax.set_facecolor(BLACK)
ax.text(0.5, 0.5, 'No historical data available',
horizontalalignment='center', verticalalignment='center',
transform=ax.transAxes, fontsize=20, color='#888888',
fontfamily='monospace', weight='normal')
ax.axis('off')
return fig
historical_df['date_dt'] = pd.to_datetime(historical_df['date'])
historical_df = historical_df.sort_values('date_dt')
daily_stats = []
dates = []
for date in historical_df['date_dt'].unique():
date_data = historical_df[historical_df['date_dt'] == date]
total_amd_passed = total_amd_failed = total_amd_skipped = 0
total_nvidia_passed = total_nvidia_failed = total_nvidia_skipped = 0
for _, row in date_data.iterrows():
amd_stats, nvidia_stats = extract_model_data(row)[:2]
total_amd_passed += amd_stats['passed']
total_amd_failed += amd_stats['failed']
total_amd_skipped += amd_stats['skipped']
total_nvidia_passed += nvidia_stats['passed']
total_nvidia_failed += nvidia_stats['failed']
total_nvidia_skipped += nvidia_stats['skipped']
amd_total = total_amd_passed + total_amd_failed
nvidia_total = total_nvidia_passed + total_nvidia_failed
amd_failure_rate = (total_amd_failed / amd_total * 100) if amd_total > 0 else 0
nvidia_failure_rate = (total_nvidia_failed / nvidia_total * 100) if nvidia_total > 0 else 0
daily_stats.append({
'amd_failure_rate': amd_failure_rate,
'nvidia_failure_rate': nvidia_failure_rate,
'amd_passed': total_amd_passed,
'amd_failed': total_amd_failed,
'amd_skipped': total_amd_skipped,
'nvidia_passed': total_nvidia_passed,
'nvidia_failed': total_nvidia_failed,
'nvidia_skipped': total_nvidia_skipped
})
dates.append(date)
fig = plt.figure(figsize=(FIGURE_WIDTH, FIGURE_HEIGHT + 4), facecolor=BLACK)
gs = fig.add_gridspec(3, 2, height_ratios=[1.2, 1, 1], width_ratios=[2, 1],
hspace=0.3, wspace=0.25)
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, 0])
ax3 = fig.add_subplot(gs[2, 0])
ax4 = fig.add_subplot(gs[1:, 1])
for ax in [ax1, ax2, ax3, ax4]:
ax.set_facecolor(BLACK)
dates_array = np.array(dates)
amd_rates = [stat['amd_failure_rate'] for stat in daily_stats]
nvidia_rates = [stat['nvidia_failure_rate'] for stat in daily_stats]
ax1.fill_between(dates_array, 0, amd_rates, color=COLORS['amd'], alpha=0.15)
ax1.fill_between(dates_array, 0, nvidia_rates, color=COLORS['nvidia'], alpha=0.15)
ax1.plot(dates_array, amd_rates, color=COLORS['amd'], linewidth=3,
label='AMD', marker='o', markersize=7, markeredgewidth=2, markeredgecolor=BLACK)
ax1.plot(dates_array, nvidia_rates, color=COLORS['nvidia'], linewidth=3,
label='NVIDIA', marker='s', markersize=7, markeredgewidth=2, markeredgecolor=BLACK)
if len(amd_rates) > 2:
z_amd = np.polyfit(range(len(amd_rates)), amd_rates, 1)
p_amd = np.poly1d(z_amd)
ax1.plot(dates_array, p_amd(range(len(amd_rates))),
color=COLORS['amd'], linestyle='--', alpha=0.5, linewidth=2)
z_nvidia = np.polyfit(range(len(nvidia_rates)), nvidia_rates, 1)
p_nvidia = np.poly1d(z_nvidia)
ax1.plot(dates_array, p_nvidia(range(len(nvidia_rates))),
color=COLORS['nvidia'], linestyle='--', alpha=0.5, linewidth=2)
ax1.set_title('Overall Failure Rates Over Time', fontsize=TITLE_FONT_SIZE,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold', pad=20)
ax1.set_ylabel('Failure Rate (%)', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax1.grid(True, color=GRID_COLOR, alpha=0.3, linestyle='-', linewidth=0.5)
ax1.legend(fontsize=LEGEND_FONT_SIZE, loc='upper right', frameon=False,
labelcolor=LABEL_COLOR, prop={'family': 'monospace'})
ax1.tick_params(colors=LABEL_COLOR, labelsize=LABEL_FONT_SIZE, axis='x', rotation=45)
amd_passed = [stat['amd_passed'] for stat in daily_stats]
amd_failed = [stat['amd_failed'] for stat in daily_stats]
amd_skipped = [stat['amd_skipped'] for stat in daily_stats]
ax2.stackplot(dates_array, amd_passed, amd_failed, amd_skipped,
colors=[COLORS['passed'], COLORS['failed'], COLORS['skipped']],
alpha=0.8, labels=['Passed', 'Failed', 'Skipped'])
ax2.set_title('AMD Test Results', fontsize=TITLE_FONT_SIZE - 2,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold', pad=15)
ax2.set_ylabel('Tests', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax2.grid(True, color=GRID_COLOR, alpha=0.3, linestyle='-', linewidth=0.5)
ax2.tick_params(colors=LABEL_COLOR, labelsize=LABEL_FONT_SIZE - 1, axis='x', rotation=45)
nvidia_passed = [stat['nvidia_passed'] for stat in daily_stats]
nvidia_failed = [stat['nvidia_failed'] for stat in daily_stats]
nvidia_skipped = [stat['nvidia_skipped'] for stat in daily_stats]
ax3.stackplot(dates_array, nvidia_passed, nvidia_failed, nvidia_skipped,
colors=[COLORS['passed'], COLORS['failed'], COLORS['skipped']],
alpha=0.8, labels=['Passed', 'Failed', 'Skipped'])
ax3.set_title('NVIDIA Test Results', fontsize=TITLE_FONT_SIZE - 2,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold', pad=15)
ax3.set_ylabel('Tests', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax3.set_xlabel('Date', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax3.grid(True, color=GRID_COLOR, alpha=0.3, linestyle='-', linewidth=0.5)
ax3.tick_params(colors=LABEL_COLOR, labelsize=LABEL_FONT_SIZE - 1, axis='x', rotation=45)
latest = daily_stats[-1]
metrics = [
('Latest AMD Failure Rate', f"{latest['amd_failure_rate']:.1f}%", COLORS['amd']),
('Latest NVIDIA Failure Rate', f"{latest['nvidia_failure_rate']:.1f}%", COLORS['nvidia']),
('', '', None),
('Total AMD Tests', str(latest['amd_passed'] + latest['amd_failed'] + latest['amd_skipped']), '#888888'),
('Total NVIDIA Tests', str(latest['nvidia_passed'] + latest['nvidia_failed'] + latest['nvidia_skipped']), '#888888'),
]
ax4.axis('off')
y_pos = 0.9
ax4.text(0.5, 0.95, 'SUMMARY', ha='center', va='top', fontsize=TITLE_FONT_SIZE - 2,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold',
transform=ax4.transAxes)
for label, value, color in metrics:
if label:
ax4.text(0.1, y_pos, label, ha='left', va='center', fontsize=LABEL_FONT_SIZE,
color=LABEL_COLOR, fontfamily='monospace', transform=ax4.transAxes)
ax4.text(0.9, y_pos, value, ha='right', va='center', fontsize=LABEL_FONT_SIZE + 2,
color=color or LABEL_COLOR, fontfamily='monospace', fontweight='bold',
transform=ax4.transAxes)
y_pos -= 0.15
handles = [plt.Rectangle((0,0),1,1, fc=COLORS['passed'], alpha=0.8),
plt.Rectangle((0,0),1,1, fc=COLORS['failed'], alpha=0.8),
plt.Rectangle((0,0),1,1, fc=COLORS['skipped'], alpha=0.8)]
ax4.legend(handles, ['Passed', 'Failed', 'Skipped'],
loc='lower center', fontsize=LEGEND_FONT_SIZE,
frameon=False, labelcolor=LABEL_COLOR, prop={'family': 'monospace'})
plt.close('all')
return fig
def create_model_time_series(historical_df: pd.DataFrame, model_name: str) -> plt.Figure:
if historical_df.empty or 'date' not in historical_df.columns:
fig, ax = plt.subplots(figsize=(FIGURE_WIDTH, FIGURE_HEIGHT), facecolor=BLACK)
ax.set_facecolor(BLACK)
ax.text(0.5, 0.5, f'No historical data available for {model_name}',
horizontalalignment='center', verticalalignment='center',
transform=ax.transAxes, fontsize=20, color='#888888',
fontfamily='monospace', weight='normal')
ax.axis('off')
return fig
model_data = historical_df[historical_df.index.str.lower() == model_name.lower()]
if model_data.empty:
fig, ax = plt.subplots(figsize=(FIGURE_WIDTH, FIGURE_HEIGHT), facecolor=BLACK)
ax.set_facecolor(BLACK)
ax.text(0.5, 0.5, f'No data found for model: {model_name}',
horizontalalignment='center', verticalalignment='center',
transform=ax.transAxes, fontsize=20, color='#888888',
fontfamily='monospace', weight='normal')
ax.axis('off')
return fig
model_data = model_data.copy()
model_data['date_dt'] = pd.to_datetime(model_data['date'])
model_data = model_data.sort_values('date_dt')
dates = model_data['date_dt'].values
amd_stats_list = []
nvidia_stats_list = []
for _, row in model_data.iterrows():
amd_stats, nvidia_stats = extract_model_data(row)[:2]
amd_stats_list.append(amd_stats)
nvidia_stats_list.append(nvidia_stats)
fig = plt.figure(figsize=(FIGURE_WIDTH, FIGURE_HEIGHT), facecolor=BLACK)
gs = fig.add_gridspec(2, 2, height_ratios=[1, 1], width_ratios=[3, 1],
hspace=0.3, wspace=0.2)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[1, 0])
ax3 = fig.add_subplot(gs[:, 1])
for ax in [ax1, ax2, ax3]:
ax.set_facecolor(BLACK)
amd_passed = [stats['passed'] for stats in amd_stats_list]
amd_failed = [stats['failed'] for stats in amd_stats_list]
amd_skipped = [stats['skipped'] for stats in amd_stats_list]
ax1.stackplot(dates, amd_passed, amd_failed, amd_skipped,
colors=[COLORS['passed'], COLORS['failed'], COLORS['skipped']],
alpha=0.7, labels=['Passed', 'Failed', 'Skipped'])
ax1.plot(dates, amd_failed, color=COLORS['failed'], linewidth=2.5,
marker='o', markersize=7, markeredgewidth=2, markeredgecolor=BLACK,
linestyle='-', label='_nolegend_')
ax1.set_title(f'{model_name.upper()} - AMD Results', fontsize=TITLE_FONT_SIZE,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold', pad=20)
ax1.set_ylabel('Number of Tests', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax1.grid(True, color=GRID_COLOR, alpha=0.3, linestyle='-', linewidth=0.5)
ax1.legend(fontsize=LEGEND_FONT_SIZE, loc='upper left', frameon=False,
labelcolor=LABEL_COLOR, prop={'family': 'monospace'})
ax1.tick_params(colors=LABEL_COLOR, labelsize=LABEL_FONT_SIZE, axis='x', rotation=45)
nvidia_passed = [stats['passed'] for stats in nvidia_stats_list]
nvidia_failed = [stats['failed'] for stats in nvidia_stats_list]
nvidia_skipped = [stats['skipped'] for stats in nvidia_stats_list]
ax2.stackplot(dates, nvidia_passed, nvidia_failed, nvidia_skipped,
colors=[COLORS['passed'], COLORS['failed'], COLORS['skipped']],
alpha=0.7, labels=['Passed', 'Failed', 'Skipped'])
ax2.plot(dates, nvidia_failed, color=COLORS['failed'], linewidth=2.5,
marker='s', markersize=7, markeredgewidth=2, markeredgecolor=BLACK,
linestyle='-', label='_nolegend_')
ax2.set_title(f'{model_name.upper()} - NVIDIA Results', fontsize=TITLE_FONT_SIZE,
color=TITLE_COLOR, fontfamily='monospace', fontweight='bold', pad=20)
ax2.set_ylabel('Number of Tests', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax2.set_xlabel('Date', fontsize=LABEL_FONT_SIZE, color=LABEL_COLOR, fontfamily='monospace')
ax2.grid(True, color=GRID_COLOR, alpha=0.3, linestyle='-', linewidth=0.5)
ax2.tick_params(colors=LABEL_COLOR, labelsize=LABEL_FONT_SIZE, axis='x', rotation=45)
ax3.axis('off')
latest_amd = amd_stats_list[-1]
latest_nvidia = nvidia_stats_list[-1]
amd_total = latest_amd['passed'] + latest_amd['failed']
nvidia_total = latest_nvidia['passed'] + latest_nvidia['failed']
amd_fail_rate = (latest_amd['failed'] / amd_total * 100) if amd_total > 0 else 0
nvidia_fail_rate = (latest_nvidia['failed'] / nvidia_total * 100) if nvidia_total > 0 else 0
ax3.text(0.5, 0.95, 'LATEST RESULTS', ha='center', va='top',
fontsize=TITLE_FONT_SIZE - 4, color=TITLE_COLOR, fontfamily='monospace',
fontweight='bold', transform=ax3.transAxes)
y = 0.80
sections = [
('AMD', [
('Pass Rate', f"{(latest_amd['passed']/amd_total*100) if amd_total > 0 else 0:.1f}%", COLORS['passed']),
('Fail Rate', f"{amd_fail_rate:.1f}%", COLORS['failed']),
('Total', str(latest_amd['passed'] + latest_amd['failed'] + latest_amd['skipped']), '#888888'),
]),
('NVIDIA', [
('Pass Rate', f"{(latest_nvidia['passed']/nvidia_total*100) if nvidia_total > 0 else 0:.1f}%", COLORS['passed']),
('Fail Rate', f"{nvidia_fail_rate:.1f}%", COLORS['failed']),
('Total', str(latest_nvidia['passed'] + latest_nvidia['failed'] + latest_nvidia['skipped']), '#888888'),
])
]
for section_name, metrics in sections:
ax3.text(0.5, y, section_name, ha='center', va='center',
fontsize=LABEL_FONT_SIZE + 2, color=TITLE_COLOR,
fontfamily='monospace', fontweight='bold', transform=ax3.transAxes)
y -= 0.08
for label, value, color in metrics:
ax3.text(0.15, y, label, ha='left', va='center',
fontsize=LABEL_FONT_SIZE - 1, color=LABEL_COLOR,
fontfamily='monospace', transform=ax3.transAxes)
ax3.text(0.85, y, value, ha='right', va='center',
fontsize=LABEL_FONT_SIZE, color=color,
fontfamily='monospace', fontweight='bold', transform=ax3.transAxes)
y -= 0.07
y -= 0.05
plt.close('all')
return fig