Discussion:
slow performance when refreshing the plot widget in a ImageDialog window
Cristina Cocho
2011-11-07 10:20:08 UTC
Permalink
Hi

We are carrying out some tests in order to check the feasibility to
develop real time applications with Guiqwt. We have already managed to
do a simple application in C++ which executes two python threads
(using Python/C API): the main thread which generates the GUI
application (in our case an ImageDialog window) and a secondary thread
that produces and gives periodically new data to the main thread (data
that should be plotted).

When measuring the overall time needed to refresh the data (the
ImagePlot widget of the ImageDialog window) we realized there is a
huge amount of time consumed when doing the conversion:

image = make.image(data)

Being data a numpy array.

We could not find another way to add images/data to the ImageDialog
window than the shown in the examples:

#create data as a numpy array:
data = np.ndarray((x,y),buffer=buf,dtype=float)

#convert our numpy based data:
image = make.image(data)

#get the ImagePlot “widget” from our ImageDialog window
plot = win.get_plot()

#where win = ImageDialog(edit=False, toolbar=True, wintitle="Cross
sections test",

#
options=dict(show_xsection=True, show_ysection=True))

#add the new image to our plot:
plot.add_item(image)

#finally show the window:
win.show()

We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use make.image(data).

Moreover, is it possible to manipulate and add data to ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating numpy
arrays, converting them into “image items” and adding the result to
the Guiqwt window?

Thank you in advance,

Cristina
Carlos Pascual
2011-11-07 12:16:19 UTC
Permalink
you may want to try with image.set_data()

I use it in my application for something similar to your needs. See
TaurusBaseImageItem.handleEvent() in :

http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revision=17889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use make.image(data).
Moreover, is it possible to manipulate and add data to ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating numpy
arrays, converting them into “image items” and adding the result to
the Guiqwt window?
--
+----------------------------------------------------+
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
+----------------------------------------------------+
Cristina Cocho
2011-11-07 15:47:12 UTC
Permalink
Hi Carlos,

Thank you very much for your answer. As suggested, I have tested the
function set_data() but, even though we save a lot of time because we
only execute once the function make.image() (in order to get the plot
item where to apply set_data()), the time consumed when executing
set_data() periodically is big enough to make our real plot
application not feasible.

Thank you very much,

Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revision=17889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use make.image(data).
Moreover, is it possible to manipulate and add data to  ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating numpy
arrays, converting them into “image items” and adding the result to
the Guiqwt window?
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
Carlos Pascual
2011-11-07 19:01:10 UTC
Permalink
Just out of curiosity, what are your requirements?

With the attached code I plot images made of floats with 2048x2048 at ~3Hz
(~10Hz if I use dtype=uint16) in a pretty old machine.

Naturally, speed decreases if the image size is bigger.

For me, this is usually enough, since it is close to the human perception
limit.

Cheers,

Carlos
Post by Cristina Cocho
Hi Carlos,
Thank you very much for your answer. As suggested, I have tested the
function set_data() but, even though we save a lot of time because we
only execute once the function make.image() (in order to get the plot
item where to apply set_data()), the time consumed when executing
set_data() periodically is big enough to make our real plot
application not feasible.
Thank you very much,
Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revision=17
889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use make.image(data).
Moreover, is it possible to manipulate and add data to ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating numpy
arrays, converting them into “image items” and adding the result to
the Guiqwt window?
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
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
+----------------------------------------------------+
Cristina Cocho
2011-11-08 14:58:27 UTC
Permalink
Hi Carlos,

My requirements are plotting 3096 x 6192 float images at 2Hz (ideal
case). Up to now, I only got close to this frequency when using images
of 1000 x 1000. I have been working with your example and, as you
said, I got the same time results. However, the plotting/loading time
considerably increases when using other types of numpy arrays. In my
case the numpy array is defined as follows:

data = np.ndarray((x,y),buffer=buf,dtype=float)

where the parameters x, y and buf are calculated in the C++ script. In
particular the parameter buf is obtained with the function (from
Python/C API):

PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)

In my opinion the bottleneck appears when the data is not generated
within the Python script. That is, if my buffer is a numpy array with
random data generated in the python script (as in your example) I
get the same time performance but when passing the data from one
script (C++) to the other (Python) ,even though the array size is the
same, the time necessary to execute img.set_data(array) is increased.

Thank you for your help,

Cristina
Post by Carlos Pascual
Just out of curiosity, what are your requirements?
With the attached code I plot images made of floats with 2048x2048 at ~3Hz
(~10Hz if I use dtype=uint16) in a pretty old machine.
Naturally, speed decreases  if the image size is bigger.
For me, this is usually enough, since it is close to the human perception
limit.
Cheers,
Carlos
Post by Cristina Cocho
Hi Carlos,
Thank you very much for your answer. As suggested, I have tested the
function set_data() but, even though we save a lot of time because we
only execute once the function make.image() (in order to get the plot
item where to apply set_data()), the time consumed when executing
set_data() periodically is big enough to make our real plot
application not feasible.
Thank you very much,
Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revision=17
889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use make.image(data).
Moreover, is it possible to manipulate and add data to  ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating numpy
arrays, converting them into “image items” and adding the result to
the Guiqwt window?
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
 swapimages.py
