Я сделал окно pyqt для отображения сигнала в виде matplotlib с QScrollBar
, чтобы увидеть другую часть сигнала. Моя проблема заключается в том, что когда я строю сигнал 100, стрелка QScrollBar
дважды вызывает функцию, которая вызывается для сигнала valueChanged
.
Когда я ставлю только 10 сигналов (self.Sigs_dict = np.random.rand(10,105*self.Fs)
), я передаю толькоодин раз в функции update_plot
, где я печатаю информацию о времени:
first 1572956286.183867
set 0.0
Но если я увеличу число сигналов до 100 (self.Sigs_dict = np.random.rand(100,105*self.Fs)
), я дважды передам функцию update_plot
. Затем я получаю:
first 1572956174.959317
set 0.009981632232666016
first 1572956175.6289513
set 0.0
Я не понимаю, почему это происходит и как я могу решить эту проблему.
Вот минимальный пример моей проблемы:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np
import time
class Viewer(QMainWindow):
def __init__(self, parent=None):
super(Viewer, self).__init__()
self.parent = parent
#######################################
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.mainVBOX_param_scene = QVBoxLayout()
self.mascene = plot(self)
self.paramPlotV = QVBoxLayout()
self.horizontalSliders = QScrollBar(Qt.Horizontal)
self.horizontalSliders.valueChanged.connect(self.update_plot)
self.horizontalSliders.setMinimum(0)
self.horizontalSliders.setMaximum(1)
self.horizontalSliders.setPageStep(1)
self.paramPlotV.addWidget(self.horizontalSliders)
self.mainVBOX_param_scene.addWidget(self.mascene)
self.mainVBOX_param_scene.addLayout(self.paramPlotV)
self.centralWidget.setLayout(self.mainVBOX_param_scene)
self.Fs = 1024
self.Sigs_dict = np.random.rand(100,105*self.Fs)
self.t = np.arange(self.Sigs_dict.shape[1])/self.Fs
self.update()
def updateslider(self):
self.horizontalSliders.setMinimum(0)
self.horizontalSliders.setMaximum(np.ceil(self.t[-1]/int(10))-1)
def update_plot(self):
t = time.time()
print('first',t)
self.mascene.update_set_data()
print('set',time.time() - t)
def update(self):
self.updateslider()
self.mascene.modify_sigs()
self.mascene.update()
class plot(QGraphicsView):
def __init__(self, parent=None):
super(plot, self).__init__(parent)
self.parent = parent
self.scene = QGraphicsScene(self)
self.setScene(self.scene)
self.figure = plt.figure(facecolor='white')#Figure()
self.canvas = FigureCanvas(self.figure)
self.widget = QWidget()
self.widget.setLayout(QVBoxLayout())
self.scroll = QScrollArea(self.widget)
self.scroll.setWidget(self.canvas)
layout = QVBoxLayout()
layout.addWidget(self.scroll)
self.setLayout(layout)
def modify_sigs(self):
self.Sigs_dict = self.parent.Sigs_dict
self.t = self.parent.t
self.Fs= self.parent.Fs
def update_set_data(self):
ts, te = self.get_ts_te()
t = self.t[ts:te]
for i,line in enumerate(self.Lines):
line.set_data(t, (self.Sigs_dict[i, ts:te]) + i)
self.axes.set_xlim((ts/ self.Fs, ts / self.Fs + 10 ))
self.canvas.draw_idle()
def update(self):
self.figure.clear()
plt.figure(self.figure.number)
self.axes = plt.subplot(1, 1, 1)
ts, te = self.get_ts_te()
self.Lines = []
for i in range(self.Sigs_dict.shape[0]):
line, = plt.plot(self.t[ts:te], (self.Sigs_dict[i,ts:te]-np.mean(self.Sigs_dict[i,ts:te]))+i)
self.Lines.append(line)
self.canvas.setGeometry(0, 0, self.parent.width()-100, (self.parent.height()-100))
self.canvas.draw_idle()
def get_ts_te(self):
win_num = self.parent.horizontalSliders.value()
ts = int(10 * (win_num) * self.Fs)
te = ts + int(10 * self.Fs)
if te > len(self.t):
diff = te - len(self.t)
ts = ts - diff
te = len(self.t)
return ts, te
def main():
app = QApplication(sys.argv)
ex = Viewer(app)
ex.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()