Graph is freezing

2,285 views
Skip to first unread message

Thomas Grübler

unread,
Nov 11, 2016, 12:45:55 PM11/11/16
to pyqtgraph

Hello,

I write an application that displays something like an oscilloscope with real time values.

Sometimes, it just stops updating the graph. Just when I change the window size, it shows the new curve, but then just one frame.

The major problem is, I would like to write a bug report, but I do not get any error message in PyCharm. When using the debugger, all objects/pointers etc are present.
Even worse, I do not have a real way to reproduce the behavior. Sometimes it is easy, sometimes it is not possible.
For reproducing, I stop updating my curve entries for a minute, and then start again.
My software is normally updating the curve entries every 0.01s.

Any idea, how to produce an error message if it is freezing to find the problem?

The freeze occurs using Python 3.4 (Anaconda) and with both PyQtGraph 0.9 and 0.10.

Thanks very much!
Thomas

Luke Campagnola

unread,
Nov 12, 2016, 11:14:37 AM11/12/16
to pyqt...@googlegroups.com
There are many reasons this could be happening. The easiest way for us to help is if you can provide a minimal working example.
As a start, I would check to see whether the problem persists if you run the script without pycharm.

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/6e624762-ebb4-4452-9957-641d108b4716%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Luke Campagnola

unread,
Nov 12, 2016, 11:20:09 AM11/12/16
to pyqt...@googlegroups.com
One that I have seen recently matching your symptoms is that if you plot values that cover a very large range, this can result in floating-point errors in the GraphicsView bounds checking, which can then cause failures to update (because the view doesn't think the plot is visible).

Thomas Grübler

unread,
Nov 14, 2016, 7:43:04 AM11/14/16
to pyqtgraph
i would like to show you a minimum working example, but until now, i did not manage it. somehow minimum examples work :D.

Am Samstag, 12. November 2016 17:20:09 UTC+1 schrieb Luke Campagnola:
One that I have seen recently matching your symptoms is that if you plot values that cover a very large range, this can result in floating-point errors in the GraphicsView bounds checking, which can then cause failures to update (because the view doesn't think the plot is visible).
On Sat, Nov 12, 2016 at 8:14 AM, Luke Campagnola <luke.ca...@gmail.com> wrote:
There are many reasons this could be happening. The easiest way for us to help is if you can provide a minimal working example.
As a start, I would check to see whether the problem persists if you run the script without pycharm.
On Fri, Nov 11, 2016 at 9:45 AM, Thomas Grübler <thomas....@gmail.com> wrote:

Hello,

I write an application that displays something like an oscilloscope with real time values.

Sometimes, it just stops updating the graph. Just when I change the window size, it shows the new curve, but then just one frame.

The major problem is, I would like to write a bug report, but I do not get any error message in PyCharm. When using the debugger, all objects/pointers etc are present.
Even worse, I do not have a real way to reproduce the behavior. Sometimes it is easy, sometimes it is not possible.
For reproducing, I stop updating my curve entries for a minute, and then start again.
My software is normally updating the curve entries every 0.01s.

Any idea, how to produce an error message if it is freezing to find the problem?

The freeze occurs using Python 3.4 (Anaconda) and with both PyQtGraph 0.9 and 0.10.

Thanks very much!
Thomas

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+...@googlegroups.com.

Thomas Grübler

unread,
Nov 14, 2016, 10:06:41 AM11/14/16
to pyqtgraph
Hi Luke, do you have any idea how to check for arrays resulting in floating-point errors?

Tim Williams

unread,
Dec 1, 2016, 3:16:23 PM12/1/16
to pyqtgraph
Hi.

I'm having a similar problem. I have an application that uses gstreamer to stream video, and I'm displaying the ImageItem to a GraphicsLayoutWidget. I have another GraphicsLayoutWidget that has a  HistogramLutItem. Sometimes the ViewBox containing the ImageItem freezes. It doesn't even respond to mouse events. The histogram is still live, and I can see from that that the image data is being updated. If I just resize my main window, the ViewBox refreshes to the last captured frame, but is still not live.  Disconnecting my camera and reconnection doesn't fix this. I have to exit the application and restart.

This problem seems to crop up randomly, but it happens often enough that I need to track this down, but I don't know how. I'm fairly new to pyqtgraph an Qt in general.

I'm using Python 3.4, pyqtgraph 0.10.0, and PyQt5.


Thanks for any help.
Tim
Message has been deleted

Tim Williams

unread,
Dec 1, 2016, 4:44:35 PM12/1/16
to pyqtgraph
Update on my earlier post:

It seems that the ViewBox is receiving events, since I do get the context menu, and I can scroll/zoom using the mouse. I just can't see the result of this until I resize the MainWindow.

Luke Campagnola

unread,
Dec 7, 2016, 1:47:46 AM12/7/16
to pyqt...@googlegroups.com
Sometimes the only way to get a minimum working example is to strip out chunks of your application one piece at a time until you have nothing left but the bug. 
This may be a lot of work if you have a large application, but it's more or less guaranteed to show you where the bug is.

To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/29c098b7-e2e6-4d38-a3a0-9c72b49cd9f9%40googlegroups.com.

Patrick

unread,
Nov 16, 2017, 9:27:18 AM11/16/17
to pyqtgraph
I have a similar issue with an application I am putting together. I have a minimum working example:

from pyqtgraph.Qt import QtCore, QtGui
from threading import Thread, Event
import time, random
import numpy as np
import pyqtgraph as pg

# Build a simple GraphicaLayout containing an image plot
app = QtGui.QApplication([])
win = pg.GraphicsLayoutWidget()
win.setWindowTitle('Test pyqtgraph paint halt')
win.show()
plot = win.addPlot()
spectrum = plot.plot()
plot.enableAutoRange(pg.ViewBox.XYAxes)

# Routine to acquire and serve data
# This might be a camera driver, notifying when a new frame is available
def generate_data(threadkill):
    while not threadkill.is_set():
        width = 1600
        data = np.zeros(width)
        data += np.cos(np.arange(0, 10*np.pi, 10*np.pi/width) - 9*time.monotonic())
        data += np.cos(np.arange(0, 4*np.pi, 4*np.pi/width) + 4*time.monotonic())
        update_data(data)
        # Can sleep for a bit, but doesn't make a difference to whether display will stop or not
        # Although perhaps sleep 0.01 seems to make it stop faster?
        time.sleep(0.01)
threadkill = Event()
thread = Thread(target=generate_data, args=(threadkill,))
app.aboutToQuit.connect(lambda event=threadkill: event.set())
thread.start()

def update_data(data):
    spectrum.setData(data)

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

My program gets served images/spectra from a (non-Qt python) camera interface, which is where the threading routine would live. I would subscribe the update_data method to receive callbacks when new data is ready. Sometimes it will run for several minutes (as will this example) but inevitably the paint events of the plot will stop. The plot menus still appear and interaction is still possible, but paint events don't occur until forced by a window resize or similar.

It could be my imagination, but running the generate_data with the 0.01 s sleep time seems to trigger the issue faster than no sleep.

Is this just that updating the plot data (Qt application) from a different (non-Qt) thread is a bad idea?

Not sure if related, as this error message does not occur on the freeze and I don't see any error messages in my application, but I noticed a image version of the example  above also produced this:
Traceback (most recent call last):
  File "/home/patrick/Documents/pyqtgraph-test/pyqtgraph/graphicsItems/ImageItem.py", line 420, in paint
    p.drawImage(QtCore.QRectF(0,0,*shape), self.qimage)
TypeError: arguments did not match any overloaded call:
  drawImage(self, QRectF, QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.AutoColor): argument 2 has unexpected type 'NoneType'
  drawImage(self, QRect, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.AutoColor): argument 1 has unexpected type 'QRectF'
  drawImage(self, Union[QPointF, QPoint], QImage, QRectF, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.AutoColor): argument 1 has unexpected type 'QRectF'
  drawImage(self, QPoint, QImage, QRect, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.AutoColor): argument 1 has unexpected type 'QRectF'
  drawImage(self, QRectF, QImage): argument 2 has unexpected type 'NoneType'
  drawImage(self, QRect, QImage): argument 1 has unexpected type 'QRectF'
  drawImage(self, Union[QPointF, QPoint], QImage): argument 1 has unexpected type 'QRectF'
  drawImage(self, QPoint, QImage): argument 1 has unexpected type 'QRectF'
  drawImage(self, int, int, QImage, sx: int = 0, sy: int = 0, sw: int = -1, sh: int = -1, flags: Union[Qt.ImageConversionFlags, Qt.ImageConversionFlag] = Qt.AutoColor): argument 1 has unexpected type 'QRectF'


Patrick

unread,
Nov 16, 2017, 9:46:55 PM11/16/17
to pyqtgraph
So it looks like updating the plot data from an outside thread is just a Bad Idea. Here is the same example wrapping the callback in a Qt Signal/Slot pattern. Note that signals need to be defined inside a QObject, hence the explicit instantiation of a GraphicsLayoutWidget. So far it seems to work as expected.

import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal, pyqtSlot
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
from pyqtgraph import GraphicsLayoutWidget
from threading import Thread, Event
import time

# Routine to acquire and serve data
# This might be a camera driver, notifying when a new frame is available
def generate_data(callback, threadkill):
    while not threadkill.is_set():
        width = 1600
        data = np.zeros(width)
        data += np.cos(np.arange(0, 10*np.pi, 10*np.pi/width) - 9*time.monotonic())
        data += np.cos(np.arange(0, 4*np.pi, 4*np.pi/width) + 4*time.monotonic())
        callback(data)
        time.sleep(0.01)

class PyQtGraphTest(GraphicsLayoutWidget):

    # Signal to indicate new data acquisition
    # Note: signals need to be defined inside a QObject class/subclass
    data_acquired = pyqtSignal(np.ndarray)

    def __init__(self):
    
        super().__init__()

        self.setWindowTitle('Test pyqtgraph paint signals')
        self.resize(640, 400)
        self.plot = self.addPlot()
        self.spectrum = self.plot.plot()
        self.plot.enableAutoRange(pg.ViewBox.XYAxes)

        # Connect the signal
        self.data_acquired.connect(self.update_data)

        # Make and start the background thread to acquire data
        # Pass it the signal.emit as the callback function
        self.threadkill = Event()
        self.thread = Thread(target=generate_data, args=(self.data_acquired.emit, self.threadkill))
        self.thread.start()

    # Kill our data acquisition thread when shutting down
    def closeEvent(self, close_event):
        self.threadkill.set()

    # Slot to receive acquired data and update plot
    @pyqtSlot(np.ndarray)
    def update_data(self, data):
        self.spectrum.setData(data)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = PyQtGraphTest()
    window.show()
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        sys.exit(app.exec_())



Luke Campagnola

unread,
Nov 17, 2017, 9:34:30 AM11/17/17
to pyqt...@googlegroups.com
More generally, you should not directly interact with any part of the GUI from outside the main thread.
I remember being surprised by this when I first started working with Qt, but found that it was true of every other GUI toolkit as well.

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyqtgraph+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages