FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[Bug]: magnitude_spectrum returns negative magnitudes for negative-sum windows · Issue #32054 · matplotlib/matplotlib · GitHub

Repository navigation

[Bug]: magnitude_spectrum returns negative magnitudes for negative-sum windows #32054

Closed as not planned

Description

Bug summary

mlab.magnitude_spectrum returns negative magnitudes when given a window whose sum is negative. Magnitude-spectrum values should be nonnegative.

Code for reproduction

# Example 13: Magnitude spectrum with a negative-sum window
import numpy as np
from matplotlib import mlab

x = np.sin(2 * np.pi * np.arange(8) / 4)
window = -np.ones(8)
print("Input:", x)
print("Window:", window)
print("Window sum:", window.sum())
magnitude, frequencies = mlab.magnitude_spectrum(
    x, Fs=8, window=window
)
print("Frequencies:", np.round(frequencies, 3))
print("Magnitude:", np.round(magnitude, 6))

Actual outcome

Input: [ 0.0000000e+00  1.0000000e+00  1.2246468e-16 -1.0000000e+00
 -2.4492936e-16  1.0000000e+00  3.6739404e-16 -1.0000000e+00]
Window: [-1. -1. -1. -1. -1. -1. -1. -1.]
Window sum: -8.0
Frequencies: [0. 1. 2. 3. 4.]
Magnitude: [-0.  -0.  -0.5 -0.  -0. ]

Expected outcome

The magnitude spectrum should contain nonnegative values. For this input, the expected output is:

Input: [ 0.0000000e+00  1.0000000e+00  1.2246468e-16 -1.0000000e+00
 -2.4492936e-16  1.0000000e+00  3.6739404e-16 -1.0000000e+00]
Window: [-1. -1. -1. -1. -1. -1. -1. -1.]
Window sum: -8.0
Frequencies: [0. 1. 2. 3. 4.]
Magnitude: [0.  0.  0.5 0.  0. ]

Additional information

This is a regression introduced by PR #25122. The change replaces absolute window sums with signed sums. For the all-negative window above, the magnitude spectrum is divided by -8, changing the magnitude at frequency 2 from 0.5 to -0.5.

The example uses the public mlab.magnitude_spectrum API with a numeric window array, which is a legal input. Although removing abs() was the stated implementation strategy for correcting signed-window scaling, the resulting negative magnitude is an unintended behavioral regression.

Operating system

Linux

Matplotlib Version

3.11.0

Matplotlib Backend

agg

Python version

3.11.13

Jupyter version

N/A

Installation

N/A

Activity

  1. jklymak commented on Jul 17, 2026

    Member

    I'd consider that a malformed window so garbage in garbage out. What are you trying to achieve that you would provide a negative sum window but don't want the resulting spectrum to also be negative?

  2. rcomer commented on Jul 17, 2026

    Member

    Apparently OP is a bot, so there isn’t a genuine use case behind the report.
    https://arxiv.org/pdf/2603.03121

    Suggest closing if the example doesn’t make sense. I can’t make that call myself as I don’t know anything about magnitude_spectrum.

  3. added
    ai-contributionPRs that are AI generated without a human in the loop
    on Jul 17, 2026
  4. added
    ai-contributionPRs that are AI generated without a human in the loop
    and removed
    ai-contributionPRs that are AI generated without a human in the loop
    on Jul 17, 2026
  5. jklymak commented on Jul 17, 2026

    Member

    We can always reopen. One could argue that a magnitude spectrum should always produce non negative values, but given that negative values indicate a broken window, I think it's ok to leave this be

    All this aside from the fact that we should remove mlab

  6. RippleTester commented on Jul 20, 2026

    Author

    Thanks for the responses.

    Regarding the bot concern: the paper linked (arXiv:2603.03121) describes a GUI testing tool for desktop applications, which is a different project. This regression was identified through manual analysis of the behavioral change introduced by PR #25122.

    To clarify the behavioral change:

    My understanding is that this is not simply a change in behavior. magnitude_spectrum computes |FFT(x)|, whose output should be nonnegative by definition, regardless of the window used. While PR #25122 addressed #24821, it appears that removing np.abs() also introduced this side effect.

  7. RippleTester commented on Jul 20, 2026

    Author

    As a follow-up, I looked at the actual diff in PR #25122. For mode == "magnitude", the relevant change was:

    # Before
    result = np.abs(result) / np.abs(window).sum()
    
    # After
    result = np.abs(result) / window.sum()

    The numerator, np.abs(result), is always nonnegative. From the PR discussion, it seems the motivation was to correct the normalization for psd mode (particularly for flattop windows, whose sums are positive). This edge case for magnitude mode with a fully negative window does not appear to have been considered during the review.

    Since magnitude_spectrum computes |FFT(x)|, the output is expected to be nonnegative regardless of the window values. With the current implementation, a negative-sum window produces negative magnitudes solely because of the normalization denominator.

    One possible way to preserve the intent of #24821 while keeping the magnitude output nonnegative would be:

    result = np.abs(result) / abs(window.sum())
  8. jklymak commented on Jul 20, 2026

    Member

    What does scipy.signal do with a window that sums to a negative value?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL