pyqtgraph GraphicsLayout中的setData不起作用

Posted

技术标签:

【中文标题】pyqtgraph GraphicsLayout中的setData不起作用【英文标题】:setData in pyqtgraph GraphicsLayout not working 【发布时间】:2020-12-09 14:30:00 【问题描述】:

我正在尝试在 pyqtgraph.GraphicsLayout 下面绘制几个图,并使用 .setData(x,y) 实时更新它们。 不幸的是,.setData 总是返回与 libshiboken 相关的 OverflowError:

RuntimeWarning: libshiboken: Overflow: Value [1000 2000 3000 4000] 超出类型 [signed] "int" (4bytes) 的限制。

当我在没有 pg.GraphicsLayout 的情况下尝试完全相同的代码时,它可以正常工作。所以 GraphicsLayout 似乎对 PlotItem 对象有一些影响,我在源代码中看不懂。

这是我的两个最小的工作示例:

单一情节:

from pyqtgraph.Qt import QtGui,  QtCore
import pyqtgraph as pg
import numpy as np

pg.mkQApp()

pw = pg.GraphicsView()
pw.show()

# layout
l = pg.PlotItem()
pw.setCentralWidget(l)

# first data and plot
x = np.array([1000, 2000, 3000, 4000])
y1 = np.array([5*10**4, 6*10**4, 7*10**4, 8*10**4])

p1 = l.plot(x, y1)


# second data and setData
x = np.array([1000, 2000, 3000, 4000])
y1 = np.array([5*10**5, 6*10**5, 7*10**5, 8*10**5])

p1.setData(x,y1)



if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

不工作的多情节:

from pyqtgraph.Qt import QtGui,  QtCore
import pyqtgraph as pg
import numpy as np

pg.mkQApp()


pw = pg.GraphicsView()
pw.show()

# layout
l = pg.GraphicsLayout()
pw.setCentralWidget(l)

p1 = pg.PlotItem()
p2 = pg.PlotItem()
l.addItem(p1, row=0, col=0)
l.addItem(p2, row=1, col=0)


# first data and plot
x = np.array([1000, 2000, 3000, 4000])
y1 = np.array([5*10**4, 6*10**4, 7*10**4, 8*10**4])
y2 = np.array([0,5,7,9])

p1.plot(x, y1, pen=pen)
p2.plot(x, y2, pen=pen)

# second data and setData
x = np.array([1000, 2000, 3000, 4000])
y1 = np.array([5*10**4, 6*10**4, 7*10**4, 8*10**4])
y2 = np.array([0,5,7,9])

p1.setData(x,y1)
p2.setData(x,y2)


if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

【问题讨论】:

【参考方案1】:

我刚刚解决了同样的问题。问题是您在 p1 和 p2 上调用 setData,它们是 PlotItem 对象。相反,您需要从 PlotDataItem 对象调用 setData 方法,当您从 PlotItem 对象调用 plot 方法时会返回该方法(例如p1.plot(...)

对于您的多情节示例,我相信它应该看起来像这样:

p1_plotdataitem = p1.plot(x, y1, pen=pen)
...
p1_plotdataitem.setData(x, y1)

您可以看到,并不是说多重绘图不起作用 - 而是您在多重绘图示例中将 p1 定义为 PlotItem(不正确),而您将 p1 定义为 PlotDataItem(正确)单图示例。

从源码来看,PlotItem 的 plot 方法创建了一个 PlotDataItem。 PlotDataItem 的构造函数接受传递参数并使用传递参数调用它自己的 setData。这就是为什么使用第一个绘图调用来渲染图形的原因。但是,当通过手动 setData 调用尝试第一次更新时,这里实际上使用了错误的方法。

我不确定 PlotItem 是如何公开 setData 方法的,因为它没有在 PlotItem 类或其任何父类中定义(我可能只是在这里缺乏一些 Python 知识)。

我在这里打开了一个问题:https://github.com/pyqtgraph/pyqtgraph/issues/1585

【讨论】:

以上是关于pyqtgraph GraphicsLayout中的setData不起作用的主要内容,如果未能解决你的问题,请参考以下文章

pyqtgraph:为绘图中的线条添加图例

在 PlotWidget GUI 中运行实时 pyqtgraph

将 pyqtgraph 嵌入到 enaml 中......如何?

Pyqtgraph 中绘图的悬停工具

从 pyqtgraph.Qt 导入 QtGui 为 *

pyqtgraph:具有与 matplotlib drawstyle 类似功能的绘图