Reputation: 117
I would like to continuously update one attribute of a plot (for example, randomizing the y-values), and then once in a while update it differently (for example, setting all y-values to zero).
Is it possible to do this with just one FuncAnimation routine?
Or, what is the best way to do this?
edit: for example, do "updatePlot()" for a while, then do "otherUpdatePlot":
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
import Tkinter as tk
class AnimatedPlot(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.fig = plt.Figure()
self.ax1 = self.fig.add_subplot(111)
self.line, = self.ax1.plot([], [], lw=2)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1, column=0, columnspan=2, rowspan=8)
self.ax1.set_ylim(0,20) #only the visible limits of the grad
self.ax1.set_xlim(0,20) ##the whole dataset swill be longer
self.startPlot()
def startPlot(self):
self.xdata = np.linspace(0, 20, 20)
self.ydata = np.linspace(0, 20, 20)
self.anim = animation.FuncAnimation(
self.fig,
self.updatePlot,
repeat=True) #here is the animation routine that right now only runs one updatePlot function
self.anim._start()
print("Running")
def updatePlot(self,i): #the function to be animated most of the time
self.ydata = np.random.randint(20, size=20)
self.line.set_data(self.xdata, self.ydata)
return self.line,
def otherUpdatePlot(self,i): #to be animated once in a while
self.ydata = np.zeros(shape=(1, 20))
self.line.set_data(self.xdata, self.ydata)
return self.line,
def main():
root = tk.Tk()
app = AnimatedPlot(root)
app.pack()
root.mainloop()
if __name__ == '__main__':
main()
Upvotes: 0
Views: 732
Reputation: 339775
Create a function that, depending on some condition, calls one of the two methods. Use this function as animating function.
In the following example, we use an attribute self.once_in_a_while = 6
to make the plot be all zeros every 6th frame.
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
import Tkinter as tk
class AnimatedPlot(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.fig = plt.Figure()
self.ax1 = self.fig.add_subplot(111)
self.line, = self.ax1.plot([], [], lw=2)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1, column=0, columnspan=2, rowspan=8)
self.ax1.set_ylim(0,20) #only the visible limits of the grad
self.ax1.set_xlim(0,20) ##the whole dataset swill be longer
self.startPlot()
def startPlot(self):
self.xdata = np.linspace(0, 20, 20)
self.ydata = np.linspace(0, 20, 20)
self.once_in_a_while = 6
self.anim = animation.FuncAnimation(
self.fig,
self.update,
repeat=True)
self.anim._start()
print("Running")
def update(self, i):
if i%self.once_in_a_while:
r = self.updatePlot(i)
else:
r = self.otherUpdatePlot(i)
return r
def updatePlot(self,i): #the function to be animated most of the time
self.ydata = np.random.randint(20, size=20)
self.line.set_data(self.xdata, self.ydata)
return self.line,
def otherUpdatePlot(self,i): #to be animated once in a while
self.ydata = np.zeros(shape=(1, 20))
self.line.set_data(self.xdata, self.ydata)
return self.line,
def main():
root = tk.Tk()
app = AnimatedPlot(root)
app.pack()
root.mainloop()
if __name__ == '__main__':
main()
Upvotes: 1