IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

Créer une animation avec matplotlib. [Python 3.X]


Sujet :

Calcul scientifique Python

  1. #1
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut Créer une animation avec matplotlib.
    Salut les pythons,

    j'ai essayer de passer un tout petit bout de code a la fonction de callback de matplotlib.animation.FuncAnimation().
    Bon le code et l'animation fonctionne seulement le problème est la fenêtre n'est pas rafraichis:
    les bars se mette au dessus des précédents sans effacer l'arrière plan alors si une nouvelle bar est plus petite que la précédente a la même place et bien l'on voit encore le haut de la bar d'avant...

    Je n'ai pas le code sous la mains mais je vous ai fait une version (qui ne fonctionne pas elle au niveau de l'animation) qui ressemble beaucoup a mon code qui se comportait comme décrit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #!/usr/bin/python3
     
    import matplotlib.pyplot    as plt
    import matplotlib.animation as ani
     
    from random import randint, uniform 
     
    fig, subplot= plt.subplots()
     
    def update(arg) :
      global subplot
     
     
      for v in range(0,10) :
     
        subplot.bar(v,randint(30,70),  color=(uniform(0.0, 1.0), uniform(0.0, 1.0), uniform(0.0, 1.0), 1.0) )
     
     
      return subplot
     
     
    ani.FuncAnimation(fig, update, interval=10, blit=False)
     
    plt.show()
    Ayant consulté les exemples de la documenation je crois que j'ai tout fait de travers. Car dans les exemples il emploies souvent des fonction retournant un itérateur de données passer comme argument frame a la fonction FuncAnimation qui nourrissent la fonction callback...

    Je crois que c'est ma méthodologie qui est en cause ?

    Tous conseil, explications est la bienvenues.
    Merci pour vos réponses éclairées.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  2. #2
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut Luke.

    Je peux peut-être t'aider car j'ai eu à faire une anim d'un graph 3d il n'y a pas longtemps. Fort heureusement j'ai conservé un code exemple fonctionnel. Le voice tel quel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    # -*- coding: utf-8 -*-
     
    """
    Animation of 3D matplotlib graph
    """
    import numpy as np
     
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import animation
     
    # Create some random data
    def randrange(n, vmin, vmax):
        return (vmax - vmin) * np.random.rand(n) + vmin
    n = 100
    xx = randrange(n, -50, 50)
    yy = randrange(n, -100, 100)
    zz = randrange(n, -50, 50)
     
    # Set up figure & 3D axis for animation
    fig = plt.figure()
    ax = fig.add_axes([0, 0, 1, 1], projection='3d')
    #ax.axis('off')
     
    # Set up points 
    pts = ax.plot([], [], [], 'o', c='k', ms=6)
     
    # Prepare the axes limits
    ax.set_xlim((-70, 70))
    ax.set_ylim((-70, 70))
    ax.set_zlim((-70, 70))
     
    # Initialization function: plot scatter graph 
    def init():
        pts[0].set_data(xx, yy)
        pts[0].set_3d_properties(zz)
        return pts
     
    # animation function.  This will be called sequentially with the frame number    
    def animate(i):
        ax.view_init(elev=10, azim=i)
        fig.canvas.draw()
        return pts
     
    # instantiate the animator.    
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=50, interval=30, blit=True)
     
    # Save as mp4. This requires mplayer or ffmpeg to be installed
    #anim.save('test.mp4', fps=15, extra_args=['-vcodec', 'libx264'])
     
    plt.show()
    L'idée générale est la suivante:
    1. On crée un objet figure
    2. On créé un subplot (objet axes) en projection 3d (bon jusque là on est bien)
    3. On crée un graph (chez moi ax.plot(), pour toi ) vide (les coordonnées sont des listes vides (peut être aussi des numpy array)
    4. On créé une fonction d'initialisation (là ça se corse). Elle fournie les coordonnées des points de mon scatter diagramme et renvoie le scatter modifié.
    5. Une fonction d'annimation. Cette fonction prend en paramètre un angle dans mon cas, l'angle d'observation (je fais juste une rotation autour d'un axe) et fait appel une méthode pour définir l'angle de vue de la figure. Là aussi on renvoie le scatter modifié.
    6. On créé l'annimation elle-même.


    Doit facilement être adaptable à ton cas avec des barres je pense.

    Ju

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2013
    Messages : 388
    Points : 692
    Points
    692
    Par défaut
    Tous conseil, explications est la bienvenues.
    La référence à l'objet FuncAnimation est perdue. Il faut l'affecter à une variable comme le fait Julien N :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    anim = animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=50, interval=30, blit=True)

  4. #4
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour votre aide les gars,

    peut-être faudrait il créer le plot avant la fonction de l'animation et appeler quelque chose comme set_data() dans la fonction d'animation pour animer.

    Car moi je crée des plots en boucle dans la fonction d'animation ce qui pose le problème suivant: l'écran n'est pas vidé de son contenus a chaque appel autrement dit les bars se superposent...

    Je vais essayer d'implémenter l'animation autrement.

    Merci encore pour votre aide.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  5. #5
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    Tu devrais parvenir à adapter le code suivant en function de tes besoins:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import matplotlib.pyplot as plt
    from matplotlib import animation
     
    from random import randint, uniform 
     
    n_bars = 100
     
    # Set up figure
    fig = plt.figure()
    ax = fig.add_subplot(111)
    # Need to set axis limits as at plot init bar heights are 0. No auto fit...
    ax.set_xlim((0, n_bars))
    ax.set_ylim((0, 100))
     
    # Initialization of the bar plot 
    bars = ax.bar(range(n_bars), [0 for i in range(n_bars)], align='center')
     
    # Animation function
    def animate(i):
        z = [randint(30, 70) for i in range(n_bars)]
        for bar, h in zip(bars, z):
            bar.set_height(h)
        fig.canvas.draw()
        return bars
     
    # Instantiate the animator.    
    anim = animation.FuncAnimation(fig, animate,
                                   frames=50, interval=30, blit=True)
     
    # Save as mp4. This requires mplayer or ffmpeg to be installed
    #anim.save('test.mp4', fps=15, extra_args=['-vcodec', 'libx264'])
     
    plt.show()
    ça "fonctionne". Je me suis passé d'une function init() finalement. Pour chaque frame (50 frames en boucle) la function animate() est appelée. Dans ce cas je génère des hauteurs au hasard pour chaque bar et je mets à jour ces bars grâce à set_height(). On doit pouvoir faire de meme avec la largeur et la couleur.

    Ju

  6. #6
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci beaucoup,

    entre-temps moi aussi je suis arriver a mes fins grâce au code suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    import numpy as np 
    import matplotlib.pyplot as plt
     
    from matplotlib.animation import FuncAnimation
     
    from random import uniform, randint
     
    fig = plt.figure(figsize=(8,6), dpi=80) # figsize in dots, dpi (dot per inch) so it result size is (8*80,6*80).   
     
    subplot = plt.subplot(1,1,1)  # Getting the subplot.
     
     
    def update(arg) :
      # Animation update screen function:
      # generate differents bars at every call.
     
      global subplot
     
      pos=[]
      datas=[]
      colors=[]
      for v in range(0,24) :
        # Generate the datas for the bars. 
        pos.append(v)
        datas.append(randint(5,24))
        colors.append( (uniform(0.0,1.0), uniform(0.0,1.0), uniform(0.0,1.0)) )
     
     
      # Set the bars and keep the returned value for function returning.  
      ret=subplot.bar(pos, datas, width=1.0, animated=True, color = colors, fill=True ) # Color.
     
     
      subplot.set_xticks([])  # X axes values marks.
      subplot.set_yticks([])  # Y axes values marks.    
     
     
      return ret  # Must be returned so that the screen is cleaned.
     
     
    def init_function() :
      # Animation initialisation function:
      # called one time at animation start.
     
      global subplot
     
     
      pos=[]
      datas=[]
      colors=[]
      for v in range(0,24) :
        # Generate the datas for the bars.
        pos.append(v)
        datas.append(randint(5,24))
        colors.append( (uniform(0.0,1.0), uniform(0.0,1.0), uniform(0.0,1.0)) )
     
     
      # Set the bars and keep the returned value for function returning.    
      ret=subplot.bar(pos, datas, width=1.0, animated=True, color = colors, fill=True ) # Color.
     
     
      subplot.set_xticks([])  # X axes values marks.
      subplot.set_yticks([])  # Y axes values marks.    
     
     
      return ret  # Must be returned so that the screen is cleaned.
     
     
    animation=FuncAnimation(fig , update,  interval=100, blit=True, frames=200, init_func=init_function)
     
    plt.show()
    Bon c'est moins compacte et la fonction d'initialisation (qui est un copier-coller de la fonction d'animation) est inutile je pense.

    Mais bon ca fonctionne.

    J'ai fait dans la foulé une animation avec un Scatter de 256 points chacun avec un marker, couleur, luminescence, etc.. différents.
    la difficultés était que l'on ne pas peut passer de tableaux de marker différents, alors je l'ai fait dans une boucle et ajoutant le Scatter courant au tableau ret et retourner celui-ci: cela fonctionne.

    Merci pour votre aide, les gars.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. créer une animation avec fortran
    Par Akina SORROW dans le forum Fortran
    Réponses: 6
    Dernier message: 17/07/2010, 15h44
  2. [FLASH MX2004] Lancer une anim avec des paramètres ??
    Par gchanteux dans le forum Flash
    Réponses: 4
    Dernier message: 23/03/2005, 17h49
  3. Réponses: 4
    Dernier message: 09/02/2005, 10h44
  4. Créer une grille avec centage
    Par lil_jam63 dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 16/08/2004, 16h21
  5. [Image]Créer une image avec JAVA 1.1
    Par burno dans le forum 2D
    Réponses: 4
    Dernier message: 11/08/2004, 09h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo