pyqtgraph GraphicsLayout 中的 setData 不起作用
setData in pyqtgraph GraphicsLayout not working
我正在尝试在 pyqtgraph.GraphicsLayout 中绘制多个图并使用 .setData(x,y) 实时更新它们。
不幸的是,.setData 总是 returns 与 libshiboken 相关的 OverflowError:
运行时警告:libshiboken:溢出:值 [1000 2000 3000 4000] 超出类型 [signed]“int”(4 字节)的限制。
当我尝试没有 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_()
我刚刚解决了同样的问题。问题是您在 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。这就是使用第一个 plot 调用渲染图形的原因。但是,当通过手动 setData 调用尝试第一次更新时,实际上使用了错误的方法。
我不确定 PlotItem 是如何公开 setData 方法的,因为它没有在 PlotItem class 或其任何父项中定义(我可能只是缺少一些 Python 此处的知识)。
我在这里开了一个问题:https://github.com/pyqtgraph/pyqtgraph/issues/1585
我正在尝试在 pyqtgraph.GraphicsLayout 中绘制多个图并使用 .setData(x,y) 实时更新它们。 不幸的是,.setData 总是 returns 与 libshiboken 相关的 OverflowError:
运行时警告:libshiboken:溢出:值 [1000 2000 3000 4000] 超出类型 [signed]“int”(4 字节)的限制。
当我尝试没有 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_()
我刚刚解决了同样的问题。问题是您在 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。这就是使用第一个 plot 调用渲染图形的原因。但是,当通过手动 setData 调用尝试第一次更新时,实际上使用了错误的方法。
我不确定 PlotItem 是如何公开 setData 方法的,因为它没有在 PlotItem class 或其任何父项中定义(我可能只是缺少一些 Python 此处的知识)。
我在这里开了一个问题:https://github.com/pyqtgraph/pyqtgraph/issues/1585