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