Я пытаюсь разработать небольшой сбор данных GUI, который изображен ниже, и все работает как предназначено для небольших наборов данных. Вот как это должно работать: нажмите «Пуск / Стоп», чтобы начать или остановить обновление графика траектории, а также гистограмм. Траектория получает данные из 2 текстовых файлов с 1 000 000 точек каждый с использованием генераторов python. После повторного нажатия этой же кнопки обновление просто прекращается. Вот и все. Проблема в том, что производительность начинает падать довольно быстро, приближаясь к 10 000 точкам в системе. Но это снижение производительности происходит только из-за реакции системы на нажатие кнопки, графики продолжают обновляться, как будто ничего не происходит. Как это может быть? Как я мог решить это? Ниже я опубликую часть кода, который может помочь поймать ошибку (я пропущу материал макета)
Извините за длинный пост.
def read_file(file):
for row in open(file, "r"):
yield row
while True:
yield None
def gaussian(x, B, mu, sigma):
return B * np.exp(-1.0 * (x - mu) ** 2 / (2 * sigma ** 2))
class Ui_MainWindow(object):
counter = 0
XDATA = read_file("xdata.txt")
YDATA = read_file("ydata.txt")
def setupUi(self, MainWindow):
(...)
self.map = pg.PlotWidget(self.centralwidget)
(...)
self.yhist = pg.PlotWidget(self.centralwidget)
(...)
self.xhist = pg.PlotWidget(self.centralwidget)
(...)
# Connect buttons to slots
self.start_stop.clicked.connect(self.start)
self.clear.clicked.connect(self.clear_data)
self.fitButton.clicked.connect(self.fit)
# Plot dummy data to map
self.xdata = [0]
self.ydata = [0]
self.curve = pg.PlotDataItem(self.xdata, self.ydata)
self.map.addItem(self.curve)
# plot dummy data to xhist
self.freqx, self.binsx = np.histogram(self.xdata)
self.binscenters_x = np.array([0.5 * (self.binsx[i] + self.binsx[i + 1]) for i in range(len(self.binsx) - 1)])
self.freqx = self.freqx / np.max(self.freqx)
self.x_bar = pg.BarGraphItem(x=self.binscenters_x, height=self.freqx,
width=self.binsx[2] - self.binsx[3],
brush='r')
pen = pg.mkPen(color=(255, 255, 0), width=2.5, style=QtCore.Qt.SolidLine)
self.fitLine_x = pg.PlotDataItem([0], [0], pen=pen)
self.xhist.addItem(self.x_bar)
self.xhist.addItem(self.fitLine_x)
# plot dummy data to yhist
self.freqy, self.binsy = np.histogram(self.xdata)
self.binscenters_y = np.array([0.5 * (self.binsy[i] + self.binsy[i + 1]) for i in range(len(self.binsy) - 1)])
self.freqx = self.freqx / np.max(self.freqx)
self.y_bar = pg.BarGraphItem(x=self.binscenters_y, height=self.freqy,
width=self.binsx[2] - self.binsx[3],
brush='r')
self.fitLine_y = pg.PlotDataItem([0], [0], pen=pen)
self.yhist.addItem(self.y_bar)
self.yhist.addItem(self.fitLine_y)
# Set a timer for the update
# make QTimer
self.qTimer = QtCore.QTimer()
# set interval
self.qTimer.setInterval(5) # 1000 ms = 1 s
# connect timeout signal to signal handler
self.qTimer.timeout.connect(self.update)
def start(self):
start=0
end=0
current_counts=0
if self.start_stop.isChecked():
print("start")
start=time()
current_counts = self.counter
self.qTimer.start()
self.fitButton.setEnabled(False)
self.clear.setEnabled(False)
else:
print("stop")
self.qTimer.stop()
self.fitButton.setEnabled(True)
self.clear.setEnabled(True)
end = time()
print(end)
print("FPS: ", (self.counter-current_counts) / (end - start))
print("Total number of points read: ", self.counter)
def clear_data(self):
self.xdata = [0]
self.ydata = [0]
self.curve.setData(self.xdata, self.ydata)
def fit(self):
params_x, cov_x = curve_fit(gaussian, self.binscenters_x, self.freqx)
params_y, cov_y = curve_fit(gaussian, self.binscenters_y, self.freqy)
# plot it on the histograms
data_range = np.linspace(-1, 1, 1000)
self.fitLine_x.setData(data_range, gaussian(data_range, *params_x))
self.fitLine_y.setData(data_range, gaussian(data_range, *params_y))
# print the data to the tables
(...)
def update(self):
# print(self.counter)
self.counter += 1
# update map
if next(self.XDATA) is None:
pass
else:
self.xdata.append(float(next(self.XDATA)))
self.ydata.append(float(next(self.YDATA)))
self.curve.setData(self.xdata, self.ydata)
# update xhist
self.freqx, self.binsx = np.histogram(self.xdata)
self.binscenters_x = np.array([0.5 * (self.binsx[i] + self.binsx[i + 1]) for i in range(len(self.binsx) - 1)])
self.freqx = self.freqx / np.max(self.freqx)
self.x_bar.setOpts(x=self.binscenters_x, height=self.freqx, width=self.binsx[2] - self.binsx[3])
self.fitLine_x.setData([0], [0])
# update yhist
self.freqy, self.binsy = np.histogram(self.ydata)
self.binscenters_y = np.array([0.5 * (self.binsy[i] + self.binsy[i + 1]) for i in range(len(self.binsy) - 1)])
self.freqy = self.freqy / np.max(self.freqy)
self.y_bar.setOpts(x=self.binscenters_y, height=self.freqy, width=self.binsy[2] - self.binsy[3])
self.fitLine_y.setData([0], [0])
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.fitButton.setText(_translate("MainWindow", "Fit Gaussian"))
self.start_stop.setText(_translate("MainWindow", "Start/Stop"))
self.clear.setText(_translate("MainWindow", "Clear data"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())