0

If have implemented an animation for the Clifford attractor

xn+1 = sin(a yn) + c cos(a xn)

yn+1 = sin(b xn) + d cos(b yn)

The animation varies the parameters and indicates this through a moving red disk.

To get a back and for movement I have introduced a step direction which is flipped each time maxframes was reached, i.e. the counter has value 0.

Unfortunately the animate function seems - or is - called always twice, why?

I have covered this problem and now there is the main problem!

Only one wy is stored in the movie ...

a,b,c,d = -1.4,  1.6, 1.0,  0.7 # Parameter
xmin,xmax,ymin,ymax=-2,2.5,-2,2

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation as ani
from timeit import default_timer as timer

fig, ax = plt.subplots(figsize=(6,6))

nmax=15000; x0,y0=xmin,ymin
XYc = np.zeros((nmax,3))
maxframes=200
deltax=(xmax-xmin)/maxframes
deltay=(ymax-ymin)/maxframes

Deltapar = 1
deltapar = 2*Deltapar/maxframes
amin,bmin,cmin,dmin = a-Deltapar, b-Deltapar, c-Deltapar, d-Deltapar
amax,bmax,cmax,dmax = a+Deltapar, b+Deltapar, c+Deltapar, d+Deltapar

from numba import jit

@jit
def iteration(a,b,c,d,x,y,XYc):
    XYc[0]=x,y,x-x
    for i in range(1,nmax):
        x,y = np.sin(a*y) + c*np.cos(a*x),np.sin(b*x) + d*np.cos(b*y)
        XYc[i]=x,y,i/nmax

iteration(a,b,c,d,x0,y0,XYc)
title='Clifford Attractor: a=%.2f, b=%.2f, c=%.2f, d=%.2f'%(a,b,c,d)
ax.set_title(title)
ax.set_xlim(xmin,xmax)
ax.set_ylim(ymin,ymax)
plt.tight_layout()
myCmap = plt.cm.get_cmap('gist_ncar_r')

dots,=ax.plot(XYc[:,0],XYc[:,1],",",linewidth=0.1)
dotm,=ax.plot([xmin],[ymin], marker="o", color="r")

step=1
anicount=0

def animate(i):
    global anicount, step
    if i==0:        
        anicount+=1        
        if anicount%2==0: step = -step
        print("#",anicount," ",step)

    if step==1:
        am=amin+i*deltapar
        xm=xmin+i*deltax
        ym=ymin+i*deltay
    else:
        am=amax-i*deltapar
        xm=xmax-i*deltax 
        ym=ymax-i*deltay

    iteration(am,b,c,d,x0,y0,XYc)
    dots.set_data(XYc[:,0],XYc[:,1])
    dotm.set_data([xm],[ym])

    return dotm, dots,

anim = ani.FuncAnimation(
    fig, animate, frames=maxframes, interval=10, blit=True)       

fname='cliffordattr'
#anim.save(fname+'.mp4')
#plt.savefig(fname+'.jpg')
#plt.savefig(fname+'.eps')
plt.show()

I have tried to use the extra_anim=[...,...] option for savefig

anim1.save(fname+'1.mp4', fps=30)
anim2.save(fname+'2.mp4', fps=30)
anim1.save(fname+'12.mp4', fps=30,extra_anim=[anim1,anim2,])

But still only one direction gets to the movie.

  • How can I save several animate cycles in one movie???
  • How can I save different animations in one movie??
  • Why is animate called twice?

Any help is appreciated

TKS
  • 1
  • 1
  • I think this is currently a bug in matplotlib. I ran into this and posted about it on the matpltolib discourse: https://discourse.matplotlib.org/t/how-to-prevent-funcanimation-looping-a-single-time-after-save/21680 which you may find interesting to read – Ianhi Jan 05 '21 at 21:47
  • Thanks for your reply! I have combined yout hint [https://discourse.matplotlib.org/t/how-to-prevent-funcanimation-looping-a-single-time-after-save/21680/2](discurse.matplotlib.org), i.e. `... repeat=false); fig.canvas.draw();anim.event_source.stop();anim.save(fname+'1.mp4');fig.canvas.draw();anim.save(fname+'2.mp4')` and then the solution from [https://stackoverflow.com/questions/56920546/combine-mp4-files-by-order-based-on-number-from-filenames-in-python](SE ...) and got the total animation. Maybe not the most elegant solution, but it works for now :-) – TKS Jan 06 '21 at 04:40
  • I never did open a github issue for this. If you would like to open an issue feel free take my example from discourse and mention this SO post. I'm sure the matplotlib devs would appreciate it :) – Ianhi Jan 06 '21 at 16:34

0 Answers0