Spaces:
Running
Running
| import matplotlib.pyplot as plt | |
| import pandas as pd | |
| def create_summary_page(df: pd.DataFrame, available_models: list[str]) -> plt.Figure: | |
| """Create a summary page with model names and both AMD/NVIDIA test stats bars.""" | |
| if df.empty: | |
| fig, ax = plt.subplots(figsize=(16, 8), facecolor='#000000') | |
| ax.set_facecolor('#000000') | |
| ax.text(0.5, 0.5, 'No data available', | |
| horizontalalignment='center', verticalalignment='center', | |
| transform=ax.transAxes, fontsize=20, color='#888888', | |
| fontfamily='monospace', weight='normal') | |
| ax.axis('off') | |
| return fig | |
| # Calculate dimensions for N-column layout | |
| model_count = len(available_models) | |
| columns = 3 | |
| rows = (model_count + columns - 1) // columns # Ceiling division | |
| # Figure dimensions - wider for 4 columns, height based on rows | |
| figure_width = 20 # Wider to accommodate 4 columns | |
| max_height = 12 # Maximum height in inches | |
| height_per_row = min(2.2, max_height / max(rows, 1)) | |
| figure_height = min(max_height, rows * height_per_row + 2) | |
| fig, ax = plt.subplots(figsize=(figure_width, figure_height), facecolor='#000000') | |
| ax.set_facecolor('#000000') | |
| colors = { | |
| 'passed': '#4CAF50', | |
| 'failed': '#E53E3E', | |
| 'skipped': '#FFD54F', | |
| 'error': '#8B0000', | |
| 'empty': "#5B5B5B" | |
| } | |
| visible_model_count = 0 | |
| max_y = 0 | |
| # Column layout parameters | |
| column_width = 100 / columns # Each column takes 25% of width | |
| bar_width = column_width * 0.8 # 80% of column width for bars | |
| bar_margin = column_width * 0.1 # 10% margin on each side | |
| for i, model_name in enumerate(available_models): | |
| if model_name not in df.index: | |
| continue | |
| row = df.loc[model_name] | |
| # Get values directly from dataframe | |
| success_amd = int(row.get('success_amd', 0)) if pd.notna(row.get('success_amd', 0)) else 0 | |
| success_nvidia = int(row.get('success_nvidia', 0)) if pd.notna(row.get('success_nvidia', 0)) else 0 | |
| failed_multi_amd = int(row.get('failed_multi_no_amd', 0)) if pd.notna(row.get('failed_multi_no_amd', 0)) else 0 | |
| failed_multi_nvidia = int(row.get('failed_multi_no_nvidia', 0)) if pd.notna(row.get('failed_multi_no_nvidia', 0)) else 0 | |
| failed_single_amd = int(row.get('failed_single_no_amd', 0)) if pd.notna(row.get('failed_single_no_amd', 0)) else 0 | |
| failed_single_nvidia = int(row.get('failed_single_no_nvidia', 0)) if pd.notna(row.get('failed_single_no_nvidia', 0)) else 0 | |
| # Calculate stats | |
| amd_stats = { | |
| 'passed': success_amd, | |
| 'failed': failed_multi_amd + failed_single_amd, | |
| 'skipped': 0, | |
| 'error': 0 | |
| } | |
| nvidia_stats = { | |
| 'passed': success_nvidia, | |
| 'failed': failed_multi_nvidia + failed_single_nvidia, | |
| 'skipped': 0, | |
| 'error': 0 | |
| } | |
| amd_total = sum(amd_stats.values()) | |
| nvidia_total = sum(nvidia_stats.values()) | |
| if amd_total == 0 and nvidia_total == 0: | |
| continue | |
| # Calculate position in 4-column grid | |
| col = visible_model_count % columns | |
| row = visible_model_count // columns | |
| # Calculate horizontal position for this column | |
| col_left = col * column_width + bar_margin | |
| col_center = col * column_width + column_width / 2 | |
| # Calculate vertical position for this row - start from top | |
| vertical_spacing = height_per_row | |
| y_base = (0.2 + row) * vertical_spacing # Start closer to top | |
| y_model_name = y_base # Model name above AMD bar | |
| y_amd_bar = y_base + vertical_spacing * 0.25 # AMD bar | |
| y_nvidia_bar = y_base + vertical_spacing * 0.54 # NVIDIA bar | |
| max_y = max(max_y, y_nvidia_bar + vertical_spacing * 0.3) | |
| # Model name centered above the bars in this column | |
| ax.text(col_center, y_model_name, model_name.lower(), | |
| ha='center', va='center', color='#FFFFFF', | |
| fontsize=16, fontfamily='monospace', fontweight='bold') | |
| # AMD label and bar in this column | |
| bar_height = min(0.4, vertical_spacing * 0.22) # Adjust bar height based on spacing | |
| label_x = col_left - 1 # Label position to the left of the bar | |
| ax.text(label_x, y_amd_bar, "amd", ha='right', va='center', color='#CCCCCC', fontsize=14, fontfamily='monospace', fontweight='normal') | |
| if amd_total > 0: | |
| # AMD bar starts at column left position | |
| left = col_left | |
| for category in ['passed', 'failed', 'skipped', 'error']: | |
| if amd_stats[category] > 0: | |
| width = amd_stats[category] / amd_total * bar_width | |
| ax.barh(y_amd_bar, width, left=left, height=bar_height, | |
| color=colors[category], alpha=0.9) | |
| # if width > 2: # Smaller threshold for text display | |
| # ax.text(left + width/2, y_amd_bar, str(amd_stats[category]), | |
| # ha='center', va='center', color='black', | |
| # fontweight='bold', fontsize=10, fontfamily='monospace') | |
| left += width | |
| else: | |
| ax.barh(y_amd_bar, bar_width, left=col_left, height=bar_height, color=colors['empty'], alpha=0.9) | |
| # ax.text(col_center, y_amd_bar, "No data", ha='center', va='center', color='black', fontweight='bold', fontsize=10, fontfamily='monospace') | |
| # NVIDIA label and bar in this column | |
| ax.text(label_x, y_nvidia_bar, "nvidia", ha='right', va='center', color='#CCCCCC', fontsize=14, fontfamily='monospace', fontweight='normal') | |
| if nvidia_total > 0: | |
| # NVIDIA bar starts at column left position | |
| left = col_left | |
| for category in ['passed', 'failed', 'skipped', 'error']: | |
| if nvidia_stats[category] > 0: | |
| width = nvidia_stats[category] / nvidia_total * bar_width | |
| ax.barh(y_nvidia_bar, width, left=left, height=bar_height, | |
| color=colors[category], alpha=0.9) | |
| # if width > 2: # Smaller threshold for text display | |
| # ax.text(left + width/2, y_nvidia_bar, str(nvidia_stats[category]), | |
| # ha='center', va='center', color='black', | |
| # fontweight='bold', fontsize=10, fontfamily='monospace') | |
| left += width | |
| else: | |
| ax.barh(y_nvidia_bar, bar_width, left=col_left, height=bar_height, color=colors['empty'], alpha=0.9) | |
| # ax.text(col_center, y_nvidia_bar, "No data", ha='center', va='center', color='black', fontweight='bold', fontsize=10, fontfamily='monospace') | |
| # Increment counter for next visible model | |
| visible_model_count += 1 | |
| # Style the axes to be completely invisible and span full width | |
| ax.set_xlim(-5, 105) # Slightly wider to accommodate labels | |
| ax.set_ylim(0, max_y) | |
| ax.set_xlabel('') | |
| ax.set_ylabel('') | |
| ax.spines['bottom'].set_visible(False) | |
| ax.spines['left'].set_visible(False) | |
| ax.spines['top'].set_visible(False) | |
| ax.spines['right'].set_visible(False) | |
| ax.set_xticks([]) | |
| ax.set_yticks([]) | |
| ax.yaxis.set_inverted(True) | |
| # Remove all margins to make figure stick to top | |
| plt.tight_layout() | |
| plt.subplots_adjust(left=0.02, right=0.98, top=1.0, bottom=0.02) | |
| return fig | |