< 1 000AfficherTélécharger
Carlos Pascual
2011-11-08 15:34:41 UTC
Permalink
Hi,
Here we also get images from a C++ thread, and we use the same way for
transferring the data by refferencing the buffer. From what you describe, it
looks like you are doing it well (not copying the data unnecessarily), so I
don't understand why it is slower.

I am out of ideas. Just double-check that your code is not copying the data
somewhere.

If the bottleneck cannot be solved, maybe you can have a look at using the C++
Qwt library directly.
Post by Cristina Cocho
Hi Carlos,
My requirements are plotting 3096 x 6192 float images at 2Hz (ideal
case). Up to now, I only got close to this frequency when using images
of 1000 x 1000. I have been working with your example and, as you
said, I got the same time results. However, the plotting/loading time
considerably increases when using other types of numpy arrays. In my
data = np.ndarray((x,y),buffer=buf,dtype=float)
where the parameters x, y and buf are calculated in the C++ script. In
particular the parameter buf is obtained with the function (from
PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
In my opinion the bottleneck appears when the data is not generated
within the Python script. That is, if my buffer is a numpy array with
random data generated in the python script (as in your example) I
get the same time performance but when passing the data from one
script (C++) to the other (Python) ,even though the array size is the
same, the time necessary to execute img.set_data(array) is increased.
Thank you for your help,
Cristina
Post by Carlos Pascual
Just out of curiosity, what are your requirements?
With the attached code I plot images made of floats with 2048x2048 at
~3Hz (~10Hz if I use dtype=uint16) in a pretty old machine.
Naturally, speed decreases if the image size is bigger.
For me, this is usually enough, since it is close to the human perception
limit.
Cheers,
Carlos
Post by Cristina Cocho
Hi Carlos,
Thank you very much for your answer. As suggested, I have tested the
function set_data() but, even though we save a lot of time because we
only execute once the function make.image() (in order to get the plot
item where to apply set_data()), the time consumed when executing
set_data() periodically is big enough to make our real plot
application not feasible.
Thank you very much,
Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revisio
n=17 889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use
make.image(data).
Moreover, is it possible to manipulate and add data to ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating
numpy arrays, converting them into “image items” and adding the
result to the Guiqwt window?
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
swapimages.py
< 1 000AfficherTélécharger
--
+----------------------------------------------------+
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
+----------------------------------------------------+
Cristina Cocho
2011-11-09 09:06:38 UTC
Permalink
Hi Carlos,

I am really impressed by the fact that you are able to plot float 2048
x 2048 images at around 3Hz using the same pattern as me. I have been
checking my code and, honestly, I do not know what I am doing wrong.

There is one thing I am curious about. When trying to communicate both
threads (the GUI and the data producer) we could not send the data
from one to another within a signal (something strange because we
managed to do that in simple examples). Trying to get a fast solution
(until now we are carrying out these tests to see whether the library
satisfies our requirements or not) we decided to advise the GUI
thread that new data is available through a signal but we pass the
data by creating an attribute of the class data producer (which is the
ndarray from the last post) and accessing it when executing the slot
function. Although that does not seem to influence the refresh time, I
wonder if there are better ways to do it (in my opinion this point
should be improved in our test).

Best regards,

Cristina
Post by Carlos Pascual
Hi,
Here we also get images from a C++ thread, and we use the same way for
transferring the data by refferencing the buffer. From what you describe, it
looks like you are doing it well (not copying the data unnecessarily), so I
don't understand why it is slower.
I am out of ideas. Just double-check that your code is not copying the data
somewhere.
If the bottleneck cannot be solved, maybe you can have a look at using the C++
Qwt library directly.
Post by Cristina Cocho
Hi Carlos,
My requirements are plotting 3096 x 6192 float images at 2Hz (ideal
case). Up to now, I only got close to this frequency when using images
of 1000 x 1000. I have been working with your example and, as you
said, I got the same time results. However,  the plotting/loading time
considerably increases when using other types of numpy arrays. In my
data = np.ndarray((x,y),buffer=buf,dtype=float)
where the parameters x, y and buf are calculated in the C++ script. In
particular the parameter buf is obtained with the function (from
PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
In my opinion the bottleneck appears when the data is not generated
within the Python script. That is, if my buffer is a numpy array with
random data generated in the python script (as in your example) I
get the same time performance but when passing the data from one
script (C++) to the other (Python) ,even though the array size is the
same, the time necessary to execute img.set_data(array) is increased.
Thank you for your help,
Cristina
Post by Carlos Pascual
Just out of curiosity, what are your requirements?
With the attached code I plot images made of floats with 2048x2048 at
~3Hz (~10Hz if I use dtype=uint16) in a pretty old machine.
Naturally, speed decreases  if the image size is bigger.
For me, this is usually enough, since it is close to the human perception
limit.
Cheers,
Carlos
Post by Cristina Cocho
Hi Carlos,
Thank you very much for your answer. As suggested, I have tested the
function set_data() but, even though we save a lot of time because we
only execute once the function make.image() (in order to get the plot
item where to apply set_data()), the time consumed when executing
set_data() periodically is big enough to make our real plot
application not feasible.
Thank you very much,
Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?revisio
n=17 889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the data
(ImagePlot widget) in order to avoid having to use
make.image(data).
Moreover, is it possible to manipulate and add data to  ImagePlot
widget (or any Guiqwt widget) by following different steps than the
ones shown above? That is, are there other options than creating
numpy arrays, converting them into “image items” and adding the
result to the Guiqwt window?
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
 swapimages.py
< 1 000AfficherTélécharger
--
+----------------------------------------------------+
 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
 Phone: +34 93 592 4428
+----------------------------------------------------+
Carlos Pascual
2011-11-09 12:17:03 UTC
Permalink
Hi,
No, the ***@3Hz is what I got with the example I sent.
In our "real life" system this case has not yet being tried (we have only
needed refreshes of ~0.5Hz)

Also, in the transference of the data, I cannot be of much help because in our
case we use communicate the data producer with the GUI via Tango [1]

If you are interested, you can have a look at the code of PyTango [2] (the GUI
uses it), because it is there that the C++ -->Python buffer transference
occurs)


[1] http://www.tango-controls.org/
[2] http://www.tango-controls.org/static/PyTango/latest/doc/html/

Cheers,

Carlos
Post by Cristina Cocho
Hi Carlos,
I am really impressed by the fact that you are able to plot float 2048
x 2048 images at around 3Hz using the same pattern as me. I have been
checking my code and, honestly, I do not know what I am doing wrong.
There is one thing I am curious about. When trying to communicate both
threads (the GUI and the data producer) we could not send the data
from one to another within a signal (something strange because we
managed to do that in simple examples). Trying to get a fast solution
(until now we are carrying out these tests to see whether the library
satisfies our requirements or not) we decided to advise the GUI
thread that new data is available through a signal but we pass the
data by creating an attribute of the class data producer (which is the
ndarray from the last post) and accessing it when executing the slot
function. Although that does not seem to influence the refresh time, I
wonder if there are better ways to do it (in my opinion this point
should be improved in our test).
Best regards,
Cristina
Post by Carlos Pascual
Hi,
Here we also get images from a C++ thread, and we use the same way for
transferring the data by refferencing the buffer. From what you describe,
it looks like you are doing it well (not copying the data
unnecessarily), so I don't understand why it is slower.
I am out of ideas. Just double-check that your code is not copying the
data somewhere.
If the bottleneck cannot be solved, maybe you can have a look at using
the C++ Qwt library directly.
Post by Cristina Cocho
Hi Carlos,
My requirements are plotting 3096 x 6192 float images at 2Hz (ideal
case). Up to now, I only got close to this frequency when using images
of 1000 x 1000. I have been working with your example and, as you
said, I got the same time results. However, the plotting/loading time
considerably increases when using other types of numpy arrays. In my
data = np.ndarray((x,y),buffer=buf,dtype=float)
where the parameters x, y and buf are calculated in the C++ script. In
particular the parameter buf is obtained with the function (from
PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
In my opinion the bottleneck appears when the data is not generated
within the Python script. That is, if my buffer is a numpy array with
random data generated in the python script (as in your example) I
get the same time performance but when passing the data from one
script (C++) to the other (Python) ,even though the array size is the
same, the time necessary to execute img.set_data(array) is increased.
Thank you for your help,
Cristina
Post by Carlos Pascual
Just out of curiosity, what are your requirements?
With the attached code I plot images made of floats with 2048x2048 at
~3Hz (~10Hz if I use dtype=uint16) in a pretty old machine.
Naturally, speed decreases if the image size is bigger.
For me, this is usually enough, since it is close to the human
perception limit.
Cheers,
Carlos
Post by Cristina Cocho
Hi Carlos,
Thank you very much for your answer. As suggested, I have tested
the function set_data() but, even though we save a lot of time
because we only execute once the function make.image() (in order
to get the plot item where to apply set_data()), the time consumed
when executing set_data() periodically is big enough to make our
real plot application not feasible.
Thank you very much,
Cristina
Post by Carlos Pascual
you may want to try with image.set_data()
I use it in my application for something similar to your needs. See
http://tango-cs.svn.sourceforge.net/viewvc/tango-
cs/gui/taurus/trunk/lib/taurus/qt/qtgui/extra_guiqwt/image.py?rev
isio n=17 889&view=markup
Post by Cristina Cocho
We would like to know if there are other ways to refresh the
data (ImagePlot widget) in order to avoid having to use
make.image(data).
Moreover, is it possible to manipulate and add data to
ImagePlot widget (or any Guiqwt widget) by following
different steps than the ones shown above? That is, are there
other options than creating numpy arrays, converting them into
“image items” and adding the result to the Guiqwt window?
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
swapimages.py
< 1 000AfficherTélécharger
--
+----------------------------------------------------+
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
Phone: +34 93 592 4428
+----------------------------------------------------+
--
+----------------------------------------------------+
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
+----------------------------------------------------+
Loading...