STFT

The Short-Time Fourier Transform (STFT) is used to quantify the change of a nonstationary signal’s frequency and phase content over time.

It is computed by dividing a longer time signal into shorter segments of equal length and then computing the Fourier transform separately on each shorter segment.

Excel Usage

=STFT(x, fs, window, nperseg, noverlap, nfft, spectral_detrend, return_onesided, boundary, padded)
  • x (list[list], required): Time series of measurement values.
  • fs (float, optional, default: 1): Sampling frequency.
  • window (str, optional, default: “hann”): Desired window to use.
  • nperseg (int, optional, default: 256): Length of each segment.
  • noverlap (int, optional, default: null): Number of points to overlap between segments.
  • nfft (int, optional, default: null): Length of the FFT used.
  • spectral_detrend (str, optional, default: “False”): Specifies how to detrend each segment.
  • return_onesided (bool, optional, default: true): If True, return a one-sided spectrum.
  • boundary (str, optional, default: “zeros”): Specifies whether the input signal is extended at both ends.
  • padded (bool, optional, default: true): If True, zero-pad signal to fit segments.

Returns (list[list]): A 2D array representing the STFT grid (interleaved real and imaginary).

Example 1: Basic STFT

Inputs:

x
1 2 3 4 5 4 3 2 1

Excel formula:

=STFT({1,2,3,4,5,4,3,2,1})

Expected output:

Result
0 5 10
0.0 (Re) 1.64381 3.21239 0.143807
0.0 (Im) 0 0 0
0.1111111111111111 (Re) -0.694229 -1.86154 0.0557706
0.1111111111111111 (Im) 0.95196 -0.828119 -0.123841
0.2222222222222222 (Re) -0.0772516 0.154503 -0.0772516
0.2222222222222222 (Im) -0.317934 0.400537 -0.0826035
0.3333333333333333 (Re) -0.0719035 0.143807 -0.0719035
0.3333333333333333 (Im) -0.018854 -0.0156369 0.034491
0.4444444444444444 (Re) 0.0214811 -0.0429621 0.0214811
0.4444444444444444 (Im) 0.0291447 -0.0703818 0.0412371
Example 2: STFT with constant detrending

Inputs:

x spectral_detrend nperseg
0 1 0 -1 0 1 0 -1 constant 4

Excel formula:

=STFT({0,1,0,-1,0,1,0,-1}, "constant", 4)

Expected output:

Result
0 2 4 6 8
0.0 (Re) 0 0 0 0 0
0.0 (Im) 0 0 0 0 0
0.25 (Re) 0.125 0 0 0 -0.125
0.25 (Im) 0.25 -0.5 0.5 -0.5 0.25
0.5 (Re) -0.25 0 0 0 0.25
0.5 (Im) 0 0 0 0 0
Example 3: STFT without boundary extension and padding

Inputs:

x boundary padded nperseg noverlap
1 2 1 2 1 2 1 2 None false 4 2

Excel formula:

=STFT({1,2,1,2,1,2,1,2}, "None", FALSE, 4, 2)

Expected output:

Result
2 4 6
0.0 (Re) 1.5 1.5 1.5
0.0 (Im) 0 0 0
0.25 (Re) -0.5 -0.5 -0.5
0.25 (Im) 0 0 0
0.5 (Re) -0.5 -0.5 -0.5
0.5 (Im) 0 0 0
Example 4: STFT with scalar-compatible input

Inputs:

x
3

Excel formula:

=STFT(3)

Expected output:

Result
0
0.0 (Re) 3
0.0 (Im) 0

Python Code

Show Code
import numpy as np
from scipy.signal import stft as scipy_stft

def stft(x, fs=1, window='hann', nperseg=256, noverlap=None, nfft=None, spectral_detrend='False', return_onesided=True, boundary='zeros', padded=True):
    """
    Compute the Short Time Fourier Transform (STFT).

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.stft.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        x (list[list]): Time series of measurement values.
        fs (float, optional): Sampling frequency. Default is 1.
        window (str, optional): Desired window to use. Default is 'hann'.
        nperseg (int, optional): Length of each segment. Default is 256.
        noverlap (int, optional): Number of points to overlap between segments. Default is None.
        nfft (int, optional): Length of the FFT used. Default is None.
        spectral_detrend (str, optional): Specifies how to detrend each segment. Valid options: Constant, Linear, None. Default is 'False'.
        return_onesided (bool, optional): If True, return a one-sided spectrum. Default is True.
        boundary (str, optional): Specifies whether the input signal is extended at both ends. Valid options: Zeros, Even, Odd, Constant, None. Default is 'zeros'.
        padded (bool, optional): If True, zero-pad signal to fit segments. Default is True.

    Returns:
        list[list]: A 2D array representing the STFT grid (interleaved real and imaginary).
    """
    try:
        def to_1d(v):
            if isinstance(v, list):
                if all(isinstance(row, list) for row in v):
                    return np.array([float(x) for row in v for x in row], dtype=float)
                return np.array([float(x) for x in v], dtype=float)
            return np.array([float(v)], dtype=float)

        x_arr = to_1d(x)

        detrend = spectral_detrend
        if detrend == "False":
            detrend = False

        bound = boundary
        if bound == "None":
            bound = None

        f, t, zxx = scipy_stft(
            x_arr, 
            fs=float(fs), 
            window=window, 
            nperseg=int(nperseg), 
            noverlap=int(noverlap) if noverlap is not None else None, 
            nfft=int(nfft) if nfft is not None else None, 
            detrend=detrend, 
            return_onesided=bool(return_onesided), 
            boundary=bound,
            padded=bool(padded)
        )

        output = []
        header = [""] + t.tolist()
        output.append(header)
        for i, freq in enumerate(f):
            row_real = [f"{freq} (Re)"] + zxx[i, :].real.tolist()
            row_imag = [f"{freq} (Im)"] + zxx[i, :].imag.tolist()
            output.append(row_real)
            output.append(row_imag)

        return output
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Time series of measurement values.
Sampling frequency.
Desired window to use.
Length of each segment.
Number of points to overlap between segments.
Length of the FFT used.
Specifies how to detrend each segment.
If True, return a one-sided spectrum.
Specifies whether the input signal is extended at both ends.
If True, zero-pad signal to fit segments.