Files
Feature-Extraction/test_of_matplotlib.py
2025-10-20 22:01:18 +08:00

240 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import numpy as np
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun'] # 使用宋体
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
from global_var import global_var_init
cycle, fs, record_name, data_path = global_var_init()
from processing import processing
(signal_dwt , waves_dwt , rpeaks , ecg_signal,
signal, signal.v, signal.fs, rows_to_extract, t_ecg, t_ppg,
on_column_list, on_column_list_toArea, on_values, on_values_toArea,
sp_column_list, sp_values, dn_column_list, dn_values, dp_column_list,
dp_values, u_column_list, u_column_list_toArea, u_values, u_values_toArea,
v_column_list, v_values, w_column_list, w_values, a_column_list, a_column_list_toArea,
a_values, a_values_toArea, b_column_list, b_values, c_column_list, c_values,
e_column_list, e_values, f_column_list, f_values,
signal.ppg, signal.vpg, signal.apg, signal.jpg) = processing()
from ecg_peaks_val import ecg_peaks_val
(P_peaks, Q_peaks, R_peaks, S_peaks, T_peaks,
P_onsets, P_offsets, T_onsets, T_offsets,
P_peaks_values, Q_peaks_values, R_peaks_values, S_peaks_values, T_peaks_values,
P_onsets_values, P_offsets_values, T_onsets_values, T_offsets_values,
PQ_baseline) = ecg_peaks_val()
from ppg_peaks_val import ppg_peaks_val
(on, on_toArea, sp, dn, dp,
on_values, on_toArea_values, sp_values, dn_values, dp_values,
u, u_toArea, v, w,
u_values, u_toArea_values, v_values, w_values,
a, a_toArea, b, c, e, f,
a_values, a_toArea_values, b_values, c_values, e_values, f_values) = ppg_peaks_val()
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#----------------------------------- 创建拖动类 ----------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
class DraggablePoints:
def __init__(self, ax, points, signal_type, signal_name):
self.ax = ax
self.points = points # 这里是 Line2D 对象的列表
self.signal_type = signal_type
self.signal_name = signal_name
self.selected_point = None
self.press = None
self.new_x = None
self.real_y = None # 最终获得的点,其纵坐标数值应在信号线上
self.point_x = None
# 连接鼠标事件
self.cidpress = ax.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.cidmotion = ax.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
self.cidrelease = ax.figure.canvas.mpl_connect('button_release_event', self.on_release)
def on_press(self, event):
if self.ax == event.inaxes:
for point in self.points:
point_x = point.get_xdata()
point_y = point.get_ydata()
distance = np.hypot(point_x - event.xdata, point_y - event.ydata)
if distance < 0.05: # 可以根据需要调整这个阈值
self.selected_point = point
self.point_x = point.get_xdata()
self.point_y = point.get_ydata()
self.press = (point_x, point_y, event.xdata, event.ydata)
break
def on_motion(self, event):
if self.selected_point is None or event.inaxes != self.ax:
return
if self.signal_name == "ECG":
# 计算点的新的位置
self.new_x = self.press[0] + (event.xdata - self.press[2])
self.real_y = self.signal_type[int(self.new_x*fs)]
self.real_y = np.array([self.real_y]) #格式转换从float64 转换成了 ndarray为了set_data能读取
# 更新选中点的位置
self.selected_point.set_data(self.new_x, self.real_y)
self.ax.figure.canvas.draw() # 使用 draw 更新
else :
# 计算点的新的位置
self.new_x = self.press[0] + (event.xdata - self.press[2])
self.real_y = self.signal_type[int(self.new_x*fs)]
self.real_y = np.array([self.real_y]) #格式转换从float64 转换成了 ndarray为了set_data能读取
# 更新选中点的位置
self.selected_point.set_data(self.new_x, self.real_y)
self.ax.figure.canvas.draw() # 使用 draw 更新
def on_release(self, event):
if self.selected_point:
if self.signal_name == "ECG":
print(" 点所属的信号 ",self.signal_name)
print(" 点的坐标(t) ",self.point_x, self.point_y)
print(" 更新后点坐标(t) ",np.round(self.new_x, 3) , "[", self.real_y, "]" )
print(" 点的位置 : ",int(self.point_x*fs))
print(" 更新后点的位置 ",int(self.new_x*fs) )
print("------------------------------------------")
else:
print(" 点所属的信号 ",self.signal_name)
print(" 点的坐标(t) ",self.point_x, self.point_y)
print(" 更新后点坐标(t) ",np.round(self.new_x, 3) , "[", self.real_y, "]" )
print(" 点的位置 : ",int(self.point_x*fs))
print(" 更新后点的位置 ",int(self.new_x*fs) )
print("------------------------------------------")
self.selected_point = None
self.press = None
self.new_x = None
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#----------------------------------- 创建绘图函数 ----------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
def create_plot_with_draggable_points(save_path = None):
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, sharex=True)
# 绘制归一化后的ECG信号
ax1.plot(t_ecg, ecg_signal)
ax1.set(xlabel='', ylabel='ECG')
# 绘制归一化后的PPG信号
ax2.plot(t_ppg, signal.ppg)
ax2.set(xlabel='', ylabel='PPG')
# 绘制归一化后的一阶导数
ax3.plot(t_ppg, signal.vpg)
ax3.set(xlabel='', ylabel='vpg')
# 绘制归一化后的二阶导数
ax4.plot(t_ppg, signal.apg)
ax4.set(xlabel='Time (s)', ylabel='apg')
# 存储并绘制这些点对象
points_1 = [ax1.plot(x, y, 'o')[0] for x, y in zip(t_ecg[P_peaks], P_peaks_values)]
points_1 += [ax1.plot(x, y, 'o', color='cyan')[0] for x, y in zip(t_ecg[Q_peaks], Q_peaks_values)]
points_1 += [ax1.plot(x, y, 'o', color='purple')[0] for x, y in zip(t_ecg[R_peaks], R_peaks_values)]
points_1 += [ax1.plot(x, y, 'o', color='blue')[0] for x, y in zip(t_ecg[S_peaks], S_peaks_values)]
points_1 += [ax1.plot(x, y, 'o', color='black')[0] for x, y in zip(t_ecg[T_peaks], T_peaks_values)]
points_1 += [ax1.plot(x, y, 'x', color='red')[0] for x, y in zip(t_ecg[P_onsets], P_onsets_values)]
points_1 += [ax1.plot(x, y, 'x', color='magenta')[0] for x, y in zip(t_ecg[P_offsets], P_offsets_values)]
points_1 += [ax1.plot(x, y, 'x', color='black')[0] for x, y in zip(t_ecg[T_onsets], T_onsets_values)]
points_1 += [ax1.plot(x, y, 'x', color='gold')[0] for x, y in zip(t_ecg[T_offsets], T_offsets_values)]
points_2 = [ax2.plot(x, y, 'o', color='red')[0] for x, y in zip(t_ppg[on], on_values)]
points_2 += [ax2.plot(x, y, 'o', color='blue')[0] for x, y in zip(t_ppg[sp], sp_values)]
points_2 += [ax2.plot(x, y, 'x', color='orange')[0] for x, y in zip(t_ppg[dn], dn_values)]
points_2 += [ax2.plot(x, y, 'o', color='purple')[0] for x, y in zip(t_ppg[dp], dp_values)]
points_3 = [ax3.plot(x, y, 'o', color='cyan')[0] for x, y in zip(t_ppg[u], u_values)]
points_3 += [ax3.plot(x, y, 'o', color='magenta')[0] for x, y in zip(t_ppg[v], v_values)]
points_3 += [ax3.plot(x, y, 'o', color='black')[0] for x, y in zip(t_ppg[w], w_values)]
points_4 = [ax4.plot(x, y, 'o', color='black')[0] for x, y in zip(t_ppg[a], a_values)]
points_4 += [ax4.plot(x, y, 'o', color='blue')[0] for x, y in zip(t_ppg[b], b_values)]
points_4 += [ax4.plot(x, y, 'o', color='green')[0] for x, y in zip(t_ppg[c], c_values)]
points_4 += [ax4.plot(x, y, 'o', color='orange')[0] for x, y in zip(t_ppg[e], e_values)]
points_4 += [ax4.plot(x, y, 'o', color='purple')[0] for x, y in zip(t_ppg[f], f_values)]
draggable_points_1 = DraggablePoints(ax1, points_1, ecg_signal, signal_name = "ECG")
draggable_points_2 = DraggablePoints(ax2, points_2, signal.ppg, signal_name = "PPG")
draggable_points_3 = DraggablePoints(ax3, points_3, signal.vpg, signal_name = "VPG")
draggable_points_4 = DraggablePoints(ax4, points_4, signal.apg, signal_name = "APG")
# 如果指定了保存路径,则保存图像
if save_path:
plt.savefig(save_path)
plt.tight_layout()
plt.show()
# 将图形嵌入到 Qt 的 canvas 中
# canvas.figure = fig
# canvas.draw()
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#----------------------------------- 调用绘图函数 ----------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
print(len(P_peaks))
print(len(Q_peaks))
print(len(R_peaks))
print(len(S_peaks))
print(len(T_peaks))
print(len(P_onsets))
print(len(P_offsets))
print(len(T_onsets))
print(len(T_offsets))
print(len(u))
print(len(v))
print(len(w))
print(len(a))
print(len(b))
print(len(c))
print(len(e))
print(len(f))
create_plot_with_draggable_points()