Source code for roastcoffea.visualization.plots.scaling

"""Scaling efficiency plots.

Visualizations for parallel efficiency and scaling analysis.
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

import matplotlib.pyplot as plt


[docs] def plot_efficiency_summary( metrics: dict[str, Any] | None, output_path: Path | None = None, figsize: tuple[int, int] = (10, 6), ) -> tuple[plt.Figure, plt.Axes]: """Plot efficiency metrics summary as bar chart. Shows core efficiency, speedup factor, and other efficiency metrics in a compact bar chart format. Parameters ---------- metrics : dict Metrics dictionary with efficiency metrics output_path : Path, optional Save path figsize : tuple Figure size Returns ------- fig, ax : Figure and Axes Matplotlib figure and axes Raises ------ ValueError If metrics is None or missing required data """ if metrics is None: msg = "metrics cannot be None" raise ValueError(msg) # Extract efficiency metrics core_efficiency = metrics.get("core_efficiency") speedup_factor = metrics.get("speedup_factor") if core_efficiency is None and speedup_factor is None: msg = "No efficiency metrics available (core_efficiency or speedup_factor)" raise ValueError(msg) # Prepare data for plotting metric_names = [] metric_values = [] if core_efficiency is not None: metric_names.append("Core Efficiency") metric_values.append(core_efficiency * 100) # Convert to percentage if speedup_factor is not None: metric_names.append("Speedup Factor") metric_values.append(speedup_factor) # Create plot fig, ax = plt.subplots(figsize=figsize) bars = ax.bar( metric_names, metric_values, color=["steelblue", "coral"][: len(metric_names)] ) # Add value labels on top of bars for bar in bars: height = bar.get_height() ax.text( bar.get_x() + bar.get_width() / 2.0, height, f"{height:.1f}", ha="center", va="bottom", fontsize=12, fontweight="bold", ) ax.set_ylabel("Value") ax.set_title("Efficiency Metrics Summary") ax.grid(True, alpha=0.3, axis="y") plt.tight_layout() if output_path: fig.savefig(output_path, dpi=150, bbox_inches="tight") return fig, ax
[docs] def plot_resource_utilization( metrics: dict[str, Any] | None, output_path: Path | None = None, figsize: tuple[int, int] = (10, 6), ) -> tuple[plt.Figure, plt.Axes]: """Plot resource utilization summary. Shows worker count, cores, and memory statistics in a grouped bar chart. Parameters ---------- metrics : dict Metrics dictionary with worker and resource metrics output_path : Path, optional Save path figsize : tuple Figure size Returns ------- fig, ax : Figure and Axes Matplotlib figure and axes Raises ------ ValueError If metrics is None or missing required data """ if metrics is None: msg = "metrics cannot be None" raise ValueError(msg) # Extract resource metrics avg_workers = metrics.get("avg_workers") total_cores = metrics.get("total_cores") peak_memory_bytes = metrics.get("peak_memory_bytes") peak_memory_gb = peak_memory_bytes / 1e9 if peak_memory_bytes else None if avg_workers is None and total_cores is None and peak_memory_gb is None: msg = "No resource metrics available (workers, cores, or memory)" raise ValueError(msg) # Prepare data for plotting resource_names = [] resource_values = [] if avg_workers is not None: resource_names.append("Avg Workers") resource_values.append(avg_workers) if total_cores is not None: resource_names.append("Total Cores") resource_values.append(total_cores) if peak_memory_gb is not None: resource_names.append("Peak Memory (GB)") resource_values.append(peak_memory_gb) # Create plot fig, ax = plt.subplots(figsize=figsize) colors = ["steelblue", "coral", "lightgreen"][: len(resource_names)] bars = ax.bar(resource_names, resource_values, color=colors) # Add value labels on top of bars for bar in bars: height = bar.get_height() ax.text( bar.get_x() + bar.get_width() / 2.0, height, f"{height:.1f}", ha="center", va="bottom", fontsize=12, fontweight="bold", ) ax.set_ylabel("Value") ax.set_title("Resource Utilization Summary") ax.grid(True, alpha=0.3, axis="y") plt.tight_layout() if output_path: fig.savefig(output_path, dpi=150, bbox_inches="tight") return fig, ax