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

Joseph A. Knapka jknapka at earthlink.net
Thu Aug 29 12:22:55 EDT 2002


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.

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