Skip to main content

ecg-records

ecg-records measures 12-lead (or 1–8-channel) ECGs and emits a small, versioned JSON document, the ECG Record: record-level intervals, axes and rhythm measures, median-beat values per lead, and per-beat, per-lead fiducials, intervals and amplitudes -- each with an explicit unit, an explicit reason for every missing value, a feature state, a stable address and a validation status. It reads WFDB, EDF/BDF, CSV and NumPy files, draws clinical-format plots, and pairs with the optional rule-based ecginterpret. The import name is ecgfeat.

This software is research and engineering software. It is not a medical device and is not intended to diagnose, treat, cure, or prevent disease. Outputs require independent validation for the intended use and must not be used as a substitute for professional medical judgment.

Install

pip install "ecg-records[engine]"        # records + the compiled measurement engine
pip install ecg-records                  # records only (read, query, plot); no measuring
pip install "ecg-records[viz]"           # + Matplotlib plots (ecgfeat.viz)
pip install "ecg-records[table]"         # + pandas DataFrames and Parquet tables
pip install "ecg-records[interpret]"     # + rule-based interpretation (ecginterpret)
pip install "ecg-records[all]"           # everything above + Plotly

Python 3.10–3.14. Optional: wfdb (exotic WFDB layouts), interactive (Plotly).

The engine (ecg-records-engine, compiled wheels for Linux, macOS and Windows) is free for noncommercial use under the PolyForm Noncommercial License 1.0.0 and needs a commercial licence key otherwise; ecg-records itself is Apache-2.0. Keys are verified offline and never restrict functionality. See the documentation page Licensing and ecgfeat.license_info().

Ten lines

import ecgfeat
from ecgfeat import viz

signal = ecgfeat.load_example("sinus")        # bundled PTB-XL record; or ecgfeat.read_signal("x.hea")
record = ecgfeat.ecg_record(signal)            # validated ECG Record, schema 1.1.0
print(record.summary())                        # rate, P/PR/QRS/QT, QTc, axes
record.get("qt_interval_ms")                   # record level, ms
record.get("median_st_60ms_uv", lead="V2")     # median beat of one lead, µV
record.get("qrs_duration_ms", lead="V1", beat=3)
record.to_dataframe("leads")                   # pandas: one row per lead
figure, ax = viz.plot_ecg(signal, record)      # 12-lead ECG paper at 25 mm/s, 10 mm/mV

Read files

signal = ecgfeat.read_signal("ptbxl/records500/00000/00001_hr.hea")  # WFDB 16/212/24/32/61/80, .mat
signal = ecgfeat.read_signal("study.edf", channels=["II", "V5"])     # EDF, EDF+, BDF
signal = ecgfeat.read_signal("export.csv")                           # header row + time column
record = ecgfeat.record_from_file("long.edf", start_s=60, end_s=70)  # read + window + measure
records = ecgfeat.ecg_record_segments(signal, segment_s=10)          # long recordings, window by window

Arrays work too: ecg_record(array, sampling_rate=500, lead_names="standard_12"). Lead names are normalized (AVR, ECG aVR → aVR). Fewer than 12 channels need input_mode="limited"; axes and formal QT are then not_applicable.

Read records back

Reading needs no NumPy, SciPy or plotting code:

from ecgfeat import dumps_record, load_record

open("rec.json", "wb").write(dumps_record(record))
record = load_record("rec.json")                       # strict validation
result = record.query("qt_interval_ms")                # value, unit, absence, feature_state, address, validation
result.feature_state                                   # e.g. {'status': 'observed', 'reason': 'value_available'}
record.to_csv("rec.csv")                               # one row per published cell

Values the engine kept but flagged (a QT that failed the reportability gate) are published with a feature state other than observed; check it before use. Addresses: ecg-record:<record_id>@<schema_version>#<RFC 6901 pointer>.

Plot

ecgfeat.viz (the viz extra) never imports pyplot; every function takes (signal, record) -- verified by SHA-256 -- and returns (figure, axes): plot_ecg (ECG paper, 3x4/6x2/12x1 with rhythm strips, real millimetres), plot_record, plot_beat, plot_beat_all_leads, plot_representative_beat, plot_median_beats, plot_st_segments, plot_rhythm, plot_quality_summary, plus plot_record_interactive (Plotly) and annotations_to_dict for web front-ends. Themes: viz.use_style("dark"), viz.PlotStyle().replace(...).

Command line

ecg-record measure ptbxl/00001_hr.hea -o rec.json       # rate and leads from the file
ecg-record summary rec.json
ecg-record table rec*.json -o global.csv                 # or .parquet; --kind long
ecg-record plot ptbxl/00001_hr.hea --kind paper -o ecg.png
ecg-record batch 'ptbxl/**/*.hea' --output-dir out --jobs 8 --table out/global.csv
ecg-record examples

Validation status

Every field's status comes from the validation-evidence registry shipped with its schema. In schema 1.1.0 the record-level P duration, PR, QRS and QT are benchmark_validated: on LUDB 1.0.1 they meet the IEC 60601-2-25 global interval limits against the expert annotations, evaluated the CSE way. On a 3,000-record PTB-XL hold-out, QRS and QT also agree with GE 12SL within those limits; P duration and PR do not (two machine algorithms disagree on PR by more than the limit too). Everything else is unvalidated -- per-lead fiducials, for instance, do not meet the CSE delineation tolerances on LUDB. Evidence manifests and tools live in the repository (benchmarks/evidence/).

Versions and compatibility

  • Package and schema versions are independent. 0.2.x writes schema 1.1.0 and reads schema major 1; schema 1.1 is additive, and the 0.1.0 reader loads 1.1 records.
  • Legacy APIs (ECGFeatureExtractor, to_dict, interpret, plot_*, ...) warn and remain until 0.3.0; ecgfeat.compat provides the exact legacy contract.

The bundled example ECGs are PTB-XL 1.0.1 records (Wagner et al., PhysioNet 2020, CC BY 4.0); see NOTICE.

Documentation: https://github.com/humansys-lab/ECG-feature-extraction-/tree/main/docs/site

Metadata

Release files for ecg-records 0.3.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 ecg-records 0.3.0
File Size Uploaded Provenance
ecg_records-0.3.0.tar.gz 439.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ecg-records 0.3.0
File Interpreter ABI Platform
ecg_records-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 909.1 kB

Release files / ecg_records-0.3.0.tar.gz

Download URL ecg_records-0.3.0.tar.gz
Size 439.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9dfa58edbf73d0fcd229e2dccb88ee5a18b43572403200b5751940715f57a217
BLAKE2b-256 checksum
How to use checksums
1a2e9382ab01b9e6c473c9da9f1be65eef5d1af3ecd2986f3bf512fc2112e4e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / ecg_records-0.3.0-py3-none-any.whl

Download URL ecg_records-0.3.0-py3-none-any.whl
Size 469.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8e150297b7dde84d2a6218c720c5b043c04eb69f992ada086ac73febd3fe8fff
BLAKE2b-256 checksum
How to use checksums
253d36751acfd830724fd21e6f17946407ee830736cff4dbb38e6b2d75a84315
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for ecg-records 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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