From 48cedab7ac4e44f10dd1f5e84cf2f92309fcb0ea Mon Sep 17 00:00:00 2001 From: Chaoming Wang Date: Wed, 10 Jun 2026 00:58:41 +0800 Subject: [PATCH] fix(visualize): use np.trapezoid for AUC/AP, restoring NumPy >=2.4 (#99) np.trapz was renamed to np.trapezoid in NumPy 2.0 and removed in NumPy 2.4, so roc_curve and precision_recall_curve raised AttributeError on NumPy 2.4+ (which CI installs). Resolve np.trapezoid when available and fall back to np.trapz for the declared numpy>=1.15 floor. This broke main CI after #98 merged; it was invisible locally because local NumPy was < 2.4. Closes #99 --- braintools/visualize/_statistical.py | 9 +++++++-- changelog.md | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/braintools/visualize/_statistical.py b/braintools/visualize/_statistical.py index 820bbfa..1077f2b 100644 --- a/braintools/visualize/_statistical.py +++ b/braintools/visualize/_statistical.py @@ -23,6 +23,11 @@ from braintools._misc import set_module_as from braintools.tree import as_numpy +# ``np.trapz`` was renamed to ``np.trapezoid`` in NumPy 2.0 and removed +# outright in NumPy 2.4, so resolve whichever name the installed NumPy +# provides (falling back to ``np.trapz`` for NumPy < 2.0). +_trapezoid = getattr(np, 'trapezoid', None) or np.trapz + __all__ = [ 'correlation_matrix', 'distribution_plot', @@ -922,7 +927,7 @@ def roc_curve( fpr = np.array(fpr) # Calculate AUC - auc = np.trapz(tpr, fpr) + auc = _trapezoid(tpr, fpr) # Plot ROC curve ax.plot(fpr, tpr, color=color, linewidth=2, label=f'AUC = {auc:.3f}', **kwargs) @@ -1003,7 +1008,7 @@ def precision_recall_curve( recall = np.array(recall) # Calculate average precision - ap = np.trapz(precision, recall) + ap = _trapezoid(precision, recall) # Plot PR curve ax.plot(recall, precision, color=color, linewidth=2, diff --git a/changelog.md b/changelog.md index 3892a57..8db8316 100644 --- a/changelog.md +++ b/changelog.md @@ -114,6 +114,9 @@ assets are migrated to the new `brainx.chaobrain.com` host. - `remove_axis` uses `ax.spines` instead of the non-existent `ax.spine` (#96). - `create_neural_colormap` / `brain_colormaps` register with `force=True`, making them idempotent rather than raising on re-use (#97). + - `roc_curve` / `precision_recall_curve` resolve `np.trapezoid` when + available (falling back to `np.trapz`), fixing an `AttributeError` on + NumPy >= 2.4 where `np.trapz` was removed (#99). ### Infrastructure