Pan-Tompkins QRS Detector — Python
A Python port of the Pan-Tompkins real-time QRS detection algorithm for ECG signals.
Original MATLAB implementation by Hooman Sedghamiz (Feb 2018), MSc Biomedical Engineering, Linköping University.
Python port by Dr. Hatem Zehir.
Python conversion retains the original BSD 3-Clause license — seeLICENSE.
Algorithm Overview
The Pan-Tompkins algorithm is a classic, widely used method for detecting QRS complexes (R-peaks) in ECG signals in real time. It processes the ECG through a signal-processing pipeline:
- Bandpass filter (5–15 Hz) — removes baseline wander and high-frequency noise
- Derivative filter — emphasises the steep slopes of QRS complexes
- Squaring — makes all values positive and amplifies large slopes
- Moving-window integration (~150 ms window) — produces a smooth envelope
- Adaptive thresholding & decision logic — distinguishes true QRS complexes from T-waves and noise using two running thresholds updated after each beat
References
- Pan, J. & Tompkins, W. J., "A Real-Time QRS Detection Algorithm", IEEE Trans. Biomed. Eng., BME-32(3), March 1985.
- Sedghamiz, H., "Matlab Implementation of Pan Tompkins ECG QRS detector", 2014. ResearchGate
Installation
pip install -r requirements.txt
Dependencies:
| Package | Version |
|---|---|
| numpy | ≥ 1.21 |
| scipy | ≥ 1.7 |
| matplotlib | ≥ 3.4 |
Usage
import numpy as np
from pan_tompkins import pan_tompkins
# Load your ECG signal and sampling frequency
# ecg : 1-D numpy array of the raw ECG
# fs : sampling frequency in Hz (e.g. 200, 360, 500)
qrs_amp, qrs_idx, delay = pan_tompkins(ecg, fs, gr=True)
print(f"Detected {len(qrs_idx)} QRS complexes")
print(f"R-peak sample indices: {qrs_idx}")
Parameters
| Parameter | Type | Description |
|---|---|---|
ecg |
np.ndarray |
Raw 1-D ECG signal |
fs |
float |
Sampling frequency in Hz |
gr |
bool |
Plot intermediate stages and results (default True) |
Returns
| Return value | Description |
|---|---|
qrs_amp_raw |
Amplitudes of detected R-waves (from bandpass-filtered signal) |
qrs_i_raw |
Sample indices of detected R-waves |
delay |
Filter delay in samples |
Quick Demo
Running the script directly generates a synthetic ECG (~70 bpm, 10 s at 200 Hz) and detects QRS complexes:
python pan_tompkins.py
Expected output:
Detected 12 QRS complexes
R-peak indices: [ 100 270 440 610 780 950 1119 1289 1459 1629 1799 1969]
Delay: 15.0 samples
Notes
- For
fs = 200 Hz, separate low-pass (12 Hz) and high-pass (5 Hz) Butterworth filters are applied sequentially. - For all other sampling rates, a single bandpass Butterworth filter (5–15 Hz) is used.
- The derivative filter kernel is interpolated to match the sampling rate when
fs ≠ 200. filtfilt(zero-phase filtering) is used throughout, sodelayreports the moving-average window contribution only.
License
BSD 3-Clause License. Copyright (c) 2018, Hooman Sedghamiz. See LICENSE for full details.
Copyright (c) 2018 Hooman Sedghamiz
Copyright (c) 2026 Dr. Hatem Zehir
Citation
If you use this implementation in your research, please cite:
@article{PanTompkins1985,
author = {Pan, J. and Tompkins, W. J.},
title = {A Real-Time QRS Detection Algorithm},
journal = {IEEE Transactions on Biomedical Engineering},
year = {1985},
volume = {BME-32},
number = {3},
pages = {230--236},
doi = {10.1109/TBME.1985.325532}
}
@software{ZehirPythonPort2026,
author = {Zehir, Hatem},
title = {Pan-Tompkins QRS Detector — Python},
year = {2026},
url = {https://github.com/Hatem-Zehir/pan-tompkins-qrs-detector}
}
🤝 Contributing
Contributions, bug reports, and feature requests are welcome.
Please open an issue or submit a pull request.
Metadata
Release files for pantompkins 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pantompkins-1.0.0.tar.gz | 69.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pantompkins-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.2 kB
Release files / pantompkins-1.0.0.tar.gz
| Download URL | pantompkins-1.0.0.tar.gz |
|---|---|
| Size | 69.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
815af307396c4b7d0d53d857a2868c5b4e0e280b997511cc1ce2e9de5400e139
|
|
BLAKE2b-256 checksum How to use checksums |
791d99b460efebc00a4b5b09603a878b14bf94fa518745b178fa547d163e24aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.11
|
Release files / pantompkins-1.0.0-py3-none-any.whl
| Download URL | pantompkins-1.0.0-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6d10ad39e5371826aa4f755544eed398ac3bcd646816a326acb9eb30319a135
|
|
BLAKE2b-256 checksum How to use checksums |
f18124cfbb022aef389dcb951213c04868d6989bcc5356d24f586ed5ad7e4c99
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.11
|