Search code examples
pythonmatplotlibanimated-gif

How to fade curves of an animated gif in matplotlib


I have a gif but i want to fade the curves plotted. I have read this solution but still I need help. At the moment all curves are the same:

enter image description here

This code makes the gif for me:

import matplotlib
import imageio
def plot_for_offset(time, value):
    ims = []
    fig, axs = plt.subplots(figsize=(6,2.5))
    for t, v in zip (time, value):
        axs.plot(t, v, lw=1.0, color='k')
        # Used to return the plot as an image rray
        fig.canvas.draw()       # draw the canvas, cache the renderer
        image = np.frombuffer(fig.canvas.tostring_rgb(), dtype='uint8')
        image  = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))
        ims.append(image)
    return ims
kwargs_write = {'fps':1.0, 'quantizer':'nq'}

import numpy as np                              
time = np.array([[0., 1., 2.], [0., 1., 2.], [0., 1., 2.]])
value = np.array([[0., 10., 20.], [20., 10., 0.], [10., 10., 10.]])
imageio.mimsave('animation.gif', plot_for_offset(time, value), fps=1.0)

Now, I want to fade the curves poped up in the past. I very much appreciate any help.


Solution

  • You can do that by changing the transparency alpha of your plot at each frame of your animation.

    See example below using the FuncAnimation function from matplotlib (doc here):

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.animation import FuncAnimation
    
    time = np.array([[0., 1., 2.], [0., 1., 2.], [0., 1., 2.],[0, 1, 2],[0, 1, 2]])
    value =np.array([[0., 10., 20.], [20., 10., 0.], [10., 10., 10.],[2, 2 ,2],[7, 14, 18]])
    fig, axs = plt.subplots(figsize=(6,2.5))
    ln=[plt.plot(time[i], value[i], lw=2.0, color='k',alpha=i==0) for i in range(len(time))]
    ln=[ln[i][0] for i in range(len(time))]
    axs.set_xlim(0, 2)
    axs.set_ylim(0, 20)
    step=5
    
    def update(frame):
    
        if frame<=(len(ln)*step)-1: # generalize to N curves
          ln[frame//step].set_alpha(1)
          [ln[i].set_alpha(0) for i in range(frame//step+1, len(ln))]
          [ln[i].set_alpha(1/(frame-(i+1)*step+1)) for i in range(frame//step)]
        else:
          [ln[i].set_alpha(1/(frame-(i+1)*step+1)) for i in range(len(ln)-1)]
        return ln
    
    ani = FuncAnimation(fig, update, frames=10*step,blit=True)
    

    And the output gives: enter image description here