Tkinter is extremely slow in drawing plots.... why???

Joseph A. Knapka jknapka at earthlink.net
Thu Aug 29 12:28:04 EDT 2002


"Joseph A. Knapka" wrote:
> 
> revyakin wrote:
> >
> > I am writing a simple application which is supposed to take an array
> > of x,y coords, generate a plot and allow simple manipulations on the
> > plot for convenient analysis(scrolling, scaling, zooming). I typically
> > work with reltaively large
> > sets of points, e.g. 65 000 (x,y) tuples. My problem is that , first,
> > it
> > takes it forever to draw a plot, and once the plot is in the window
> > it's extremely slow in
> > scrolling, zooming, resizing, etc. I don't have programming experience
> > in optimizing applications, and I picked python since I've done some
> > CGI based coding.  So I may not know smth that make my app work very
> > inefficiently. Can I use python Tk at
> > all for my purpose? Can anyone suggest what I can do to make it work
> > faster?
> >
> > I generate plots as following:
> >
> >         fileWindow = Toplevel()
> > #       the following returns an array of (x,y) tuples from an
> > external file.
> >         dataset = processData(data)
> >
> >         scrollbar = Scrollbar(fileWindow,orient=HORIZONTAL)
> >         scrollbar.pack(side=BOTTOM, fill=Y,expand=YES)
> >
> >         canvas = Canvas (master=fileWindow,height=600, width=800,
> > xscrollcommand=scrollbar.set)
> >         canvas.pack()
> >         scrollbar.config(command=canvas.xview)
> >
> >         for datum in dataset:
> >                 item = canvas.create_line(datum[0], datum[1], datum[0]+1,
> > datum[1]+1, fill = 'black')
> 
> I think your problem is just that the nature of the Tk
> canvas is not suited to this kind of use. It isn't just
> a block of pixels you draw on; it keeps track of each
> individual visual object you create(), so that you can
> manipulate them independently. Also, the fact that
> every one of your create() calls is being transformed
> into a Tcl string and passed into an embedded Tcl
> interpreter does not help matters.
> 
> You can create the entire plot as a single canvas item,
> however, which might speed things up considerably.
> Assuming "dataset" is just a list of 2-tuples,
> then this should work:
> 
> def flatten(l):
>   import operator
>   return reduce(operator.add,map(list,l),[])
> item = canvas.create_line(*flatten(dataset),fill="black")
> 
> That code will give you a smooth line connecting
> all of your data points. The "flatten()" is just
> to convert your [(x1,y1),(x2,y2),..] into an
> unstructured [x1,y1,x2,y2], which is what create_line()
> wants.

Actually, it will give you a syntax error due to the keyword
arg "fill" following the magic *argument. Use this instead:

item = canvas.create_line(*flatten(dataset),**{"fill":"black"})
 
Cheers,

-- Joe
  "I'd rather chew my leg off than maintain Java code, which
   sucks, 'cause I have a lot of Java code to maintain and
   the leg surgery is starting to get expensive." - Me



More information about the Python-list mailing list