|
| 1 | +Correct scaling of :func:`magnitude_spectrum()` |
| 2 | +``````````````````````````````````````````````` |
| 3 | + |
| 4 | +The functions :func:`matplotlib.mlab.magnitude_spectrum()` and :func:`matplotlib.pyplot.magnitude_spectrum()` implicitly assumed the sum |
| 5 | +of windowing function values to be one. In Matplotlib and Numpy the |
| 6 | +standard windowing functions are scaled to have maximum value of one, |
| 7 | +which usually results in a sum of the order of n/2 for a n-point |
| 8 | +signal. Thus the amplitude scaling :func:`magnitude_spectrum()` was |
| 9 | +off by that amount when using standard windowing functions (`Bug 8417 |
| 10 | +<https://github.com/matplotlib/matplotlib/issues/8417>`_ ). Now the |
| 11 | +behavior is consistent with :func:`matplotlib.pyplot.psd()` and |
| 12 | +:func:`scipy.signal.welch()`. The following example demonstrates the |
| 13 | +new and old scaling:: |
| 14 | + |
| 15 | + import matplotlib.pyplot as plt |
| 16 | + import numpy as np |
| 17 | + |
| 18 | + tau, n = 10, 1024 # 10 second signal with 1024 points |
| 19 | + T = tau/n # sampling interval |
| 20 | + t = np.arange(n)*T |
| 21 | + |
| 22 | + a = 4 # amplitude |
| 23 | + x = a*np.sin(40*np.pi*t) # 20 Hz sine with amplitude a |
| 24 | + |
| 25 | + # New correct behavior: Amplitude at 20 Hz is a/2 |
| 26 | + plt.magnitude_spectrum(x, Fs=1/T, sides='onesided', scale='linear') |
| 27 | + |
| 28 | + # Original behavior: Amplitude at 20 Hz is (a/2)*(n/2) for a Hanning window |
| 29 | + w = np.hanning(n) # default window is a Hanning window |
| 30 | + plt.magnitude_spectrum(x*np.sum(w), Fs=1/T, sides='onesided', scale='linear') |
| 31 | + |
0 commit comments