-
sdr.plot.dft(x: ArrayLike, sample_rate: float | None =
None
, window: str | float | tuple | None =None
, size: int | None =None
, oversample: int | None =None
, fast: bool =False
, centered: bool =True
, ax: Axes | None =None
, type: 'plot' | 'stem' ='plot'
, x_axis: 'freq' | 'bin' ='freq'
, y_axis: 'complex' | 'mag' | 'mag^2' | 'db' ='mag'
, diff: 'color' | 'line' ='color'
, **kwargs) Plots the discrete Fourier transform (DFT) of the time-domain signal \(x[n]\).
- Parameters:¶
- x: ArrayLike¶
The time-domain signal \(x[n]\).
- sample_rate: float | None =
None
¶ The sample rate \(f_s\) of the signal in samples/s. If
None
, the x-axis will be labeled as “Normalized frequency”.- window: str | float | tuple | None =
None
¶ The SciPy window definition. See
scipy.signal.windows.get_window()
for details. IfNone
, no window is applied.- size: int | None =
None
¶ The number of points to use for the DFT. If
None
, the length of the signal is used.- oversample: int | None =
None
¶ The factor to oversample the DFT. If
None
, the DFT is not oversampled. This is only considered ifsize
isNone
.- fast: bool =
False
¶ Indicates whether to use the fast Fourier transform (FFT) algorithm. If
True
, the DFT size is set to the next power of 2.- centered: bool =
True
¶ Indicates whether to center the DFT about 0.
- ax: Axes | None =
None
¶ The axis to plot on. If
None
, the current axis is used.- type: 'plot' | 'stem' =
'plot'
¶ The type of plot to use.
- x_axis: 'freq' | 'bin' =
'freq'
¶ The x-axis scaling.
- y_axis: 'complex' | 'mag' | 'mag^2' | 'db' =
'mag'
¶ The y-axis scaling.
- diff: 'color' | 'line' =
'color'
¶ Indicates how to differentiate the real and imaginary parts of a complex signal. If
"color"
, the real and imaginary parts will have different colors based on the current Matplotlib color cycle. If"line"
, the real part will have a solid line and the imaginary part will have a dashed line, and both lines will share the same color.- **kwargs¶
Additional keyword arguments to pass to the plotting function.
See also
Notes
The discrete Fourier transform (DFT) is defined as
\[X[k] = \sum_{n=0}^{N-1} x[n] e^{-j 2 \pi k n / N},\]where \(x[n]\) is the time-domain signal, \(X[k]\) is the DFT, \(k\) is the DFT frequency bin, and \(N\) is the number of samples in the DFT. The frequency corresponding to the k-th bin is \(\frac{k}{N} f_s\).
The DFT is a sampled version of the discrete-time Fourier transform (DTFT).
Examples
Create a tone whose frequency will straddle two DFT bins.
In [1]: n = 10 # samples In [2]: f = 1.5 / n # cycles/sample In [3]: x = np.exp(1j * 2 * np.pi * f * np.arange(n)) In [4]: plt.figure(); \ ...: sdr.plot.dft(x, x_axis="bin", type="stem"); ...:
Plot the DFT against normalized frequency. Compare the DTFT, an oversampled DFT, and a critically sampled DFT. Notice that the critically sampled DFT has scalloping loss (difference between the true peak and the DFT peak) when the signal frequency does not align with a bin. Furthermore, the sidelobes are non-zero and large. This is known as spectral leakage – the spreading of a tone’s power from a single bins to all bins.
In [5]: plt.figure(); \ ...: sdr.plot.dtft(x, color="k", label="DTFT"); \ ...: sdr.plot.dft(x, oversample=4, type="stem", label="4x oversampled DFT"); \ ...: sdr.plot.dft(x, type="stem", label="DFT"); ...:
If a window is applied to the signal before the DFT is computed, the main lobe is widened and the sidelobes are reduced. Given the wider main lobe, the scalloping loss of the critically sampled DFT is also reduced. These benefits come at the cost of reduced frequency resolution.
In [6]: plt.figure(); \ ...: sdr.plot.dtft(x, window="hamming", color="k", label="DTFT"); \ ...: sdr.plot.dft(x, oversample=4, window="hamming", type="stem", label="4x oversampled DFT"); \ ...: sdr.plot.dft(x, window="hamming", type="stem", label="DFT"); ...: