Hi everyone,
I know I am late to the party, but I wanted to share my experience using both pyqtgraph and matplotlib embedded in a PyQt application and the use of QtThreads for various tasks. It is actually four different applications, each one is a status screen with live updating images and plots based on telemetry inputs from instrumentation, but the same approach is used in each status screen.
First of all, I used PyQt5 as it was a much easier environment in which to work than Qt, which is C++ :-). I used Qt Creator and Designer to develop the overall application display windows. For real-time image display, I used two different approaches:
1) I created a generic image display widget using pyqtgraph's GraphicsLayoutWidget, subclassing it to add methods to update the image data and add an overlay grid.
2) I created a generic surface plot widget using pyqtgraph's GLViewWidget, subclassing it to add methods for updating the display data and for changing the amplitude scale of the surface plot.
The generic image display widget was used to display images of varying sizes, all the way up to a 2k x 2k image updating at 10 Hz. On a couple of the images I also used pyqtgraph's HistogramLUTWidget to allow for real-time adjustment of the display to maximize contrast based on the current image conditions (autoscaling is not always your friend in this regard).
I used matplotlib for graphs and plots, as they all had fairly slow update requirements and matplotlib was fast enough to handle the load. If matplotlib had not been fast enough I would have used pyqtgraph for the plots. I developed a few simple QtWidgets with matplotlib plots embedded in them. All of the image display and plotting was done by the main Qt application's event loop, as that way Qt handles all of the multiple graphics tasks that were happening simultaneously.
I used QThreads to handle the receipt of the telemetry data, which came from several socket subscriptions to the various data sources on other servers. The nice thing about the QThreads was that it allowed me to separate the receipt of new data from the display application. Moreover, QThreads support the Qt infrastructure, so I was able to use signals and slots to communicate the new data and values directly to the Qt widgets that displayed them. Basically I had one QThread per data source, with the run method subscribing to the data source, then repeatedly calling a data acquisition method until a shutdown command occurs, and finally, unsubscribing from the data source. The data acquisition method performs blocking reads on the data queue associated with that thread, performs minimal preprocessing to unpack the data and then calls the Qt signal methods to pass the data to the respective widgets. This design works surprisingly well and is able to support a high volume of image data and simultaneous plots updating in real time.
Hope this is helpful.
Regards,
Erik