diff --git a/doc/api/api_changes/2017-06-11-DB_magnitude_spectrum.rst b/doc/api/api_changes/2017-06-11-DB_magnitude_spectrum.rst new file mode 100644 index 000000000000..67efbb580a99 --- /dev/null +++ b/doc/api/api_changes/2017-06-11-DB_magnitude_spectrum.rst @@ -0,0 +1,31 @@ +Correct scaling of :func:`magnitude_spectrum()` +``````````````````````````````````````````````` + +The functions :func:`matplotlib.mlab.magnitude_spectrum()` and :func:`matplotlib.pyplot.magnitude_spectrum()` implicitly assumed the sum +of windowing function values to be one. In Matplotlib and Numpy the +standard windowing functions are scaled to have maximum value of one, +which usually results in a sum of the order of n/2 for a n-point +signal. Thus the amplitude scaling :func:`magnitude_spectrum()` was +off by that amount when using standard windowing functions (`Bug 8417 +`_ ). Now the +behavior is consistent with :func:`matplotlib.pyplot.psd()` and +:func:`scipy.signal.welch()`. The following example demonstrates the +new and old scaling:: + + import matplotlib.pyplot as plt + import numpy as np + + tau, n = 10, 1024 # 10 second signal with 1024 points + T = tau/n # sampling interval + t = np.arange(n)*T + + a = 4 # amplitude + x = a*np.sin(40*np.pi*t) # 20 Hz sine with amplitude a + + # New correct behavior: Amplitude at 20 Hz is a/2 + plt.magnitude_spectrum(x, Fs=1/T, sides='onesided', scale='linear') + + # Original behavior: Amplitude at 20 Hz is (a/2)*(n/2) for a Hanning window + w = np.hanning(n) # default window is a Hanning window + plt.magnitude_spectrum(x*np.sum(w), Fs=1/T, sides='onesided', scale='linear') + diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 6a46414aafc5..93841e8f1a4e 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6665,8 +6665,7 @@ def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None, scale : [ 'default' | 'linear' | 'dB' ] The scaling of the values in the *spec*. 'linear' is no scaling. - 'dB' returns the values in dB scale. When *mode* is 'density', - this is dB power (10 * log10). Otherwise this is dB amplitude + 'dB' returns the values in dB scale, i.e., the dB amplitude (20 * log10). 'default' is 'linear'. Fc : integer diff --git a/lib/matplotlib/mlab.py b/lib/matplotlib/mlab.py index dfa22e01888b..e362bfcc6ae9 100644 --- a/lib/matplotlib/mlab.py +++ b/lib/matplotlib/mlab.py @@ -727,12 +727,12 @@ def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None, elif mode == 'psd': result = np.conj(result) * result elif mode == 'magnitude': - result = np.abs(result) + result = np.abs(result) / np.abs(windowVals).sum() elif mode == 'angle' or mode == 'phase': # we unwrap the phase later to handle the onesided vs. twosided case result = np.angle(result) elif mode == 'complex': - pass + result /= np.abs(windowVals).sum() if mode == 'psd': diff --git a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_dB.png b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_dB.png index ebc50c676692..15d32d399208 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_dB.png and b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_dB.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_linear.png b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_linear.png index 14f832a7355b..9dec3eef4339 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_linear.png and b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_freqs_linear.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_dB.png b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_dB.png index a18d0b40f43b..a8ceb982774b 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_dB.png and b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_dB.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_linear.png b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_linear.png index c2deb9e2414d..95a64798607b 100644 Binary files a/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_linear.png and b/lib/matplotlib/tests/baseline_images/test_axes/magnitude_spectrum_noise_linear.png differ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy