Discussion:
use guiqwt for realtime data
John
2012-01-07 09:38:00 UTC
Permalink
Hi,

I am new to the guiqwt toolkit but I am trying to use it for realtime plotting.
The data stream comes from a low speed source @ about 50kbits/sec.
But I don't seem to get it fully fluent on the screen.
If I set a timer to update my plot curve (set_data) every 0.1 or 0.05 sec
I don't see any improvement so I think the plot speed is at it's maximum.
I set the whole data again every time I call setdata() (!?).
And I set the x-axis scale because the timelime (in seconds) is changed.
Is there a better way to do this ?
Every time just a little bit of the whole data array (about 8 sec) is changed.
Is there a method in plot.curve that sets data and merges this with the old?
Like matlibplot bitblt function.

greets,
Marc
Carlos Pascual
2012-01-09 08:23:58 UTC
Permalink
I have a similar problem, and my approach (I do it with PyQwt, but I guess it
can be done with guiqwt as well) is to reduce the nuber of full replots by
minimizing the changes to the x-axis scale.

My general algorithm is:

1-set the x-axis scale to xmin,xmax
2-call setdata() with the latest xarray,yarray
3-if max(xarray)>xmax: set the x-axis scale to newxmin,newxmax where
newxmin=xmin-delta and newxmax=xmax-delta, where delta=(xmax-xmin)*0.3

Note that the step 3 is only done from time to time since it makes room for
many data updates before having to be repeated again.

Apart from that, when dealing with very large sets of data (which take a lot
of CPU to replot) AND for which the x-axis is the time AND which I can assume
they are more or less smooth, I use another "trick". I schedule periodic
replots of the data, and I dynamically adjust the period of the replot to that
of the time represented by 1 pixel in the screen (so I do not bother to replot
unless a new point is at least 1 pixel away from the previous points).

The advantage of the last approach is that for a steady flow of real data, the
CPU usage is fairly constant and low regardless of the zoom level that the
user chooses (because if the user zooms-out more points are replotted but a
longer replot period is used)

I hope this helps.
Post by John
Hi,
I am new to the guiqwt toolkit but I am trying to use it for realtime
50kbits/sec. But I don't seem to get it fully fluent on the screen.
If I set a timer to update my plot curve (set_data) every 0.1 or 0.05 sec
I don't see any improvement so I think the plot speed is at it's maximum.
I set the whole data again every time I call setdata() (!?).
And I set the x-axis scale because the timelime (in seconds) is changed.
Is there a better way to do this ?
Every time just a little bit of the whole data array (about 8 sec) is
changed. Is there a method in plot.curve that sets data and merges this
with the old? Like matlibplot bitblt function.
greets,
Marc
--
+----------------------------------------------------+
Carlos Pascual Izarra
Scientific Software Coordinator
Computing Division
Cells / Alba Synchrotron [http:/www.cells.es]
Carretera BP 1413 de Cerdanyola-Sant Cugat, Km. 3.3
E-08290 Cerdanyola del Valles (Barcelona), Spain
E-mail: cpascual-***@public.gmane.org
Phone: +34 93 592 4428
+----------------------------------------------------+
john marc
2012-01-10 19:25:10 UTC
Permalink
Post by Carlos Pascual
I have a similar problem, and my approach (I do it with PyQwt, but I guess it
can be done with guiqwt as well) is to reduce the nuber of full replots by
minimizing the changes to the x-axis scale.
1-set the x-axis scale to xmin,xmax
2-call setdata() with the latest xarray,yarray
3-if max(xarray)>xmax: set the x-axis scale to newxmin,newxmax where
newxmin=xmin-delta and newxmax=xmax-delta, where delta=(xmax-xmin)*0.3
Note that the step 3 is only done from time to time since it makes room for
many data updates before having to be repeated again.
Apart from that, when dealing with very large sets of data (which take a lot
of CPU to replot) AND for which the x-axis is the time AND which I can assume
they are more or less smooth, I use another "trick". I schedule periodic
replots of the data, and I dynamically adjust the period of the replot to that
of the time represented by 1 pixel in the screen (so I do not bother to replot
unless a new point is at least 1 pixel away from the previous points).
The advantage of the last approach is that for a steady flow of real data, the
CPU usage is fairly constant and low regardless of the zoom level that the
user chooses (because if the user zooms-out more points are replotted but a
longer replot period is used)
I hope this helps.
Thanks for the reply.
What I understand is that it creates a space of 30% at the right(beginning),
of the plot, that will be filled in time.
And when the space is filled the x-axis scale must be set again.

I am going to check if this looks OK on the screen.
It would be nice though if QWT had some kind of bitblt function so the videocard
takes care of moving the plot to the left and it only has to draw the new data.
Carlos Pascual
2012-01-11 08:28:46 UTC
Permalink
Post by john marc
Post by Carlos Pascual
I have a similar problem, and my approach (I do it with PyQwt, but I
guess it can be done with guiqwt as well) is to reduce the nuber of full
replots by minimizing the changes to the x-axis scale.
1-set the x-axis scale to xmin,xmax
2-call setdata() with the latest xarray,yarray
3-if max(xarray)>xmax: set the x-axis scale to newxmin,newxmax where
newxmin=xmin-delta and newxmax=xmax-delta, where delta=(xmax-xmin)*0.3
Note that the step 3 is only done from time to time since it makes room
for many data updates before having to be repeated again.
Apart from that, when dealing with very large sets of data (which take a
lot of CPU to replot) AND for which the x-axis is the time AND which I
can assume they are more or less smooth, I use another "trick". I
schedule periodic replots of the data, and I dynamically adjust the
period of the replot to that of the time represented by 1 pixel in the
screen (so I do not bother to replot unless a new point is at least 1
pixel away from the previous points).
The advantage of the last approach is that for a steady flow of real
data, the CPU usage is fairly constant and low regardless of the zoom
level that the user chooses (because if the user zooms-out more points
are replotted but a longer replot period is used)
I hope this helps.
Thanks for the reply.
What I understand is that it creates a space of 30% at the
right(beginning), of the plot, that will be filled in time.
And when the space is filled the x-axis scale must be set again.
Exactly. The result looks a lot like the way many digital oscilloscopes
display their signals: instead of scrolling smoothly, the scroll is done in
steps of 30% of the full time scale.
To my application, it also has another advantage: it is easier for the user to
read the x,y value of a given point because the point is not "moving" all the
time.
Post by john marc
I am going to check if this looks OK on the screen.
It would be nice though if QWT had some kind of bitblt function so the
videocard takes care of moving the plot to the left and it only has to
draw the new data.
I agree, and note that I am not saying that it doesn't have one (I don't know
all of Qwt API). Perhaps you could ask at the (C++) Qwt list as well (guiqwt
is "just" a layer over PyQwt, after all):
https://lists.sourceforge.net/lists/listinfo/qwt-interest

Cheers,
--
+----------------------------------------------------+
Carlos Pascual Izarra
Scientific Software Coordinator
Computing Division
Cells / Alba Synchrotron [http:/www.cells.es]
Carretera BP 1413 de Cerdanyola-Sant Cugat, Km. 3.3
E-08290 Cerdanyola del Valles (Barcelona), Spain
E-mail: cpascual-***@public.gmane.org
Phone: +34 93 592 4428
+----------------------------------------------------+
Uwe Rathmann
2012-01-11 09:17:39 UTC
Permalink
Post by Carlos Pascual
I am going to check if this looks OK on the screen. It would be nice
though if QWT had some kind of bitblt function so the videocard takes
care of moving the plot to the left and it only has to draw the new
data.
This is not supported by the Qt graphics pipeline - a limitation Qwt or
your code can work around.
Post by Carlos Pascual
I agree, and note that I am not saying that it doesn't have one (I don't
know all of Qwt API). Perhaps you could ask at the (C++) Qwt list as
https://lists.sourceforge.net/lists/listinfo/qwt-interest
Qwt offers the feature to paint incrementally, what is also "against" the
philosophy of the Qt. The implementation in Qwt varies depending on the
platform and its capabilities. F.e. on X11 you can paint outside of paint
events, what makes its the fastest environment for this use case. ( Qwt
includes an oscilloscope example, that shows what is possible on your
system. )

Beside trying to improve the performance of rendering you could also try
to reduce what has to be painted. Qwt 6 offers an implementation of the
Douglas Peucker algorithm, that could be used to sort out points.

Unfortunately there are no python bindings for Qwt 6 yet and you might
have to port the code yourself. And as I don't know guiqwt myself I don't
know how much of the C++ API is available there.

HTH,
Uwe

Loading...