2 newbie questions: redraw plot and access to raw image buffer

I'm trying to generate plots as textures for use within a real-time graphics application (written using the pythonOgre graphics engine). I'm brand new to matplotlib so please bear with me. Two questions, one easy, one possibly hard.

In the following code snippet, I create and draw a pie chart, do some intermediate work, update the pie fractions, and redraw. I end up with the second version superimposed on the first. Initially I thought it was simply a matter of clearing the canvas, but as I repeat this test with more and more updates, the redraw seems to slow down - this makes me think that each redraw is actually rerendering all the layers. Is this the case? If so, how do I avoid it?

# create matplotlib figure
figure = Figure(figsize=(4,3), dpi=200, frameon=True)
figureCanvas = FigureCanvas(figure)

# unchanging details of pie chart
ax = figure.add_subplot(111) # pie plot
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
ax.set_title('Example pyOgre Pie Chart')
ax.grid(True)
ax.pie([25,25,30,20], labels=labels)
figureCanvas.draw()

# ....

# update pie chart
ax.pie([30,25,25,20], labels=labels)

# matplotlib draw
figureCanvas.draw()

And the harder question. I need access to the address of the raw image buffer. (I assume this is a contiguous block of c-allocated memory?) Presently, I copy into a ctypes buffer but this slows things down significantly. Is there an alternative approach?

# retrieve buffer from matplotlib
height = int( figureCanvas.get_renderer().height )
width = int( figureCanvas.get_renderer().width )

# extract image buffer (need as void ptr to contiguous byte array)
buff = figureCanvas.buffer_rgba(0,0)
cbuffer[:] = buff[:] ## would prefer to eliminate this step
address = ctypes.addressof(cbuffer)

Any help is much appreciated ...

Cheers,
Darran.

···

--
Darran Edmundson [darran@...1769...]
http://www.edmstudio.com

Hi,

2007/10/29, Darran Edmundson <darran@...1769...>:

I'm trying to generate plots as textures for use within a real-time
graphics application (written using the pythonOgre graphics engine).
I'm brand new to matplotlib so please bear with me. Two questions, one
easy, one possibly hard.

In the following code snippet, I create and draw a pie chart, do some
intermediate work, update the pie fractions, and redraw. I end up with
the second version superimposed on the first. Initially I thought it
was simply a matter of clearing the canvas, but as I repeat this test
with more and more updates, the redraw seems to slow down - this makes
me think that each redraw is actually rerendering all the layers. Is
this the case? If so, how do I avoid it?

# create matplotlib figure
figure = Figure(figsize=(4,3), dpi=200, frameon=True)
figureCanvas = FigureCanvas(figure)

# unchanging details of pie chart
ax = figure.add_subplot(111) # pie plot
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
ax.set_title('Example pyOgre Pie Chart')
ax.grid(True)
ax.pie([25,25,30,20], labels=labels)
figureCanvas.draw()

# ....

# update pie chart

At this point I guess you can do ax.clear() to clear the axis and
delete all the old plots.

ax.pie([30,25,25,20], labels=labels)

# matplotlib draw
figureCanvas.draw()

And the harder question. I need access to the address of the raw image
buffer. (I assume this is a contiguous block of c-allocated memory?)
Presently, I copy into a ctypes buffer but this slows things down
significantly. Is there an alternative approach?

Sorry I can't help with this :-/.

Regards,

    ~ Antonio

And the harder question. I need access to the address of the raw image
buffer. (I assume this is a contiguous block of c-allocated memory?)
Presently, I copy into a ctypes buffer but this slows things down
significantly. Is there an alternative approach?

I'm assuming you're using the Agg backend. If so, you can get the raw memory wrapped in a Python buffer object as follows:

   figureCanvas.get_renderer().buffer_rgba(x, y)

(where x, y is the upper left corner in the plot of the area you want to get.) It should be possible in C side to then get the address out of that using the Python/C API.

Cheers,
Mike

···

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Michael Droettboom wrote:

I'm assuming you're using the Agg backend. If so, you can get the raw memory wrapped in a Python buffer object as follows:
  figureCanvas.get_renderer().buffer_rgba(x, y)
(where x, y is the upper left corner in the plot of the area you want to get.) It should be possible in C side to then get the address out of that using the Python/C API.

Hi Mike. I am using the above API call. What I'm hoping to avoid is having to copy this buffer to a ctypes buffer.

buff = figureCanvas.buffer_rgba(0,0)
cbuffer[:] = buff[:] ## would prefer to eliminate this step
address = ctypes.addressof(cbuffer)
ptr = ogre.CastVoidPtr(address)

This question probably belongs on the pythonOgre mailing list. Thanks though.

Cheers,
Darran.

···

--
Darran Edmundson [darran@...1769...]
http://www.edmstudio.com