Animation - Tk

All,

Alright I’ve made some progress here improving upon the example. (Codes at the bottom). So it looks like I’ve started a writing a wrapper class around the plot command that continuously updates it’s data by itself without having to write extra code. To me, using the subplot commands like set_xdata and set_ydata, should automatically update the graph, as I really don’t like dealing with that myself. So what’s happening below is that I’m starting two threads along with the Tkinter user thread. The first thread watches for changes in the data and the second actually induces changes forever. I know that the way I’m doing all this is a) quick and dirty b) really bad c) un-pythonic and d) it closes off all the current methods to plot etc, which if I need to continue developing this, I’ll open them up as well the best I can.

So that brings me to my next question. Is all this necessary? Is there a simpler way to make auto-updating graphs without all of the lines of “outside” code?

One last question, if anyone runs this, you’ll notice that the graph stops updating whenever you use the menu, or move the tkinter window, does anyone have a clue to why this is?

Thank you to everyone for your time.

Regards,
Kenneth Miller


import sys
import pylab as p
import numpy as npy
import time
import Tkinter as Tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg

import threading

class SimplePlot:
   def __init__(self,root):

       f = matplotlib.figure.Figure(figsize=(5,4),dpi=100)
       self.ax = f.add_subplot(111)
       self.canvas = self.ax.figure.canvas

       # create the initial line

       canvas = FigureCanvasTkAgg(f, master=root)
       canvas.show()
       canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

       self.canvas = canvas

       toolbar = NavigationToolbar2TkAgg( canvas, root )
       toolbar.update()
       canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

       manager = p.get_current_fig_manager()
       manager.window.after(100, self.run)

   def plot(self,x,y):
       line, = p.plot(x,y,animated=True,lw=2)
       self.x = x
       self.y = y
       self.line = line

   def run(self,*args):

       class MyThread(threading.Thread):
           def __init__(self,simplePlot):
               self.simplePlot = simplePlot
               print dir(self)
               threading.Thread.__init__(self)
           def run(self):
               background = self.simplePlot.canvas.copy_from_bbox(self.simplePlot.ax.bbox)
           # for profiling
               tstart = time.time()
               self.cnt = 0
               while 1:
                   # restore the clean slate background
                   self.simplePlot.canvas.restore_region(background)
                   # update the data
                   self.simplePlot.line.set_ydata(self.simplePlot.y)
                   # just draw the animated artist
                   self.simplePlot.ax.draw_artist(self.simplePlot.line)
                   # just redraw the axes rectangle
                   self.simplePlot.canvas.blit(self.simplePlot.ax.bbox)

                   if self.cnt==100:
                       # print the timing info and quit
                       print 'FPS:' , 100/(time.time()-tstart)
                       self.cnt=0
                       tstart = time.time()

                   self.cnt += 1

       mt = MyThread(self)
       mt.start()

class DataThread(threading.Thread):
   def run(self):
       import time
       i = 0.0
       while 1:
           s.x = x
           s.y = npy.sin(x+i/10.0)
           time.sleep(0.01)
           i += 1.0

root = Tk.Tk()
root.wm_title("Embedding")

s = SimplePlot(root)

#some data points
x = npy.arange(0,2*npy.pi,0.01)
y = npy.sin(x)
s.plot(x,y)

dt = DataThread()
dt.start()

Tk.mainloop()

dt.join()

~~~~~~~~~~~~~~~~~~end code~~~~~~~~~~~~~~~~~~~~~

<details class='elided'>
<summary title='Show trimmed content'>&#183;&#183;&#183;</summary>

On Mar 14, 2008, at 12:46 PM, Kenneth Miller wrote:

> All,
> 
> I've seen the examples for embedding matplot lib in Tk and the Tk animation example. However I've not yet been successful with creating an example where i can both animate data and stay in control of Tk. (The animation in tk example seems to lock the mainloop.) Does anyone have any advice or a quick example of a Tk app with an animated graph that doesn't lock the user out of Tk control?
> 
> Regards,
> Kenneth Miller

</details>