matplotlib/matplotlib · error · ValueError
noverlap must be less than NFFT
Error message
noverlap must be less than NFFT
What it means
mlab._spectral_helper, the engine behind psd/csd/coherence/spectrogram, segments the signal into NFFT-length windows stepped by (NFFT - noverlap); it enforces 0 <= noverlap < NFFT because overlap equal to or larger than the window makes the step zero or negative, so no segments could be produced. NFFT=None defaults to 256 before the check runs.
Source
Thrown at lib/matplotlib/mlab.py:253
# implement the core of psd(), csd(), and spectrogram() without doing
# extra calculations. We return the unaveraged Pxy, freqs, and t.
same_data = y is x
if Fs is None:
Fs = 2
if noverlap is None:
noverlap = 0
if detrend_func is None:
detrend_func = detrend_none
if window is None:
window = window_hanning
# if NFFT is set to None use the whole signal
if NFFT is None:
NFFT = 256
if not (0 <= noverlap < NFFT):
raise ValueError('noverlap must be less than NFFT')
if mode is None or mode == 'default':
mode = 'psd'
_api.check_in_list(
['default', 'psd', 'complex', 'magnitude', 'angle', 'phase'],
mode=mode)
if not same_data and mode != 'psd':
raise ValueError("x and y must be equal if mode is not 'psd'")
# Make sure we're dealing with a numpy array. If y and x were the same
# object to start with, keep them that way
x = np.asarray(x)
if not same_data:
y = np.asarray(y)
if sides is None or sides == 'default':
if np.iscomplexobj(x):View on GitHub (pinned to b379c1b69e)
Solutions
- Keep noverlap strictly below NFFT; the idiomatic choice is noverlap = NFFT // 2 (50% overlap).
- If you need more overlap, raise NFFT accordingly (e.g. NFFT=noverlap + 64).
- Validate/clip before calling: noverlap = max(0, min(noverlap, NFFT - 1)).
- Remember NFFT=None silently becomes 256 — pass an explicit NFFT when tuning noverlap.
Example fix
# before Pxx, freqs = mlab.psd(x, NFFT=128, Fs=fs, noverlap=128) # after Pxx, freqs = mlab.psd(x, NFFT=128, Fs=fs, noverlap=64) # 50% overlap
Defensive patterns
Strategy: validation
Validate before calling
def clamp_spectral_params(NFFT, noverlap):
NFFT = 256 if NFFT is None else NFFT
noverlap = 0 if noverlap is None else noverlap
assert 0 <= noverlap < NFFT, f'need 0 <= noverlap < NFFT, got {noverlap=}, {NFFT=}'
return NFFT, min(noverlap, NFFT - 1) Try / catch
try:
Pxx, f = mlab.psd(x, NFFT=NFFT, noverlap=noverlap)
except ValueError as e:
if 'noverlap' in str(e):
Pxx, f = mlab.psd(x, NFFT=NFFT, noverlap=NFFT // 2)
else:
raise Prevention
- Default to noverlap = NFFT // 2 whenever you set NFFT.
- Treat NFFT and noverlap as a pair in configs; validate 0 <= noverlap < NFFT once at entry.
- Remember NFFT=None means 256 — always pass NFFT explicitly when tuning overlap.
When it happens
Trigger: psd(x, NFFT=128, noverlap=128) or noverlap > NFFT; spectrogram(x, NFFT=256, noverlap=300); passing a negative noverlap; setting a large noverlap while leaving NFFT at its 256 default.
Common situations: Porting scipy.signal.spectrogram parameters (nperseg/noverlap) where relationships differ; copying examples that assume 50% overlap but forgetting to raise NFFT for finer resolution; computing noverlap dynamically (e.g. noverlap = int(0.75 * len(x))) without clamping to NFFT.
Related errors
- The window length must match the data's first dimension
- x and y must be equal if mode is not 'psd'
- Coherence is calculated by averaging over *NFFT* length segm
- `bw_method` should be 'scott', 'silverman', a scalar or a ca
- Cannot plot a complex specgram
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/44fc418ff3089f41.
Report an issue: GitHub.