CromeX
CromeX

Reputation: 445

Python Script to animate a set of lines in a class

I am trying to put the matplotlib.animation set into a class function. Though I don't seem to be having much luck. I have tried both, FunctionAnimation() & ArtistAnimation(). For both I don't seem to be able to get them to work (though they are vastly different).

# ------------------------------ #
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# ------------------------------ #
class AniPlot():
    def __init__(self):
        self.fig = plt.figure()
        self.ax = plt.axes(xlim=(-3.5, 3.5), ylim=(-5, 2))
        self.line, = self.ax.plot([], [], lw=2)


    def set_data(self,tvector):
        self.data = tvector

    def ani_init(self):
        self.line.set_data([], [])

    def ani_update(i):
        x = self.data[i][0]
        y = self.data[i][1]

        self.line.set_data(x, y)
        return self.line,


    def animate(self):
        anim = animation.FuncAnimation(self.fig, self.ani_update, init_func=self.ani_init,
                               frames=4, interval=20, blit=True)
        plt.show()

# ------------------------------ #

data = [
[[0,0,1,0],[0,-1,-2,-3]],
[[0,0,0,0.1],[0,-1,-3,-4]],
[[0,0,0.5,0],[0,-1,-2.5,-3.5]],
[[0,0,1,2],[0,-1,-2,-2.5]]
        ]
myani = AniPlot()
myani.set_data(data)
myani.animate()

I want to try get my head around it, rather than use someone else's code. Though I did use others as a starting point. Can anyone help?

Upvotes: 4

Views: 4387

Answers (2)

kh.waeli
kh.waeli

Reputation: 21

You can either set blit as False, or as True but make sure you replace the line return self.line by return self.line,.

#!/usr/bin/env python3

# ------------------------------ #
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# ------------------------------ #
class AniPlot():
    
    def __init__(self):
        self.fig = plt.figure()
        self.ax = plt.axes(xlim=(-3.5, 3.5), ylim=(-5, 2))
        self.line, = self.ax.plot([], [], lw=2)


    def set_data(self,data):
        self.data = data

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

    def ani_update(self, i):
        x = self.data[i][0]
        y = self.data[i][1]
        self.line.set_data(x, y)
        return self.line


    def animate(self):
        self.anim = animation.FuncAnimation(self.fig, self.ani_update, init_func=self.ani_init, frames=4, interval=20, blit=False)
        plt.show()

# ------------------------------ #

data = [
[[0,0,1,0],[0,-1,-2,-3]],
[[0,0,0,0.1],[0,-1,-3,-4]],
[[0,0,0.5,0],[0,-1,-2.5,-3.5]],
[[0,0,1,2],[0,-1,-2,-2.5]]
        ]
myani = AniPlot()
myani.set_data(data)
myani.animate()

Upvotes: 1

Roberto
Roberto

Reputation: 2786

(warning: Newbie here.)

I think the best way for "anim" to stick is actually to set it as instance variable, using self.anim:

self.anim = ...

You also need to add "self" here:

def ani_update(self, i)

I use Spyder 2.1.10 and it seems to be working, although the animation is a bit fast.

Upvotes: 4

Related Questions