{"record":{"id":"44fc418ff3089f41","repo":"matplotlib/matplotlib","slug":"noverlap-must-be-less-than-nfft","errorCode":null,"errorMessage":"noverlap must be less than NFFT","messagePattern":"noverlap must be less than NFFT","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/matplotlib/mlab.py","lineNumber":253,"sourceCode":"        # implement the core of psd(), csd(), and spectrogram() without doing\n        # extra calculations.  We return the unaveraged Pxy, freqs, and t.\n        same_data = y is x\n\n    if Fs is None:\n        Fs = 2\n    if noverlap is None:\n        noverlap = 0\n    if detrend_func is None:\n        detrend_func = detrend_none\n    if window is None:\n        window = window_hanning\n\n    # if NFFT is set to None use the whole signal\n    if NFFT is None:\n        NFFT = 256\n\n    if not (0 <= noverlap < NFFT):\n        raise ValueError('noverlap must be less than NFFT')\n\n    if mode is None or mode == 'default':\n        mode = 'psd'\n    _api.check_in_list(\n        ['default', 'psd', 'complex', 'magnitude', 'angle', 'phase'],\n        mode=mode)\n\n    if not same_data and mode != 'psd':\n        raise ValueError(\"x and y must be equal if mode is not 'psd'\")\n\n    # Make sure we're dealing with a numpy array. If y and x were the same\n    # object to start with, keep them that way\n    x = np.asarray(x)\n    if not same_data:\n        y = np.asarray(y)\n\n    if sides is None or sides == 'default':\n        if np.iscomplexobj(x):","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/matplotlib/matplotlib/blob/b379c1b69e012b142c0f496a52bcb30513802d72/lib/matplotlib/mlab.py#L235-L271","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nPxx, freqs = mlab.psd(x, NFFT=128, Fs=fs, noverlap=128)\n\n# after\nPxx, freqs = mlab.psd(x, NFFT=128, Fs=fs, noverlap=64)  # 50% overlap","handlingStrategy":"validation","validationCode":"def clamp_spectral_params(NFFT, noverlap):\n    NFFT = 256 if NFFT is None else NFFT\n    noverlap = 0 if noverlap is None else noverlap\n    assert 0 <= noverlap < NFFT, f'need 0 <= noverlap < NFFT, got {noverlap=}, {NFFT=}'\n    return NFFT, min(noverlap, NFFT - 1)","typeGuard":null,"tryCatchPattern":"try:\n    Pxx, f = mlab.psd(x, NFFT=NFFT, noverlap=noverlap)\nexcept ValueError as e:\n    if 'noverlap' in str(e):\n        Pxx, f = mlab.psd(x, NFFT=NFFT, noverlap=NFFT // 2)\n    else:\n        raise","preventionTips":["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."],"tags":["matplotlib","mlab","psd","spectrogram","signal-processing","parameter-validation"],"backgroundTag":"invalid-parameter-combination","analyzedSha":"b379c1b69e012b142c0f496a52bcb30513802d72","analyzedAt":"2026-08-21T23:31:55.468Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}