Displaying (numpy) arrays in pyglet

1,342 views
Skip to first unread message

Tony

unread,
Dec 4, 2007, 4:20:25 PM12/4/07
to pyglet-users
Hi,

I just started using pyglet after upgrading to Leopard OS X (before I
was using pygame). I'm trying to display (or animate) the values of a
numpy array (2D), but I haven't been able to figure out how.

With pygame, I iterated through my array and used
pygame.surface.fill(color, (x, y, w, h))
to fill squares (with dimensions `w` by `h`, at location `x`, `y`)
with a color corresponding to the value of my array. I could also have
used pygame.surfarray to directly display my array (after converting
from numpy to Numeric).

I haven't been able to figure out how to get something like this to
work in pyglet. I apologize if this is a stupid question. I've tried
searching the forums and looking through the documentation, but I
haven't found anything similar.

Thanks for your help,
-Tony

Alex Holkner

unread,
Dec 4, 2007, 5:10:01 PM12/4/07
to pyglet...@googlegroups.com

All graphics with pyglet are drawn using OpenGL. One way to draw rectangles is:

from pyglet.gl import *
glColor3f(1, 0, 0) # red
glRectf(x, y, x+w, y+h)

A more efficient way to draw the entire array is to copy it into a
texture. Use the pyglet.image.ImageData to create and update the data
in a texture, which is then drawn using the blit() method. If your
numpy array is not in a format that ImageData can use, you can use the
glTexSubImage2D call directly, with a little more effort.

If you've never used OpenGL before this task is going to give you a
steep learning curve -- you may want to skim some of the many
tutorials around on the net first.

You could also take a look at
http://groups.google.com/group/pyglet-users/web/2d-drawing-primitives-module,
which provides some simple drawing primitives without needing to know
OpenGL.

Cheers
Alex.

Tony

unread,
Dec 5, 2007, 12:57:21 AM12/5/07
to pyglet-users
Thanks for the quick reply!

After some stupid errors (on my part), I finally got this to work
(using the first method). It's a little slow (as you suggested), but
it'll do until I have time to dabble with the ImageData stuff.

Thanks again,
-Tony

On Dec 4, 5:10 pm, "Alex Holkner" <alex.holk...@gmail.com> wrote:
> You could also take a look athttp://groups.google.com/group/pyglet-users/web/2d-drawing-primitives...,

Andrew Straw

unread,
Dec 14, 2007, 1:40:29 PM12/14/07
to pyglet...@googlegroups.com
Alex Holkner wrote:
> On 12/5/07, Tony <burlyg...@gmail.com> wrote:
>
>> Hi,
>>
>> I just started using pyglet after upgrading to Leopard OS X (before I
>> was using pygame). I'm trying to display (or animate) the values of a
>> numpy array (2D), but I haven't been able to figure out how.
>>
> A more efficient way to draw the entire array is to copy it into a
> texture. Use the pyglet.image.ImageData to create and update the data
> in a texture, which is then drawn using the blit() method. If your
> numpy array is not in a format that ImageData can use, you can use the
> glTexSubImage2D call directly, with a little more effort.
>
It seems a good idea to be able to create an Image without copying the
data. As far as I can tell from a few minutes of browsing the code, this
doesn't seem currently possible, as ImageData's _ensure_string_data()
seems to allocate a new buffer each time. What are the prospects for
making a code path that takes the raw data buffer, e.g. from numpy's
my_array.ctypes.data (of course checking that the array properties are
valid for a direct memory view, such as dimensions, strides, dtype, and
so on)?

Can you give some hints as to what would be necessary to either A)
modify ImageData to take a buffer object (or a view of numpy data,
although this is more specific and less general) or B) create a
ImageData-like class that would do something similar?

Thanks,
Andrew

Alex Holkner

unread,
Dec 14, 2007, 7:52:41 PM12/14/07
to pyglet...@googlegroups.com

The _ensure_string_data() path is skipped if the data is already in a
format supported by your video card. Off the top of my head, this
means:

* Positive pitch (image rows are ordered bottom-up)
* Not having the subimage workaround enabled
* A format such as 'RGBA', 'RGB' or perhaps 'BGR', 'BGRA' if you have
the relevant extension.

Alex.

Andrew Straw

unread,
Dec 14, 2007, 8:30:49 PM12/14/07
to pyglet...@googlegroups.com, alex.h...@gmail.com
I gather you're implying that I can use a string view of the numpy
array's buffer interface... OK, I'll give that a try and write up an
example if I succeed.

Andrew Straw

unread,
Dec 21, 2007, 2:43:36 PM12/21/07
to pyglet...@googlegroups.com, alex.h...@gmail.com
Andrew Straw wrote:
> I gather you're implying that I can use a string view of the numpy
> array's buffer interface... OK, I'll give that a try and write up an
> example if I succeed.

I succeeded in displaying numpy arrays without copying the data (via a
slightly different means -- the array's ctypes attribute). I have sent a
patch, including example code to
http://code.google.com/p/pyglet/issues/detail?id=202

(I don't know how to change the type of this report to "enhancement"
rather than "defect".)

I would be happy if you included this in pyglet.

Cheers!
Andrew

Patrick Devine

unread,
Dec 21, 2007, 3:22:01 PM12/21/07
to pyglet...@googlegroups.com
I just struggled with something similar to this as well. I'm doing
pixel perfect collisions with a black and white collision map which
has the same coordinates as my overlay image. Surfarray in pygame
made this really easy to do since you could specify the x and y
coordinates of a pixel and get a tupple value back of the RGB values.
I ended up changing the code to change the format to just return the
value for 'R' and then wrote a function for determining the x/y index
value for a given pixel. It'd be nice if pyglet could do this for you
though.

Another annoying problem was the data member returned each individual
pixel value back as a string which looks like '\x00' or '\xff'. It'd
be nice if these were integers instead.

--Patrick.

Reply all
Reply to author
Forward
0 new messages