easiest way to plot x,y graphically during run-time?

Scott David Daniels Scott.Daniels at Acm.Org
Thu Jun 4 15:52:21 CEST 2009


Esmail wrote:
> Scott David Daniels wrote:
>> Esmail wrote:
>>> ... Tk seems a bit more complex .. but I really don't know much about
>>> it and its interface with Python to make any sort of judgments as
>>> to which option would be better.
>>
>> This should look pretty easy:
> 
> Thanks Scott for taking the time to share this code with me, it
> will give me something to study. I'm not sure if I'd say it looks
> easy (but then again I am not very familiar with Tk :-)

I threw in too much, I think.  The reason for the "idle -n" trick is to
share the Tkinter mainloop with idle itself, so you can experiment with
using Tkinter and see the effects of a single command, just after you
type it in (and thus get a nice intuitive feel for the possibilities).

The tricky part to understand is the switch from imperative programming
to interrupt driven programming.  gui stuff has to switch to interrupt
driven so that it can respond to things like mouse drags, windows
repaints, and so on when they happen, rather than when the software
asks for them.  Typically, a GUI program sets some stuff up (in
imperative mode), and then switches to event-driven code and drops into
an event loop.  It is also typical of most GUI programs that the display
manipulating code (the actual painting) must all be done in a single
thread (the display thread) where the events happen.  Small calculations
can occur inside these events, but slow calculations leave your GUI
unresponsive and unable to do things like restore hidden parts as you
drag another window across it.  So, big or slow calculations are either
done in a separate threads (or single calculation thread) that
communicate back with the display thread, or the big slow calculation
are done in bite-sized pieces in the display thread, doing a piece and
moving the rest on to another event.

A Tkinter canvas is nice to use because you can draw things on it, move
those things around (separately or in groups), change their shape or
color, make them visible or invisible, and the canvas keeps track of
drawing them.

     import Tkinter as tk

     # First set up Tkinter and a root window (idle -n fakes part)
     root = tk.Tk()

     # Set that window's size (400x400) and loc (5,5)
     root.geometry('400x400+5+5')

     # make a canvas (2-D drawing area) in that window
     canvas = tk.Canvas(root)

     #make the canvas fill the window (even as the window is resized)
     canvas.pack(expand=1, fill=tk.BOTH)

     # draw a red filled oval on the canvas bounded by (50,100), (70,140)
     a = canvas.create_oval((50, 100, 70, 140), fill='red')

     # the hard-to-get part about the example is that the Mover class
     # takes a canvas element or tag (such as a above), and provides a
     # couple of methods (.start(event) and .move(event)) for associating
     # with the mouse.  ".start" when the button goes down, and ".move"
     # as the button is dragged with the mouse down.

     canvas.itemconfig(a, fill='#55AADD') # Change to oval to near cyan
     canvas.move(a, 5, 5) # move it down right 5 pixels

     single_mover = Mover(canvas, a) # associate motion with our oval
     # make the "left button down" on canvas call our start method
     # which just gives u a point to move around from.
     canvas.bind("<Button-1>", single_mover.start)

     # make motion while left button is down call our move method.
     # there we will compare the mouse position to our saved location,
     # move our oval (in this case) a corresponding distance, and
     # update the saved location.
     canvas.bind("<B1-Motion>", single_mover.move)

     # at this point we have our behavior wired up. If in idle, "just
     # try it", but if not:
     tk.mainloop() # stays there until you click the close window.

Also, a Tkinter Canvas can be saved as an encapsulated postscript file,
thus allowing you pretty pictures into PDFs.

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list