绘图速度改进
Speed improvements on plotting
我正在做一个更大的项目,我需要绘制大量的实时数据。我的程序的一个非常简化的版本是这个(感谢 ):
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 会很好。
有什么想法吗?感谢您的宝贵时间!
最佳
我想出了如何在我的案例中提高速度。
正如我在评论中提到的,如果缩小,绘图会变得更快。绘图的重新缩放实际上占用了绘图所需的大部分时间。在我的例子中,绘制一个点需要大约 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() 禁用绘图左下角的自动缩放按钮。这可以防止用户重新启用自动缩放。用户仍然可以根据需要放大和缩小,但自动重新缩放不再发生。这不是一个完美的解决方案,但适用于我的情况。
我正在做一个更大的项目,我需要绘制大量的实时数据。我的程序的一个非常简化的版本是这个(感谢
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 会很好。
有什么想法吗?感谢您的宝贵时间!
最佳
我想出了如何在我的案例中提高速度。 正如我在评论中提到的,如果缩小,绘图会变得更快。绘图的重新缩放实际上占用了绘图所需的大部分时间。在我的例子中,绘制一个点需要大约 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() 禁用绘图左下角的自动缩放按钮。这可以防止用户重新启用自动缩放。用户仍然可以根据需要放大和缩小,但自动重新缩放不再发生。这不是一个完美的解决方案,但适用于我的情况。