【问题标题】:Plotting in time using PyQtGraph and Pyserial使用 PyQtGraph 和 Pyserial 及时绘图
【发布时间】:2023-04-06 23:09:01
【问题描述】:

我正在尝试使用 pyqtgraph 进行实时绘图。我正在使用 Pyserial 从和 arduino 读取数据。我在使用 pyqtgraph 之前尝试了 matplotlib 库,但它没有给我需要绘制的速度。因此,在寻找另一种绘制实时数据的方法时,我遇到了 PyQtgraph。我阅读了文档和大量示例,并找到了以下两个示例:

pltting with sample interval

plotting using pyqt4

两者都是作为时间的函数绘制的,这是我需要做的。我已经修改了它们中的每一个以使用 Pyserial 从 Arduino 获取数据。问题是它仍然画得很慢。

这是我正在使用的代码(来自第二个链接):

class TimeAxisItem(pg.AxisItem):
  def __init__(self, *args, **kwargs):
    super(TimeAxisItem, self).__init__(*args, **kwargs)

  def tickStrings(self, values, scale, spacing):
    return [QTime().addMSecs(value).toString('mm:ss') for value in values]

class MyApplication(QtGui.QApplication):
  def __init__(self, *args, **kwargs):
    super(MyApplication, self).__init__(*args, **kwargs)
    self.t = QTime()
    self.t.start()

    self.data = deque(maxlen=20)

    self.win = pg.GraphicsWindow(title="Basic plotting examples")
    self.win.resize(1000,600)

    self.plot = self.win.addPlot(title='Timed data', axisItems={'bottom':  TimeAxisItem(orientation='bottom')})
    self.curve = self.plot.plot()

    self.tmr = QTimer()
    self.tmr.timeout.connect(self.update)
    self.tmr.start(100)

    print "Opening port"
    self.raw=serial.Serial("com4",9600)
    print "Port is open"


  def update(self):
    line = self.raw.read()
    ardString = map(ord, line)
    for number in ardString:
        numb = float(number/77.57)
        print numb
        self.data.append({'x': self.t.elapsed(), '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)

def main():
  app = MyApplication(sys.argv)
  sys.exit(app.exec_())

if __name__ == '__main__':
  main()

随着时间的推移,我该怎么做才能更快地绘制?我似乎在使用这段代码丢失了一些数据。

真的希望你能帮助我。

【问题讨论】:

  • 您可以使用Python Profiler 调查哪些函数使用的执行时间最多。我真的建议你试试看。

标签: python plot pyqt4 pyqtgraph


【解决方案1】:

在你的更新函数中,尝试调用

self.curve.clear()

在函数的最开始。

【讨论】:

  • 感谢您的回答。你的意思是在for循环之后?还是在它之前?
  • 尝试将其作为 for 循环的第一行。但是,查看您的脚本,我不确定这是挂断的地方。此刻我面前没有 Arduino,否则我会尝试排除故障。您确定您的更新功能在超时之前完成并尝试重新启动更新功能吗?
【解决方案2】:

让我觉得有点不对劲的是这里发生的事情的时间,而不是 pyqtgraph 的细节。您的更新方法是每个 QTimer 对象以 100 毫秒的间隔轮询串行端口,因此在 9600 波特时,您的端口可以生成 9600bps*.1sec = 960 字节。但是,您的 serial.Serial.read() 没有参数默认为 size = 1 per 这里:http://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read

所以看起来好像您在更新调用中每 100 毫秒只读取 1 个字节:

line = self.raw.read()

所以我的猜测是您应该在读取大小 1024 中添加更合理的内容:

line = self.raw.read(1024)

在 serial.Serial 实例化中指定超时:

self.raw=serial.Serial("com4",9600,timeout=0)

这样,读取不会阻塞,只会返回缓冲区中可用的全部数据量。

【讨论】:

    猜你喜欢
    • 2018-03-05
    • 1970-01-01
    • 2019-02-02
    • 2019-07-24
    • 2017-12-16
    • 2011-12-01
    • 2021-12-27
    • 2019-04-01
    • 2017-05-31
    相关资源
    最近更新 更多