如何加载、去噪并绘制临床标准12导联ECG(.hea/.mat格式)
12导联ECG临床标准样式绘图解决方案
核心问题排查
你之前的代码存在两个关键错误:
- 加载数据时将12导联的二维信号直接
flatten(),丢失了各导联的独立通道信息,导致后续绘图无法区分不同导联 - 去噪过程针对一维混合信号处理,而非每个导联单独去噪,破坏了导联间的独立性
修正后的完整代码实现
1. 数据加载(保留导联通道)
import wfdb import scipy.io import pywt import numpy as np import matplotlib.pyplot as plt import ecg_plot # 确保已安装:pip install ecg-plot # 加载.mat格式数据(推荐,val直接是12行×采样点数的二维数组) mat_data = scipy.io.loadmat('/JS00001.mat') ecg_signals = mat_data['val'] # 形状:(12, n_samples),每行对应一个导联 fs = 500 # 根据数据实际采样率修改,常见为500Hz或250Hz # 若用.hea格式加载,需转置匹配mat格式结构 # record = wfdb.rdrecord('/JS00001') # ecg_signals = record.p_signal.T # 转置为(12, n_samples)
2. 针对每个导联单独去噪
def wavelet_denoise(signal, wavelet='db4', threshold_factor=0.1): coeffs = pywt.wavedec(signal, wavelet) coeffs[1:] = [pywt.threshold(c, threshold_factor * np.max(np.abs(c)), mode='soft') for c in coeffs[1:]] return pywt.waverec(coeffs, wavelet) # 对12个导联逐一去噪 denoised_signals = np.array([wavelet_denoise(lead) for lead in ecg_signals])
3. 临床标准样式绘图
方法1:matplotlib手动绘制(自定义临床布局)
临床12导联标准布局:
- 上排:I、II、III导联
- 中排:aVR、aVL、aVF导联
- 下排:V1-V6导联
# 定义导联名称顺序 lead_names = ['I', 'II', 'III', 'aVR', 'aVL', 'aVF', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6'] # 生成时间轴 time = np.arange(ecg_signals.shape[1]) / fs plt.figure(figsize=(18, 12)) for i in range(12): plt.subplot(6, 2, i+1) plt.plot(time, denoised_signals[i], color='black', linewidth=0.8) plt.title(lead_names[i], fontsize=12) plt.xlim([0, 10]) # 显示前10秒数据,可按需调整 plt.ylim([-2, 2]) # 振幅范围符合临床常规(单位:mV) plt.xticks(fontsize=10) plt.yticks(fontsize=10) # 隐藏冗余边框,仅保留左、下边框 plt.gca().spines['top'].set_visible(False) plt.gca().spines['right'].set_visible(False) plt.tight_layout() plt.show()
方法2:正确使用ecg_plot库
之前调用无效的原因是数据格式或采样率参数错误,需确保输入为(12, n_samples)的二维数组,且采样率匹配实际数据:
# 绘制去噪后的12导联ECG ecg_plot.plot_12(denoised_signals, sample_rate=fs, title='12导联ECG(去噪后)') ecg_plot.show()
关键注意事项
- 采样率
fs必须与数据实际采样率一致,否则时间轴显示错误 - 若需绘制原始信号,只需将
denoised_signals替换为ecg_signals - 手动绘图的振幅范围
ylim可根据数据实际幅值调整,临床常规为±2mV~±3mV
内容的提问来源于stack exchange,提问作者R. Carrillo
相关产品推荐
相关产品推荐

