Улучшение скорости на графике - PullRequest
0 голосов
/ 13 февраля 2020

Я работаю над большим проектом, в котором мне нужно подготовить большое количество поступающих данных. Очень упрощенная версия моей программы такая (благодарность { ссылка }):

from PyQt5 import QtCore, QtGui, QtWidgets
import pyqtgraph as pg
import random
import time

number_of_plots = 6
number_of_caps = 48
show_plots = True

print(f"Number of plots: {number_of_plots}")
print(f"Number of caps: {number_of_caps}")


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.central_widget = QtWidgets.QStackedWidget()
        self.setCentralWidget(self.central_widget)
        self.login_widget = LoginWidget(self)
        self.login_widget.button.clicked.connect(self.plotter)
        self.central_widget.addWidget(self.login_widget)
        self.data = dict()
        self.curve = dict()

        self.points_kwargs = list()

        colors = ["#000000", "#e6194B", "#f58231", "#3cb44b", "#42d4f4", "#4363d8", "#911eb4", "#f032e6", "#bfef45" ,"#000075", "#e6beff", "#9A6324"]

        self.colors = colors * 4

        for color in self.colors:
            self.points_kwargs.append({"pen": None,
                                       "symbol": 'x',
                                       "symbolSize": 8,
                                       "symbolPen": color,
                                       "symbolBrush": color})

    def plotter(self):
        for j in range(number_of_plots):
            self.data[j] = list()
            self.curve[j] = list()
            for i in range(number_of_caps):
                self.data[j].append([i])
                self.curve[j].append(self.login_widget.plots[j].getPlotItem().plot(**self.points_kwargs[i]))

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.updater)
        self.timer.start(0)

    def updater(self):
        starttime = time.perf_counter()

        for key in self.data.keys():
            for i in range(number_of_caps):
                self.data[key][i].append(self.data[key][i][-1]+0.2*(0.5-random.random()))
                self.curve[key][i].setData(self.data[key][i])

        print(f"Plottime: {time.perf_counter() - starttime}")


class LoginWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(LoginWidget, self).__init__(parent)
        layout = QtWidgets.QHBoxLayout()
        self.button = QtWidgets.QPushButton('Start Plotting')
        layout.addWidget(self.button)

        self.plots = list()

        for i in range(number_of_plots):
            plot = pg.PlotWidget()
            self.plots.append(plot)
            layout.addWidget(plot)
            if not show_plots:
                plot.hide()

        self.plots[0].show()
        self.setLayout(layout)


if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

Цифры сверху показывают, как это масштабируется с графиками и заглавными буквами. 6 и 48, поэтому моя программа должна обрабатывать. При запуске программы время прорисовки составляет около 1 с / обновление. По крайней мере, на моей машине.

Чтобы упростить сложные вопросы: мне нужно как можно больше сократить время прорисовки. Фактор 2 может быть хорошо, 10 было бы очень хорошо.

Есть идеи? Спасибо за ваше время!

Лучший

1 Ответ

0 голосов
/ 19 февраля 2020

Я разобрался, как улучшить скорость в моем случае. Как уже упоминалось в моем комментарии, построение графиков становится намного быстрее, если вы уменьшаете масштаб. Масштабирование графиков фактически занимает большую часть времени, необходимого для построения графиков. В моем случае построение одной точки занимает ~ 2-4 мс, а изменение масштаба - 20-40 мс.

Я решил эту проблему, рассчитав максимальный диапазон x и y, который будет иметь мой график в конце, и установив диапазон до начала заговора. Это не поможет, если вы не знаете, сколько данных будет отображаться, но в этом случае функция autoPan может помочь. Я добавил в свой код следующее:

plot.setXRange(min_x,max_x, 0.05)
plot.setYRange(min_y,max_y, 0.05)
plot.hideButtons()

.hideButtons () отключает кнопку автоматического масштабирования в левом нижнем углу графика. Это препятствует тому, чтобы пользователь снова включил автоматическое увеличение. Пользователь по-прежнему может увеличивать и уменьшать масштаб, если ему нравится, но автоматического масштабирования c больше не происходит. Это не идеальное решение, но работает в моем случае.

...