setData in pyqtgraph GraphicsLayout not working

Viewed 1365

I'm trying to make several plots underneath in a pyqtgraph.GraphicsLayout and update them in real-time with .setData(x,y). Unfortunately, .setData always returns an OverflowError related to libshiboken:

RuntimeWarning: libshiboken: Overflow: Value [1000 2000 3000 4000] exceeds limits of type [signed] "int" (4bytes).

When I try exactly the same code without a pg.GraphicsLayout, it works fine. So the GraphicsLayout seems to have some effect on the PlotItem objects that I don't understand and find in the source code.

Here are my two minimal working examples:

Single plot:

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_()

Multi-plot that isn't working:

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 Answers

I just solved this same issue. The issue is that you are calling setData on p1 and p2, which are PlotItem objects. Instead, you need to call the setData method from PlotDataItem objects, which are returned when you call the plot method from the PlotItem objects (e.g. p1.plot(...))

For your multi-plot example, I believe it should look something like this:

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

You can see that it's not so much that the multi-plotting isn't working - it's that you defined p1 as a PlotItem (incorrect) in the multi-plot example, while you defined p1 as a PlotDataItem (correct) in the single plot example.

From the source code, the plot method of PlotItem creates a PlotDataItem. The constructor for the PlotDataItem takes the passed-along parameters and calls its own setData using the passed-along parameters. This is why rendering the graph using the first plot call works. However, when the first update is attempted through a manual setData call, the wrong method is actually being used here.

I am not sure how PlotItem even has a setData method exposed since it's not defined in the PlotItem class or any of its parents (I may just be lacking some Python knowledge here).

I opened an issue here: https://github.com/pyqtgraph/pyqtgraph/issues/1585

Related