Peak Detection in Python for Spectroscopy: find_peaks, Prominence, and Baseline Correction

Spectroscopy plots are rarely clean. Baselines drift, noise hides weaker peaks, and a naive threshold can miss the features that matter. A better workflow is to smooth first, tune peak prominence carefully, and then inspect the detected peaks before you trust the result.
Preprocess
Smooth and de-noise before peak detection.
Detect
Use prominence and width, not just raw height.
Validate
Inspect the annotated result before reporting anything.
Example workflow
The code below keeps the logic intentionally simple. In real Raman, FTIR, UV-Vis, or chromatogram data, you would usually add baseline correction and maybe fit the strongest peaks with Gaussian or Lorentzian models.
Try it
Try it now: generate your ROC curve
Build an ROC figure with AUC annotation and threshold-aware styling from your own classification results.
Generate my ROC curve →Newsletter
Get a weekly Python plotting tip
One concise tip each week for cleaner, faster scientific figures. Built for researchers who publish.
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks, savgol_filter
x = np.linspace(400, 1800, 1200)
signal = np.exp(-0.5 * ((x - 730) / 18) ** 2) + 0.6 * np.exp(-0.5 * ((x - 1100) / 25) ** 2)
signal += 0.03 * np.sin(x / 25) + np.random.default_rng(4).normal(0, 0.03, len(x))
smoothed = savgol_filter(signal, 41, 3)
peaks, props = find_peaks(smoothed, prominence=0.08, width=10)
fig, ax = plt.subplots(figsize=(8, 4.5))
ax.plot(x, signal, color="gray", alpha=0.5, label="Raw")
ax.plot(x, smoothed, color="black", lw=1.5, label="Smoothed")
ax.plot(x[peaks], smoothed[peaks], "o", color="crimson")
ax.legend(frameon=False)
plt.tight_layout()What matters most
- Prominence is usually more useful than height when the baseline shifts.
- Width helps separate broad real features from narrow noise spikes.
- Peak distances prevent the same feature from being counted twice.
- Always annotate units on the x-axis, especially for spectra.
Best for
Raman, FTIR, UV-Vis, NMR, chromatography, and any instrument trace where peaks represent interpretable physical or chemical events.
Avoid if
You only need a descriptive trend line. Peak detection is overkill when the underlying question is about overall shape, not discrete maxima.
For preprocessing details, review Savitzky-Golay smoothing. For peak shape modeling, see Gaussian fitting.
Try Plotivy on your spectrumRelated chart guides
Apply this tutorial directly in the chart gallery with ready-to-run prompts and examples.
Technique guides scientists read next
scipy.signal.find_peaks guide
Tune prominence and width parameters for robust peak extraction.
Savitzky-Golay smoothing
Reduce noise while preserving peak shape and position.
PCA visualization workflow
Move from high-dimensional measurements to interpretable components.
ANOVA with post-hoc brackets
Add statistically correct pairwise significance annotations.
Found this helpful? Share it with your network.
Experimental Physicist & Photonics Researcher
Hands-on experience in silicon photonics, semiconductor fabrication (DRIE/ICP-RIE), optical simulation, and data-driven analysis. Built Plotivy to help researchers focus on discoveries instead of data struggles.
More about the authorVisualize your own data
Apply the techniques from this article to your own datasets. Upload CSV, Excel, or paste data directly.