Home > Blockchain >  add a matplotlib mp4 plot to an existing matplotlib mp4
add a matplotlib mp4 plot to an existing matplotlib mp4

Time:06-27

Windows 10, python 3.6, matplotlib 3.3.2

I am trying to make a mp4 where a function plot would show and then another function plot would show on the top of it:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# params
plt.rcParams['animation.ffmpeg_path'] = 'C:/xxx/ffmpeg.exe'

x_val = np.arange(0, 10)
lbl = ['sqr', 'cub', ]

# plot
fig, ax = plt.subplots(figsize=(4,2))
line_2, = ax.plot([], [])
line_3, = ax.plot([], [])
ax.set_xlim(x_val.min(), x_val.max())
ax.set_ylim(0, 4)
ax.set_title('sqr & cub')
ax.legend(lbl, bbox_to_anchor=(1.3, 1))
plt.tight_layout()


def func_2(x):
    return x**(1/2)


def func_3(x):
    return x**(1/3)



X, Y_2, Y_3 = [], [], []
def animation_frame_2(x):
    X.append(x)
    Y_2.append(func_2(x))
    line_2.set_xdata(X)
    line_2.set_ydata(Y_2)
    return line_2,


def animation_frame_3(x):
    X.append(x)
    Y_2 = func_2(x_val)
    line_2.set_xdata(x_val)
    line_2.set_ydata(Y_2)
    Y_3.append(func_3(x))
    line_3.set_xdata(X)
    line_3.set_ydata(Y_3)
    return line_2, line_3,
   

anim = animation.FuncAnimation(fig,
                               func=animation_frame_2,
                               frames=x_val,
                               interval=100,
                               repeat=False)


anim = animation.FuncAnimation(fig,
                               func=animation_frame_3,
                               frames=x_val,
                               interval=100,
                               repeat=False)
plt.show()

My intent is to have the first plot to show as an animation then, fix it and draw the second plot show as an animation on the top of the fixed first plot. Hence create some progression as opposed to both plot lines progressing together.

I was expecting to see: first the sqr plot progressing across all x_val individually, then on the top of showing the entire sqr plot, the cub plot progressing across all x_val individually. Instead, I am getting only the plot where sqr is plotted entirely and cub progresses across x_val.

Would love to have a few hints on how to work this, thanks.

CodePudding user response:

This is what I resolved doing. This could be optimized. Just my 2 cents, hoping it will help someone. Cheers

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# params
plt.rcParams['animation.ffmpeg_path'] = 'C:/xxx/ffmpeg.exe'

x_val = np.linspace(0, 10, 10)

# plot
fig, ax = plt.subplots(figsize=(4,2))
line_sqr, = ax.plot([], [], label='square')
line_cub, = ax.plot([], [], label='cube')
ax.set_xlim(x_val.min(), x_val.max())
ax.set_ylim(0, 4)
ax.set_title('square & cube')
ax.legend(bbox_to_anchor=(1.3, 1))
plt.tight_layout()


def func_sqr(x):
    return x**(1/2)

    
def func_cub(x):
    return x**(1/3)



x, X, Y_sqr, Y_cub = 0, [], [], []

def animation_frame(i):
    global x, X, Y_sqr, Y_cub

    if i % len(x_val) == 0:
        x = 0
        X, Y_sqr, Y_cub = [], [], []

    X.append(x_val[x])

    if i // len(x_val) == 0:  # first animation episode --> sqr
        Y_sqr.append(func_sqr(x_val[x]))
        line_sqr.set_xdata(X)
        line_sqr.set_ydata(Y_sqr)

        line_cub.set_xdata(None)
        line_cub.set_ydata(None)

    if i // len(x_val) == 1:  # second animation episode --> cube
        Y_sqr = func_sqr(x_val)
        line_sqr.set_xdata(x_val)
        line_sqr.set_ydata(Y_sqr)

        Y_cub.append(func_cub(x))
        line_cub.set_xdata(X)
        line_cub.set_ydata(Y_cub)
        
    x  = 1
    return line_sqr, line_cub,


   
anim = animation.FuncAnimation(fig,
                               func=animation_frame,
                               frames=range(0, 2*len(x_val)),
                               interval=50,
                               repeat=False)



plt.show()
  • Related