Module neuralops.analysis.plotting
Comprehensive plotting functions for model analysis.
Functions
def create_comprehensive_plots(df: pandas.DataFrame, output_dir: str, figsize: tuple[int, int] = (18, 16)) ‑> None-
Expand source code
def create_comprehensive_plots( df: pd.DataFrame, output_dir: str, figsize: tuple[int, int] = (18, 16) ) -> None: """Build and return comprehensive plots.""" os.makedirs(output_dir, exist_ok=True) set_style() fig, axes = plt.subplots(3, 3, figsize=figsize) fig.suptitle( "SVD Compression Analysis: Comprehensive Results", fontsize=16, fontweight="bold", ) # 1. Accuracy vs Rank by model ax = axes[0, 0] for model in df["model"].unique(): sub = df[df["model"] == model].groupby("rank")["accuracy"].mean().reset_index() ax.plot(sub["rank"], sub["accuracy"], marker="o", label=model, linewidth=2) ax.set_title("Accuracy vs Rank (by Model)") ax.legend() ax.grid(True, alpha=0.3) # 2. Accuracy vs Rank by task ax = axes[0, 1] for task in df["task"].unique(): sub = df[df["task"] == task].groupby("rank")["accuracy"].mean().reset_index() ax.plot(sub["rank"], sub["accuracy"], marker="s", label=task, linewidth=2) ax.set_title("Accuracy vs Rank (by Task)") ax.legend() ax.grid(True, alpha=0.3) # 3. Speedup factor ax = axes[0, 2] if "speedup_factor" in df.columns: for model in df["model"].unique(): sub = df[df["model"] == model].groupby("rank")["speedup_factor"].mean() ax.plot(sub.index, sub.values, marker="^", label=model, linewidth=2) ax.set_title("Speedup vs Rank") ax.legend() ax.grid(True, alpha=0.3) else: ax.text( 0.5, 0.5, "No speedup data", ha="center", va="center", transform=ax.transAxes, ) # 4. Parameter reduction ax = axes[1, 0] if "param_reduction" in df.columns: pd_data = df.groupby(["model", "rank"])["param_reduction"].mean().reset_index() models = pd_data["model"].unique() width = 0.8 / len(models) for i, m in enumerate(models): sub = pd_data[pd_data["model"] == m] x = sub["rank"] + (i - len(models) / 2) * width ax.bar(x, sub["param_reduction"], width=width, label=m) ax.set_title("Parameter Reduction") ax.legend() ax.grid(True, axis="y", alpha=0.3) else: ax.text( 0.5, 0.5, "No param reduction", ha="center", va="center", transform=ax.transAxes, ) # 5. Accuracy drop distribution ax = axes[1, 1] if "accuracy_drop" in df.columns: drops = df["accuracy_drop"].dropna() ax.hist(drops, bins=20, color="lightcoral", edgecolor="darkred", alpha=0.7) ax.axvline(drops.mean(), color="blue", linestyle="-", label=f"Mean: {drops.mean():.3f}") ax.set_title("Accuracy Drop Distribution") ax.legend() ax.grid(True, axis="y", alpha=0.3) else: ax.text( 0.5, 0.5, "No accuracy drop", ha="center", va="center", transform=ax.transAxes, ) # 6. Memory reduction ax = axes[1, 2] if "memory_reduction" in df.columns: mem = df.groupby("rank")["memory_reduction"].mean().reset_index() ax.bar( mem["rank"], mem["memory_reduction"], color="lightgreen", edgecolor="darkgreen", ) ax.set_title("Avg Memory Reduction") ax.grid(True, axis="y", alpha=0.3) else: ax.text( 0.5, 0.5, "No memory reduction", ha="center", va="center", transform=ax.transAxes, ) # 7. Accuracy by task type ax = axes[2, 0] if "task_type" in df.columns: for tt in df["task_type"].unique(): sub = df[df["task_type"] == tt].groupby("rank")["accuracy"].mean().reset_index() ax.plot(sub["rank"], sub["accuracy"], marker="D", label=tt, linewidth=2) ax.set_title("Accuracy by Task Type") ax.legend() ax.grid(True, alpha=0.3) else: ax.text(0.5, 0.5, "No task type", ha="center", va="center", transform=ax.transAxes) # 8. Compression ratio heatmap ax = axes[2, 1] if "compression_ratio" in df.columns: pivot = df.pivot_table( index="model", columns="rank", values="compression_ratio", aggfunc="mean" ) im = ax.imshow(pivot.values, cmap="YlOrRd", aspect="auto") ax.set_xticks(range(len(pivot.columns))) ax.set_xticklabels(pivot.columns) ax.set_yticks(range(len(pivot.index))) ax.set_yticklabels(pivot.index) plt.colorbar(im, ax=ax, label="Compression Ratio") ax.set_title("Compression Ratio Heatmap") else: ax.text(0.5, 0.5, "No comp ratio", ha="center", va="center", transform=ax.transAxes) # 9. Best config per dataset ax = axes[2, 2] best = [] for task in df["task"].unique(): sub = df[df["task"] == task] if "accuracy" in sub.columns: idx = sub["accuracy"].idxmax() best.append(sub.loc[idx]) if best: best_df = pd.DataFrame(best) ax.barh(best_df["task"], best_df["accuracy"], color="skyblue", edgecolor="navy") ax.set_title("Best Configuration per Dataset") for i, (acc, model, rank) in enumerate( zip(best_df["accuracy"], best_df["model"], best_df["rank"]) ): ax.text(acc + 0.005, i, f"{model} r={int(rank)}", va="center", fontsize=8) else: ax.text(0.5, 0.5, "No best config", ha="center", va="center", transform=ax.transAxes) plt.tight_layout() plt.savefig(Path(output_dir) / "comprehensive_analysis.png", dpi=300, bbox_inches="tight") plt.close()Build and return comprehensive plots.
def plot_accuracy_curve(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_accuracy_curve(history, metrics, config, output_dir, opts) -> Any: """Plot accuracy curve.""" steps = [h.get("step", i) for i, h in enumerate(history) if "eval_accuracy" in h] acc = [h["eval_accuracy"] for h in history if "eval_accuracy" in h] if not steps: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 6])) ax.plot(steps, acc, "o-", color="#5DC963", markersize=4) ax.set_xlabel("Step") ax.set_ylabel("Accuracy") ax.set_title("Validation Accuracy") ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "accuracy_curve.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot accuracy curve.
def plot_accuracy_curves(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_accuracy_curve(history, metrics, config, output_dir, opts) -> Any: """Plot accuracy curve.""" steps = [h.get("step", i) for i, h in enumerate(history) if "eval_accuracy" in h] acc = [h["eval_accuracy"] for h in history if "eval_accuracy" in h] if not steps: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 6])) ax.plot(steps, acc, "o-", color="#5DC963", markersize=4) ax.set_xlabel("Step") ax.set_ylabel("Accuracy") ax.set_title("Validation Accuracy") ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "accuracy_curve.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot accuracy curve.
def plot_attention_heatmap(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_attention_heatmap(history, metrics, config, output_dir, opts) -> Any: """Plot attention heatmap.""" attn_path = Path(output_dir).parent / "artifacts" / "attention_sample.json" if not attn_path.exists(): return [] with open(attn_path) as f: attn_data = json.load(f) matrix = np.array(attn_data.get("matrix", [])) tokens = attn_data.get("tokens", None) layer = attn_data.get("layer", 0) head = attn_data.get("head", 0) # Simple heatmap fig, ax = plt.subplots(figsize=(10, 8)) sns.heatmap(matrix, cmap="viridis", xticklabels=tokens, yticklabels=tokens, ax=ax) ax.set_title(f"Attention Heatmap – Layer {layer} Head {head}") path = Path(output_dir) / "attention_heatmap.png" fig.savefig(path, dpi=150, bbox_inches="tight") plt.close() return [str(path)]Plot attention heatmap.
def plot_confusion_matrix(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_confusion_matrix(history, metrics, config, output_dir, opts) -> Any: """Plot confusion matrix.""" preds_path = Path(output_dir).parent / "artifacts" / "eval_predictions.json" if not preds_path.exists(): return [] with open(preds_path) as f: data = json.load(f) labels = data.get("labels", []) preds = data.get("predictions", []) if not labels: return [] from sklearn.metrics import confusion_matrix cm = confusion_matrix(labels, preds) class_names = opts.get("class_names", None) fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 8])) sns.heatmap( cm, annot=True, fmt="d", cmap="Blues", xticklabels=class_names, yticklabels=class_names, ax=ax, ) ax.set_xlabel("Predicted") ax.set_ylabel("True") ax.set_title("Confusion Matrix") path = Path(output_dir) / "confusion_matrix.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot confusion matrix.
def plot_gpu_memory(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_gpu_memory(history, metrics, config, output_dir, opts) -> Any: """Plot gpu memory.""" gpu_steps = [h.get("step", i) for i, h in enumerate(history) if "gpu_mem" in h] gpu = [h["gpu_mem"] for h in history if "gpu_mem" in h] cpu_steps = [h.get("step", i) for i, h in enumerate(history) if "cpu_mem" in h] cpu = [h["cpu_mem"] for h in history if "cpu_mem" in h] if not gpu_steps and not cpu_steps: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 4])) if gpu_steps: ax.plot(gpu_steps, gpu, label="GPU Mem (MB)", color="#3B528B") if cpu_steps: ax.plot(cpu_steps, cpu, label="CPU Mem (MB)", color="#5DC963") ax.set_xlabel("Step") ax.set_ylabel("Memory (MB)") ax.set_title("Memory Usage") ax.legend() ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "gpu_memory.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot gpu memory.
def plot_gradient_flow(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_training_time(history, metrics, config, output_dir, opts) -> Any: """Plot training time.""" times = [ h.get("elapsed", i * 0.01) for i, h in enumerate(history) if "elapsed" in h or "step" in h ] if not times: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 4])) ax.plot(range(len(times)), times, color="#440154") ax.set_xlabel("Step") ax.set_ylabel("Time (s)") ax.set_title("Training Time vs Steps") ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "training_time.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot training time.
def plot_loss_curve(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_loss_curve(history, metrics, config, output_dir, opts) -> Any: """Plot loss curve.""" steps = [h.get("step", i) for i, h in enumerate(history) if "loss" in h] train = [h["loss"] for h in history if "loss" in h] eval_steps = [h.get("step", i) for i, h in enumerate(history) if "eval_loss" in h] eval_l = [h["eval_loss"] for h in history if "eval_loss" in h] smooth = opts.get("loss_smooth", 0.6) if smooth > 0 and len(train) > 5: window = max(1, int(len(train) * smooth / 10)) train = uniform_filter1d(np.array(train), size=window) fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 6])) ax.plot(steps, train, label="Train Loss", color="#3B528B") if eval_steps: ax.plot(eval_steps, eval_l, "o-", label="Eval Loss", color="#21908C", markersize=4) ax.set_xlabel("Step") ax.set_ylabel("Loss") ax.set_title("Training & Validation Loss") ax.legend() ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "loss_curve.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot loss curve.
def plot_loss_curves(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_loss_curve(history, metrics, config, output_dir, opts) -> Any: """Plot loss curve.""" steps = [h.get("step", i) for i, h in enumerate(history) if "loss" in h] train = [h["loss"] for h in history if "loss" in h] eval_steps = [h.get("step", i) for i, h in enumerate(history) if "eval_loss" in h] eval_l = [h["eval_loss"] for h in history if "eval_loss" in h] smooth = opts.get("loss_smooth", 0.6) if smooth > 0 and len(train) > 5: window = max(1, int(len(train) * smooth / 10)) train = uniform_filter1d(np.array(train), size=window) fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 6])) ax.plot(steps, train, label="Train Loss", color="#3B528B") if eval_steps: ax.plot(eval_steps, eval_l, "o-", label="Eval Loss", color="#21908C", markersize=4) ax.set_xlabel("Step") ax.set_ylabel("Loss") ax.set_title("Training & Validation Loss") ax.legend() ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "loss_curve.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot loss curve.
def plot_lr_schedule(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_lr_schedule(history, metrics, config, output_dir, opts) -> Any: """Plot lr schedule.""" steps = [h.get("step", i) for i, h in enumerate(history) if "learning_rate" in h] lr = [h["learning_rate"] for h in history if "learning_rate" in h] if not steps: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 4])) ax.plot(steps, lr, color="#FDE725") ax.set_xlabel("Step") ax.set_ylabel("LR") ax.set_title("Learning Rate Schedule") ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "lr_schedule.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot lr schedule.
def plot_parameter_distribution(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_parameter_distribution(history, metrics, config, output_dir, opts) -> Any: """Plot parameter distribution.""" param_path = Path(output_dir).parent / "artifacts" / "param_counts.json" if not param_path.exists(): return [] with open(param_path) as f: param_data = json.load(f) layers = list(param_data.keys()) counts = list(param_data.values()) fig, ax = plt.subplots(figsize=opts.get("figsize", [8, 6])) ax.barh(layers, counts, color="#21908C") ax.set_xlabel("Parameter Count") ax.set_title("Parameter Distribution per Layer") plt.tight_layout() path = Path(output_dir) / "parameter_count.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot parameter distribution.
def plot_pareto_front(df, output_dir, x_metric='speedup_factor', y_metric='accuracy') ‑> None-
Expand source code
def plot_pareto_front(df, output_dir, x_metric="speedup_factor", y_metric="accuracy") -> None: """Plot pareto front.""" set_style() points = df[[x_metric, y_metric, "model", "rank"]].dropna().values pareto = [] for i, p in enumerate(points): dominated = False for q in points: if q[0] >= p[0] and q[1] >= p[1] and (q[0] > p[0] or q[1] > p[1]): dominated = True break if not dominated: pareto.append(p) pareto_df = pd.DataFrame(pareto, columns=[x_metric, y_metric, "model", "rank"]) fig, ax = plt.subplots(figsize=(10, 8)) for model in df["model"].unique(): sub = df[df["model"] == model] ax.scatter(sub[x_metric], sub[y_metric], label=model, alpha=0.5) ax.scatter( pareto_df[x_metric], pareto_df[y_metric], color="red", s=150, marker="*", label="Pareto front", ) ax.set_xlabel(x_metric.replace("_", " ").capitalize()) ax.set_ylabel(y_metric.capitalize()) ax.set_title("Pareto Frontier of Configurations") ax.legend() ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(Path(output_dir) / "pareto_front.png", dpi=150) plt.close()Plot pareto front.
def plot_radar_chart(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_radar_chart(history, metrics, config, output_dir, opts) -> Any: """Plot radar chart.""" if not metrics: return [] numeric = {k: v for k, v in metrics.items() if isinstance(v, (int, float))} if len(numeric) < 3: return [] categories = list(numeric.keys()) values = list(numeric.values()) angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist() values = values + values[:1] angles += angles[:1] fig, ax = plt.subplots(figsize=opts.get("figsize", [8, 8]), subplot_kw=dict(polar=True)) ax.fill(angles, values, alpha=0.25, color="#3B528B") ax.plot(angles, values, color="#3B528B", linewidth=2) ax.set_xticks(angles[:-1]) ax.set_xticklabels(categories) ax.set_title("Performance Radar Chart") plt.tight_layout() path = Path(output_dir) / "radar_chart.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot radar chart.
def plot_rank_allocation(recommended_ranks, output_dir) ‑> None-
Expand source code
def plot_rank_allocation(recommended_ranks, output_dir) -> None: """Plot rank allocation.""" set_style() fig, ax = plt.subplots(figsize=(12, 6)) layers = list(range(len(recommended_ranks))) ax.bar(layers, recommended_ranks, color="steelblue", edgecolor="navy") ax.set_xlabel("Layer Index") ax.set_ylabel("Recommended Rank") ax.set_title("Layer‑wise Rank Allocation Recommendation") ax.grid(True, axis="y", alpha=0.3) plt.tight_layout() plt.savefig(Path(output_dir) / "rank_allocation.png", dpi=150) plt.close()Plot rank allocation.
def plot_tradeoff(df, output_dir, metric='accuracy') ‑> None-
Expand source code
def plot_tradeoff(df, output_dir, metric="accuracy") -> None: """Plot tradeoff.""" set_style() fig, ax = plt.subplots(figsize=(10, 8)) for model in df["model"].unique(): sub = df[df["model"] == model].dropna(subset=["speedup_factor", metric]) ax.scatter(sub["speedup_factor"], sub[metric], s=100, label=model, alpha=0.7) ax.set_xlabel("Speedup Factor") ax.set_ylabel(metric.capitalize()) ax.set_title("Accuracy vs Speedup Tradeoff") ax.legend() ax.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(Path(output_dir) / "tradeoff.png", dpi=150, bbox_inches="tight") plt.close()Plot tradeoff.
def plot_training_history(history: dict, save_path: str) ‑> None-
Expand source code
def plot_training_history(history: dict, save_path: str) -> None: """Plot training history.""" fig, ax = plt.subplots(figsize=(8, 5)) if history.get("train_steps") and history.get("train_loss"): ax.plot( history["train_steps"], history["train_loss"], label="Train Loss", color="blue", ) if history.get("eval_steps") and history.get("eval_loss"): ax.plot( history["eval_steps"], history["eval_loss"], label="Eval Loss", color="red", marker="o", ) ax.set_xlabel("Steps") ax.set_ylabel("Loss") ax.set_title("Training History") ax.legend() ax.grid(True, alpha=0.3) plt.savefig(save_path, dpi=150, bbox_inches="tight") plt.close()Plot training history.
def plot_training_time(history, metrics, config, output_dir, opts) ‑> Any-
Expand source code
def plot_training_time(history, metrics, config, output_dir, opts) -> Any: """Plot training time.""" times = [ h.get("elapsed", i * 0.01) for i, h in enumerate(history) if "elapsed" in h or "step" in h ] if not times: return [] fig, ax = plt.subplots(figsize=opts.get("figsize", [10, 4])) ax.plot(range(len(times)), times, color="#440154") ax.set_xlabel("Step") ax.set_ylabel("Time (s)") ax.set_title("Training Time vs Steps") ax.grid(True, alpha=0.3) plt.tight_layout() path = Path(output_dir) / "training_time.png" fig.savefig(path, dpi=opts.get("dpi", 150), bbox_inches="tight") plt.close() return [str(path)]Plot training time.
def set_style() ‑> None-
Expand source code
def set_style() -> None: """Set the style.""" plt.style.use("seaborn-v0_8-darkgrid") sns.set_palette("husl") sns.set_context("paper", font_scale=1.2)Set the style.