Help needed with FuncAnimation

Hi,

I’m trying to learn how to use FuncAnimation. I made some small modifications to one of the matplotlib examples & tried it out, but I encounter a problem. I’m trying to update a line plot every 1 sec & I have my x-axis limit set to (0,10) initially. When the plot reaches x=10, I change the x-axis limit to (10,20) & continue the plot from there. I found that the 1st 2 seconds of the plot is always re-drawn in the 10th to 12th seconds, 20th to 22nd seconds and so on. I don’t understand what’s going on, so I hope someone here in this list can help me.

Just in case you don’t understand what I mean, I’ve included the code below so you’ll have a better idea when you run the code:

import matplotlib
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class Scope:
def init(self, ax, maxt=10, dt=1):
self.ax = ax
self.dt = dt
self.maxt = maxt
self.tdata = [0]
self.ydata = [0]

    self.line = Line2D(self.tdata, self.ydata, marker='o')
    self.ax.add_line(self.line)
    self.ax.set_ylim(0, 200)
    self.ax.set_xlim(0, self.maxt)
    self.ax.set_xlabel("Time(s)")

    self.ax.set_ylabel("Jitter Buffer Size(ms)", color=self.line.get_color())

self.ax.yaxis.label.set_color(self.line.get_color())

def update(self, y):
lastt = self.tdata[-1]
if lastt == self.tdata[0] + self.maxt: # reset the arrays
self.tdata = [self.tdata[-1]]
self.ydata = [self.ydata[-1]]

        self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)
        self.ax.figure.canvas.draw()

t = self.tdata[-1] + self.dt
self.tdata.append(t)
self.ydata.append(y)
self.line.set_data(self.tdata, self.ydata)
return self.line,

def emitter():
while True:
yield np.random.randint(0,200)

fig = plt.figure()
ax = fig.add_subplot(111)
scope = Scope(ax)

pass a generator in “emitter” to produce data for the update func

ani = animation.FuncAnimation(fig, scope.update, emitter, interval=1000,
blit=True)

plt.show()

Best Regards,

Clare.

Hi,

I managed to figure this out. I need to pass an init function to
FuncAnimation. Quoting from the MatPlotLib API documentation:

*init_func* is a function used to draw a clear frame. If not given, the
results of drawing from the first item in the frames sequence will be used.

So just in case someone has the same problem, here's the correct code:

import matplotlib
import numpy as np
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class Scope:
    def __init__(self, ax, maxt=10, dt=1):
        self.ax = ax
        self.dt = dt
        self.maxt = maxt
        self.tdata = [0]
        self.ydata = [0]
        self.line = Line2D(self.tdata, self.ydata, marker='o')
        self.ax.add_line(self.line)
        self.ax.set_ylim(0, 200)
        self.ax.set_xlim(0, self.maxt)
        self.ax.set_xlabel("Time(s)")
        self.ax.set_ylabel("Jitter Buffer Size(ms)",
color=self.line.get_color())

    def init(self):
        self.line.set_data([], [])
        return self.line,

    def update(self, y):
        lastt = self.tdata[-1]
        if lastt == self.tdata[0] + self.maxt: # reset the arrays
            self.tdata = [self.tdata[-1]]
            self.ydata = [self.ydata[-1]]
            self.ax.set_xlim(self.tdata[0], self.tdata[0] + self.maxt)
            self.ax.figure.canvas.draw()

        t = self.tdata[-1] + self.dt
        self.tdata.append(t)
        self.ydata.append(y)
        self.line.set_data(self.tdata, self.ydata)
        return self.line,

def emitter():
    while True:
        yield np.random.randint(0,200)

fig = plt.figure()
ax = fig.add_subplot(111)
scope = Scope(ax)

# pass a generator in "emitter" to produce data for the update func
ani = animation.FuncAnimation(fig, scope.update, emitter, interval=1000,
blit=True, init_func=scope.init)

plt.show()
Best Regards,
Clare.