我正在尝试使用PyQtgraph
绘制实时数据,我开始学习。我在这里阅读了很多帖子,例如:
并在互联网上搜索文档。我遇到的问题是绘制数据时绘图非常慢。这是因为,当数据来自串口时,我将它附加到列表中,然后我从该列表中取出并绘制它。因此,即使关闭了数据来源的设备,该图也会继续绘制。
这是我的代码:
class LivePlot(QtGui.QApplication):
def __init__(self, *args, **kwargs):
super(MyApplication, self).__init__(*args, **kwargs)
self.t = QTime()
self.t.start()
self.data = deque()
self.plot = self.win.addPlot(title='Timed data')
self.curve = self.plot.plot()
print "Opening port"
self.raw=serial.Serial("com4",115200)
print "Port is open"
self.tmr = QTimer()
self.tmr.timeout.connect(self.update)
self.tmr.start(100)
self.cnt = 0
def update(self):
line = self.raw.read()
ardString = map(ord, line)
for number in ardString:
numb = float(number/77.57)
self.cnt += 1
x = self.cnt/2
self.data.append({'x': x , 'y': numb})
x = [item['x'] for item in self.data]
y = [item['y'] for item in self.data]
self.curve.setData(x=x, y=y)
那么,如何在不将其附加到列表的情况下绘制数据呢?我是这个图书馆的新手,所以我很困惑。希望你能帮帮我。
我在代码中尝试了这个修改:
class LivePlot(QtGui.QApplication):
def __init__(self, *args, **kwargs):
super(MyApplication, self).__init__(*args, **kwargs)
self.cnt = 0
#Added this new lists
self.xData = []
self.yData = []
def update(self):
line = self.raw.read()
ardString = map(ord, line)
for number in ardString:
numb = float(number/77.57)
self.cnt += 1
x = self.cnt/2
self.data.append({'x': x , 'y': numb})
self.xData.append(x)
self.yData.append(numb)
self.curve.setData(x=self.xData, y=self.yData)
但我遇到了同样的问题。
答案 0 :(得分:0)
对于您从设备中读取的每个号码,您将从头开始重新创建x
和y
数组。这意味着,如果您有1000个数据点,您将通过1000个元素的列表行走1000次,这相当于一百万步。可以想象,这并不能很好地扩展。您的执行时间会增加n^2
因子,其中n
是您衡量的点数。 Google '计算复杂性' 或&#O;大O符号' 并阅读相关内容。
附加到Python列表(或deque)的速度很快,所花费的时间并不取决于列表中元素的数量(请注意,为了附加到Numpy数组,这不为True )。如果您创建self.xData
和self.yData
列表然后将数据附加到这些列表,则可以摆脱内部循环:
def update(self):
line = self.raw.read()
ardString = map(ord, line)
for number in ardString:
numb = float(number/77.57)
self.cnt += 1
x = self.cnt/2
# Appending goes in constant time
self.data.append({'x': x , 'y': numb})
self.xData.append(x) # self.xData should be a list or deque
self.yData.append(x) # self.yData should be a list or deque
# Drawing the plot is now only performed once per update
self.curve.setData(x=x, y=y)
此外,重新绘制setData
中发生的绘图是一项昂贵的操作,您可以在读取每个数据点后执行此操作。更好的解决方案是每次更新只更新一次。请参阅上面的示例。这仍然是十秒钟(至少,如果您的绘图可以跟上数据)。
作为最后一句话,与硬件的沟通是一个棘手的主题,你的第一次尝试无疑将是不稳定的,充满了错误。如果你这是一个爱好项目,那么这是一个很好的学习机会。如果您在专业环境中这样做,请尝试找一位导师。