Saved matplotlib gif animation is different from the jupyter notebook output ! Why?

Viewed 116

The below code creates an animation of sine and cosine graph along with its intersection points. The animation works perfectly in jupyter notebook( I am using google colab). However, when I save animation in gif format , then it differs from the jupyter notebook animation. The intersection points are showing already in the saved animation(please second picture) ! Can anyone tell me why is it happening and how to fix the code. I think the code needs to be fixed at if statement which I wrote below.

(1) Animation playing inside notebook

Animation playing inside notebook

(2) Saved Animation

saved animation

and here is the code and my approach:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter
from matplotlib import rc
rc('animation', html='jshtml') 

def truncation(values, decimals = 0):
    """
    Truncate the value to the desired places.
    """
    req_trunc = np.trunc(values*10**decimals)/10**decimals
    return req_trunc

def animated_graph(x, y_1, y_2, label_list):
    """
    Creates an animated graph
    
    Arguments :
    x -- values of x to draw the graphs
    y_1, y_2 -- values of function f1 and f2 corresponding to x
    
    Return :
    ani : animation output
    """
    # creates Figure and Axes objects
    fig, ax = plt.subplots()
    # set figure size
    fig.set_size_inches(10,5)
    # set x axis and y axis limit
    ax.set_xlim(min(x)-1, max(x)+1)
    ax.set_ylim(min(min(y_1), min(y_2))-1, max(max(y_1), max(y_2))+1)
    # marker positions
    pos_1, = ax.plot([], [], marker = "o", color = "red", ls = "", markersize = 10)
    pos_2, = ax.plot([], [], marker = "o", color = "green", ls = "", markersize = 10)
    # line graph
    line_1, = ax.plot([], [], marker = "", color = "blue", ls ="-", lw = 2, label = label_list[0])
    line_2, = ax.plot([], [], marker = "", color = "black", ls ="-", lw = 2, label = label_list[1] )
    # coordinates annotation of marker
    annotation_1 = ax.annotate('', xy=(0,0))
    annotation_2 = ax.annotate('', xy=(0,0))
    # add legend
    plt.legend()
    # animation function
    def animate(i):
        # update marker postions
        pos_1.set_data(x[i], y_1[i])
        pos_2.set_data(x[i], y_2[i])
        # update line graph
        line_1.set_data(x[:i], y_1[:i])
        line_2.set_data(x[:i], y_2[:i])
        # update lable
        line_1.set_label(label_list[0])
        line_2.set_label(label_list[1])
        # update annotations i.e. coordinates 
        annotation_1.set_text(f"({x[i]}, {y_1[i]})")
        annotation_1.set_position((x[i],y_1[i]))
        annotation_2.set_text(f"({x[i]}, {y_2[i]})")
        annotation_2.set_position((x[i],y_2[i]))
        # Add coordinates for the intersection points.
        if (x[i], y_1[i]) == (x[i], y_2[i]):
            ax.text(x[i], y_1[i], f"{x[i],y_1[i]}", color = "m")
        else :
            pass
        return pos_1, pos_2, line_1, line_2, annotation_1, annotation_2
    ani = FuncAnimation(fig, animate, frames = len(x), interval = 150, repeat = True )
    return ani  

# x ranging from :
x_range = np.linspace(-2*np.pi, 2*np.pi, 129)
# sin(x)
sin_x = np.sin(x_range)
# cos(x)
cos_x = np.cos(x_range)
# truncation for intersection
x_range,sin_x, cos_x = truncation(x_range, 2), truncation(sin_x, 3), truncation(cos_x, 3)

# creating animation of sine cosine wave  
sine_cos_animation = animated_graph(x_range, sin_x, cos_x, label_list = ["sin(x)", "cos(x)"])
sine_cos_animation

# animation saving
sine_cos_animation.save("sine_cos_animation.gif", writer = PillowWriter(fps = 20))
0 Answers
Related