Animated graphs / wxPython
Philip Swartzleonard
starx at pacbell.net
Sat Feb 9 18:06:29 EST 2002
Duncan Smith || Sat 09 Feb 2002 11:04:01a:
> I need to frequently redraw a graph (ie. nodes and edges) to a wxPython
> panel. ie. I remove and/or add edges to the graph and then redraw it.
> I am currently using wxPython ellipses and lines for drawing the nodes
> and edges. The problems are the speed of redrawing and the flickering
> as the window is redrawn. SetClippingRegion() doesn't help a great
> deal as the clipping region is usually nearly as large as the full
> graph. I am currently using a workaround whereby I draw edges in the
> background colour in order to remove them. But after a number of
> redraws the graph starts to get noticeably whited out by drawing over
> existing nodes and edges.
>
> Does anyone know of a better approach? Ideally I would like to be able
> to simply remove and add edges and send them to the back of the nodes
> rather than redrawing the relevant nodes each time I add an edge. I
> have looked at a number of packages, but none seem to be able to do
> what I want. Essentially I want an animated graph that will show a user
> what the graph algorithms are up to. (Gato won't do the job.) Thanks
> in advance.
Well, if you want to solve the flickering you either need to use double
buffering or draw really, really, really fast. I'd suggest the former. I
don't really know any other options, but you could use basic 2d opengl with
pyopengl and pyopenglcontext's wxcontext... or something like that.
Actually, i felt like thinking a little bit, so i worked this out. This is
a rough draft of a class that would do what you want -- just alter it's
points and hit it's draw() for every update. You'd just have to set a
background color (optionally) and point the 'camera' where you want it
once, and that's about it-- just call this with an initilized GL setup
available. Note that i haven't tested this at all, but if you want to go
this way it should get you started :).
(Also, it's probably overkill, but it's the only graphics system i'm very
familiar with, and it can do this job :)
class graph_rep(object):
def __init__( self, initial_points, nodesize=.25 ):
self.points = initial_points
self.nodelist = self.gennode( nodesize )
def __del__( self ):
glDeleteLists( self.nodelist, 1 )
def gennode( self, nodesize ):
# Generate a simple hexagon
glNewList( listnum, GL_COMPILE )
glBegin( GL_POLYGON )
for deg in range( 0, 360, 60 ):
rads = math.pi * (deg/180.0)
glVertex2d( nodesize * math.cos(rads),
nodesize * math.sin(rads) )
glEnd
glEndList()
return listnum
def draw( self, mode ):
# So we don't do this for every mouseover, etc
if mode == 1:
glBegin( GL_LINESTRIP )
glColor3d( 0,0,0 ) #black
for point in self.points:
glVertex2d( point.x, point.y )
glEnd()
glColor3d( 1,0,0 ) #red
for point in self.points:
glPushMatrix()
glTranslated( point.x, point.y, 0 )
glCallList( self.nodelist )
glPopMatrix()
myapp.3display.triggerRedraw()
# or a swap-buffer command and GLUTpostRedisplay, or whatever
# it is that you need to do to update the screen. This could
# easily be done in whatever calls the draw function, too.
--
Philip Sw "Starweaver" [rasx] :: www.rubydragon.com
More information about the Python-list
mailing list