Skip to main content

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 — see LICENSE.


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:

  1. Bandpass filter (5–15 Hz) — removes baseline wander and high-frequency noise
  2. Derivative filter — emphasises the steep slopes of QRS complexes
  3. Squaring — makes all values positive and amplifies large slopes
  4. Moving-window integration (~150 ms window) — produces a smooth envelope
  5. 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, so delay reports 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)

Source distribution for pantompkins 1.0.0
File Size Uploaded
pantompkins-1.0.0.tar.gz 69.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pantompkins 1.0.0
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page