Mostafa Ghadimi
Mostafa Ghadimi

Reputation: 6756

matplotlib: bar-plot animation only works once

I have implemented an animation using the FuncAnimation method of matplotlib.animation.

There is no error in the code but I don't know where the problem really is!

Code:

def visualization(self):
    fig = plt.figure()
    
    def animation_frame(i):
        print(i)
        trimmed_dist = self.get_distributions(i, self.window_size + i)
        # create labels             
        label_no = len(trimmed_dist)
        labels = []
        for index in range(label_no):
            from_ = index * self.bucket_length
            to_ = (index + 1) * self.bucket_length
            label = '{:.2f} - {:.2f}'.format(from_, to_)
            labels.append(label)
        
        #create bar chart
        colors = plt.cm.Dark2(range(label_no))
        plt.xticks(rotation=90)
        plt.bar(x=labels, height=trimmed_dist, color=colors)
        
    frames_no = len(self.percentages) - self.window_size
    print('frames_no:', frames_no)
    animation = FuncAnimation(fig, animation_frame, frames=frames_no, interval=1000)
    return animation

Output:

matplotlib output image

PS 1: The frame_no value is 877.

PS 2: I think the problem is with the return in the visualization method. So I have changed the code but it still doesn't work properly.

Upvotes: 2

Views: 346

Answers (1)

Zephyr
Zephyr

Reputation: 12496

I believe you are running your code in a Jupyter notebook. In that case, you should add %matplotlib notebook at the beginning of your code.
As a reference, try to run the code you can find in this answer in order to see if it runs for you.


EDIT

I implemented a part of your code in a notebook. Since I do not know what self.percentages, self.window_size, self.get_distributions and self.bucket_length are and which values they have, I set labels = ['a', 'b', 'c'] and trimmed_dist = [3*i, 2*i, i**2] for seek of simplicity, in order to run a simple animation.
This is my code:

%matplotlib notebook
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt

def animation_frame(i):
    plt.gca().cla()
    
    labels = ['a', 'b', 'c']
    trimmed_dist = [3*i, 2*i, i**2]
    label_no = len(trimmed_dist)
    
    colors = plt.cm.Dark2(range(label_no))
    plt.xticks(rotation=90)
    plt.bar(x=labels, height=trimmed_dist, color=colors)
    plt.title(f'i = {i}') # this replaces print(i)
    plt.ylim([0, 100])    # only for clarity purpose

fig = plt.figure()
frames_no = 877
print('frames_no:', frames_no)
animation = FuncAnimation(fig, animation_frame, frames=frames_no, interval=1000)

And this is the result.

I added plt.gca().cla() in order to erase the previous frame at each iteration.
print(i) statement does not work for me neither, so I replace it with plt.title(f'i = {i}') in order to write i in the title. On the contrary, print('frames_no:', frames_no) works properly.

As you can see, my animation runs, so try implement the changes I made into your code.
If the animation still does not run, try to check self.percentages, self.window_size, self.get_distributions and self.bucket_length values and types, in order to be sure that labels and trimmed_dist are computed properly.

Upvotes: 1

Related Questions