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

On Thu, Oct 13, 2022 at 11:38 AM Ognyan Moore <[email protected]>
wrote:

> I just want to add that the real advantage of QThreads (when talking about
> pyqtgraph) is that you can do CPU-heavy processing in a non-GUI thread, so
> the GUI doesn't (temporarily) freeze/lag as number crunching is happening.
> I use a QThread to do some log-based calculations here, and I use the
> Signal/Slot mechanism to relay the information I want pyqtgraph to plot:
>
>
> https://github.com/j9ac9k/barney/blob/main/src/barney/controllers/SubPlotControllers/SpectrogramController.py
>
> The calculation is based on an interactive element in the GUI, so when I
> first had this setup, when the user would adjust a linear region item, the
> GUI would temporarily freeze while I was doing a log calculation on a
> ~500x2000 numpy array.  Moving to a QThread meant the resulting plot was a
> little late to update vs. the others, but the GUI didn't lag or freeze.
>
> Adding QThreads does add complexity, and I hope to roll an example in the
> pyqtgraph example library on how to do this; but the general advice is
> don't go down that route unless you have an actual need.
>
> On Thu, Oct 13, 2022 at 5:27 AM Edmondo Giovannozzi <
> [email protected]> wrote:
>
>> Personally I want speed in a GUI application. So I always use pyqtgraph,
>> even sometime modifying the pyqtgraph source in order to have what I need.
>> It is well written, so modifying it is easy.
>> If a calculation is slowing me down I can transform it in a Fortran or C
>> code and use ctypes to link it to Python.
>>
>> Il Mer 12 Ott 2022, 23:36 Martin Chase <[email protected]> ha
>> scritto:
>>
>>> Heya,
>>>
>>> There isn't any performance difference between QThreads and python
>>> Threads; that's mostly a difference of how you want to integrate with Qt
>>> (QThreads fit into the rest of the Qt lifecycle better). Otherwise, the
>>> question that I ask to determine thread v. multiprocess is: will my worker
>>> mostly be sitting around waiting? If that's the case (e.g. waiting on i/o),
>>> then using a thread is great. Otherwise, if the worker needs to do a bunch
>>> of heavy work before the data is ready to display (e.g. it's the output of
>>> a difficult analysis), put that work on a different core.
>>>
>>> Only matplotlib is as good at plotting as matplotlib; it's the best
>>> python plotting library. If that's your minimum bar, I agree that you'll be
>>> writing everything yourself from scratch. PyQtGraph is built for
>>> performance, though, so you're going to need the best of both libraries if
>>> that's your use-case.
>>>
>>> Good luck,
>>>  - Martin
>>>
>>> --
>>> 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 [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/pyqtgraph/CAD_p8v3668bj82zYmWi%2Bns_DfHK4JHAbwvb8oSmitU-RkArFpA%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/pyqtgraph/CAD_p8v3668bj82zYmWi%2Bns_DfHK4JHAbwvb8oSmitU-RkArFpA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
>> 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 [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/pyqtgraph/CACwj3kUb7toyty5sAE4vP6mV3YsRxQ%2BjGMxRh-hecLFvy9w2DA%40mail.gmail.com
>> <https://groups.google.com/d/msgid/pyqtgraph/CACwj3kUb7toyty5sAE4vP6mV3YsRxQ%2BjGMxRh-hecLFvy9w2DA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pyqtgraph/CA%2BnduTFi5wBSuqB9_g43HC_yYhwVSunEf7qz4Km4fjUMLnLbXw%40mail.gmail.com
> <https://groups.google.com/d/msgid/pyqtgraph/CA%2BnduTFi5wBSuqB9_g43HC_yYhwVSunEf7qz4Km4fjUMLnLbXw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pyqtgraph/CAMZ%2BuanqZVBv18-Ow7cAH%3DdaKc7BbzYTWZOw_cMwGcbfV5U2TQ%40mail.gmail.com.

Reply via email to