Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Closed
Description
Bug summary
The gif and mp4 are different from each other and from what is displayed. I was also unable to enlarge the central graphic.
Code for reproduction
importosimportnumpyasnpimportmatplotlib.pyplotaspltfrommatplotlib.animationimportFuncAnimationfrommatplotlib.backends.backend_pdfimportPdfPagesimportnumpy.randomasrdimportmatplotlibfrommatplotlib.animationimportPillowWriter,FFMpegWritermatplotlib.use('Qt5Agg')# Paramètres de la simulationN=1000# Nombre de particulesT=1000# Nombre de pas de calcull=200# Taille de la simulationdt=0.05# Pas de temps simulationa=1# Paspos=np.array([[0,0]]*N)# Tableau des positions de chaque pointstep=np.linspace(0,T,T)# Tableau de T valeursmx=np.zeros(T)# Le tableau qui contient la moyenne des positionsmy=np.zeros(T)stdx=np.zeros(len(step))# Le tableau qui contient l'écart-type des positionsstdy=np.zeros(len(step))# Création du dossier pour les imagesifnotos.path.exists(f"images_N{N}"):os.makedirs(f"images_N{N}")defactualise_position(M):p= [(M[0],M[1]+a), (M[0],M[1]-a), (M[0]+a,M[1]), (M[0]-a,M[1])]returnp[rd.choice([0,1,2,3])]# Paramètres graphiquesplt.ion()# Mode interactif activé pour Spyderfig=plt.figure(figsize=(14,24))# Taille de la figure# Ajout des sous-graphes (3 lignes, 2 colonnes) avec des espacements ajustésax1=fig.add_subplot(3,2, (1,2))# Le premier graphique occupe toute la largeurax2=fig.add_subplot(3,2,3)# Deuxième ligne, première colonneax3=fig.add_subplot(3,2,4)# Deuxième ligne, deuxième colonneax4=fig.add_subplot(3,2,5)# Troisième ligne, première colonneax5=fig.add_subplot(3,2,6)# Troisième ligne, deuxième colonne# Ajout du titre principalfig.suptitle(f"Simulation de diffusion pour N ={N} particules",fontsize=20,y=0.97)# Réorganisation des titresax1.set_title("Position des particules",fontsize=16)ax2.set_title("Moyenne des positions $<x>$",fontsize=14)ax3.set_title("Écart-type des positions $<x^2>$",fontsize=14)ax4.set_title("Moyenne des positions $<y>$",fontsize=14)ax5.set_title("Écart-type des positions $<y^2>$",fontsize=14)# Configuration des axesax1.set_xlim(-l//2,l//2)ax1.set_ylim(-l//2,l//2)ax1.set_xlabel("x",fontsize=12)ax1.set_ylabel("y",fontsize=12)ax2.set_ylabel("$<x>$",fontsize=12)ax2.set_xlabel("$t$",fontsize=12)ax3.set_ylabel("$<x^2>$",fontsize=12)ax3.set_xlabel("$t$",fontsize=12)ax4.set_ylabel("$<y>$",fontsize=12)ax4.set_xlabel("$t$",fontsize=12)ax5.set_ylabel("$<y^2>$",fontsize=12)ax5.set_xlabel("$t$",fontsize=12)# Assurer un aspect carré pour le graphique 1 (Position des particules)ax1.set_aspect('equal',adjustable='box')# Grillesforaxisin [ax1,ax2,ax3,ax4,ax5]:axis.grid(True)# Ajustement des espacements entre les sous-graphiquesfig.subplots_adjust(hspace=0.4,wspace=0.2)# Initialisation des graphiquespoints,=ax1.plot([], [],'bo',ms=3)linex,=ax2.plot([], [],c='r')line_stdx,=ax3.plot([], [],c='g')liney,=ax4.plot([], [],c='r')line_stdy,=ax5.plot([], [],c='g')definit():points.set_data([], [])linex.set_data([], [])line_stdx.set_data([], [])liney.set_data([], [])line_stdy.set_data([], [])returnpoints,linex,line_stdx,liney,line_stdydefanimate(i):globalpospos=np.array([actualise_position(M)forMinpos])points.set_data(pos[:,0],pos[:,1])mx[i]=np.mean(pos[:,0])my[i]=np.mean(pos[:,1])stdx[i]=np.var(pos[:,0])stdy[i]=np.var(pos[:,1])linex.set_data(step[:i]*dt,mx[:i])line_stdx.set_data(step[:i]*dt,stdx[:i])liney.set_data(step[:i]*dt,my[:i])line_stdy.set_data(step[:i]*dt,stdy[:i])# Ajuster les limites pour chaque graphiqueax2.set_xlim(0, (i+1)*dt)ax2.set_ylim(min(mx[:i+1])-0.5,max(mx[:i+1])+0.5)ax3.set_xlim(0, (i+1)*dt)ax3.set_ylim(0,max(stdx[:i+1])+0.5)ax4.set_xlim(0, (i+1)*dt)ax4.set_ylim(min(my[:i+1])-0.5,max(my[:i+1])+0.5)ax5.set_xlim(0, (i+1)*dt)ax5.set_ylim(0,max(stdy[:i+1])+0.5)# Sauvegarder une image toutes les 10 itérationsifi%10==0:fig.savefig(f"images_N{N}/step_N{N}_{i:04d}.png",bbox_inches='tight')returnpoints,linex,line_stdx,liney,line_stdy# Modifier la taille pour être divisible par 2width,height=fig.get_size_inches()width,height=int(width*fig.dpi),int(height*fig.dpi)ifheight%2!=0:height+=1ifwidth%2!=0:width+=1fig.set_size_inches(width/fig.dpi,height/fig.dpi)# Créer l'animationani=FuncAnimation(fig,animate,frames=T,init_func=init,interval=dt*1000,repeat=False,blit=False)# Enregistrer d'abord l'animation dans le format GIFgif_writer=PillowWriter(fps=30)ani.save(f"diffusion_N{N}.gif",writer=gif_writer)# Ensuite, enregistrer dans le format MP4mp4_writer=FFMpegWriter(fps=30)ani.save(f"diffusion_N{N}.mp4",writer=mp4_writer)plt.show(block=True)# Sauvegarde des images dans un PDFwithPdfPages(f"animation_images_N{N}.pdf")aspdf:forimage_fileinsorted(os.listdir(f"images_N{N}")):ifimage_file.endswith(".png"):img=plt.imread(f"images_N{N}/{image_file}")fig_img,ax=plt.subplots(figsize=(12,8))ax.imshow(img)ax.axis('off')pdf.savefig(fig_img,dpi=300,bbox_inches='tight')plt.close(fig_img)
Actual outcome
diffusion_N1000.mp4
animation_images_N1000_compressed.pdf
Expected outcome
A simulation that starts with all the particles in the center and in the graph, and in the pdf, and in the mp4 and gif, as given by this program.
importosimportnumpyasnpimportmatplotlib.pyplotaspltfrommatplotlib.animationimportFuncAnimationimportnumpy.randomasrdimportmatplotlibmatplotlib.use('Qt5Agg')# Paramètres de la simulationN=1000# Nombre de particulesT=1000# Nombre de pas de calcull=200# Taille de la simulationdt=0.05# Pas de temps simulationa=1# Paspos=np.array([[0,0]]*N)# Tableau des positions de chaque pointstep=np.linspace(0,T,T)# Tableau de T valeursmx=np.zeros(T)# Le tableau qui contient la moyenne des positionsmy=np.zeros(T)stdx=np.zeros(len(step))# Le tableau qui contient l'écart-type des positionsstdy=np.zeros(len(step))# Création du dossier pour les imagesifnotos.path.exists(f"images_N{N}"):os.makedirs(f"images_N{N}")defactualise_position(M):p= [(M[0],M[1]+a), (M[0],M[1]-a), (M[0]+a,M[1]), (M[0]-a,M[1])]returnp[rd.choice([0,1,2,3])]# Paramètres graphiquesplt.ion()# Mode interactif activé pour Spyderfig=plt.figure(figsize=(14,24))# Taille de la figure# Ajout des sous-graphes (3 lignes, 2 colonnes) avec des espacements ajustésax1=fig.add_subplot(3,2, (1,2))# Le premier graphique occupe toute la largeurax2=fig.add_subplot(3,2,3)# Deuxième ligne, première colonneax3=fig.add_subplot(3,2,4)# Deuxième ligne, deuxième colonneax4=fig.add_subplot(3,2,5)# Troisième ligne, première colonneax5=fig.add_subplot(3,2,6)# Troisième ligne, deuxième colonne# Ajout du titre principalfig.suptitle(f"Simulation de diffusion pour N ={N} particules",fontsize=20,y=0.97)# Réorganisation des titresax1.set_title("Position des particules",fontsize=16)ax2.set_title("Moyenne des positions $<x>$",fontsize=14)ax3.set_title("Écart-type des positions $<x^2>$",fontsize=14)ax4.set_title("Moyenne des positions $<y>$",fontsize=14)ax5.set_title("Écart-type des positions $<y^2>$",fontsize=14)# Configuration des axesax1.set_xlim(-l//2,l//2)ax1.set_ylim(-l//2,l//2)ax1.set_xlabel("x",fontsize=12)ax1.set_ylabel("y",fontsize=12)ax2.set_ylabel("$<x>$",fontsize=12)ax2.set_xlabel("$t$",fontsize=12)ax3.set_ylabel("$<x^2>$",fontsize=12)ax3.set_xlabel("$t$",fontsize=12)ax4.set_ylabel("$<y>$",fontsize=12)ax4.set_xlabel("$t$",fontsize=12)ax5.set_ylabel("$<y^2>$",fontsize=12)ax5.set_xlabel("$t$",fontsize=12)# Assurer un aspect carré pour le graphique 1 (Position des particules)ax1.set_aspect('equal',adjustable='box')# Grillesforaxisin [ax1,ax2,ax3,ax4,ax5]:axis.grid(True)# Ajustement des espacements entre les sous-graphiquesfig.subplots_adjust(hspace=0.4,wspace=0.2)# Initialisation des graphiquespoints,=ax1.plot([], [],'bo',ms=3)linex,=ax2.plot([], [],c='r')line_stdx,=ax3.plot([], [],c='g')liney,=ax4.plot([], [],c='r')line_stdy,=ax5.plot([], [],c='g')definit():points.set_data([], [])linex.set_data([], [])line_stdx.set_data([], [])liney.set_data([], [])line_stdy.set_data([], [])returnpoints,linex,line_stdx,liney,line_stdydefanimate(i):globalpospos=np.array([actualise_position(M)forMinpos])points.set_data(pos[:,0],pos[:,1])mx[i]=np.mean(pos[:,0])my[i]=np.mean(pos[:,1])stdx[i]=np.var(pos[:,0])stdy[i]=np.var(pos[:,1])linex.set_data(step[:i]*dt,mx[:i])line_stdx.set_data(step[:i]*dt,stdx[:i])liney.set_data(step[:i]*dt,my[:i])line_stdy.set_data(step[:i]*dt,stdy[:i])ax2.set_xlim(0, (i+1)*dt)ax2.set_ylim(min(mx[:i+1])-0.5,max(mx[:i+1])+0.5)ax3.set_xlim(0, (i+1)*dt)ax3.set_ylim(0,max(stdx[:i+1])+0.5)ax4.set_xlim(0, (i+1)*dt)ax4.set_ylim(min(my[:i+1])-0.5,max(my[:i+1])+0.5)ax5.set_xlim(0, (i+1)*dt)ax5.set_ylim(0,max(stdy[:i+1])+0.5)returnpoints,linex,line_stdx,liney,line_stdyani=FuncAnimation(fig,animate,frames=T,init_func=init,interval=dt*1000,repeat=False,blit=False)plt.show(block=True)
Additional information
I am using Spyder.
Operating system
Windows 11
Matplotlib Version
3.9.3
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
3.11.10
Jupyter version
No response
Installation
conda