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

Python Discussion :

matplotlib slider widget [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut matplotlib slider widget
    Bonsoir, je me casse la tête depuis quelques heures.
    Je me suis inspiré d'un script de démo mais comme je ne comprends pas tout, j'ai du mal à l'adapter.
    Je souhaite tracer un graphe avec possibilité de faire varier les paramètres avec des sliders.
    Voici mon code :
    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
    71
    72
    73
    74
    75
    76
    77
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.widgets import Slider, Button
    fig, ax = plt.subplots()
    plt.subplots_adjust(left=0.25, bottom=0.25)
     
    # coefficients stoechiométriques
    nu_C3H8 = 1
    nu_O2 = 5
    nu_CO2 = 3
    nu_H2O = 4
     
    # Quantités de matières initiales (en mol)
    no_C3H8 = 0.1
    no_O2 = 0.1
    no_CO2 = 0
    no_H2O = 0
     
    # Avancement maximal
    x_max_C3H8 = no_C3H8 / nu_C3H8
    x_max_O2 = no_O2 / nu_O2
    if x_max_C3H8 < x_max_O2 :
        x_max = x_max_C3H8
    else :
        x_max = x_max_O2
     
    # Listes de quantités de matière
    x = np.arange(0, x_max, x_max/100)
    n_C3H8 = no_C3H8-nu_C3H8*x
    n_O2 = no_O2 - nu_O2*x
    n_CO2 = no_CO2 + nu_CO2*x
    n_H2O = no_H2O + nu_H2O*x
     
    ax_C3H8 = plt.axes([0.25, 0.1, 0.65, 0.03])
    #ax_O2 = plt.axes([0.25, 0.15, 0.65, 0.03])
    s_C3H8 = Slider(ax_C3H8, 'Propane', 0, 10.0, valinit=no_C3H8)
    #s_O2 = Slider(ax_O2, 'Dioxygène', 0, 10.0, valinit=no_O2)
     
    # Courbes
    l1, = plt.plot(x, n_C3H8, label="C3H8",lw=2)
    l2, = plt.plot(x, n_O2, label="O2")
    l3, = plt.plot(x, n_CO2, label="CO2")
    l4, = plt.plot(x, n_H2O, label="H2O")
     
    liste_des_n_max = [max(n_C3H8), max(n_O2), max(n_CO2), max(n_H2O)]
    n_max = 1.1*max(liste_des_n_max)
     
    plt.xlabel("Avancement (mol)")
    plt.ylabel("Quantité de matière (mol)")
    plt.title("Evolution de la réaction de combustion")
    plt.legend(loc='upper center')
    plt.axis([0,x_max,0,n_max])
    plt.grid()
     
    def update(val):
    #    O2 = s_O2.val
        C3H8 = s_C3H8.val
        l1.set_ydata(C3H8-nu_C3H8*np.arange(0, x_max, x_max/100))
    #    l2.set_ydata(O2-nu_O2*np.arange(0, x_max, x_max/100))
    #    l3.set_ydata(n_CO2+nu_CO2*np.arange(0, x_max, x_max/100))
    #    l4.set_ydata(n_H2O+nu_H2O*np.arange(0, x_max, x_max/100))
        fig.canvas.draw_idle()
     
     
    s_C3H8.on_changed(update)
    #s_O2.on_changed(update)
     
    resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
    button = Button(resetax, 'Reset', hovercolor='0.975')
     
    def reset(event):
        s_C3H8.reset()
    #    s_O2.reset()
    button.on_clicked(reset)
     
    # Affichage
    plt.show()
    Il n'y a pas d'erreur mais le graphe est dans le slider, ce qui ne me convient pas...
    A mon avis, il y a d'autres problèmes mais tant que j'aurai celui-ci, je ne pourrai pas avancer.
    Si quelqu'un connaît ces trucs, je suis preneur.

  2. #2
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    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 : 662
    Par défaut
    Salut!

    Le problème me semble venir de la définition des axes. Il faut un ax principal dans lequel sont tracées toutes les courbes, un ax pour le slider et un autre pour le bouton reset. Ainsi on aurait ceci:
    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
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.widgets import Slider, Button
     
    fig, main_ax = plt.subplots()
    plt.subplots_adjust(left=0.25, bottom=0.25)
     
    # coefficients stoechiométriques
    nu_C3H8 = 1
    nu_O2 = 5
    nu_CO2 = 3
    nu_H2O = 4
     
    # Quantités de matières initiales (en mol)
    no_C3H8 = 0.1
    no_O2 = 0.1
    no_CO2 = 0
    no_H2O = 0
     
    # Avancement maximal
    x_max_C3H8 = no_C3H8 / nu_C3H8
    x_max_O2 = no_O2 / nu_O2
    if x_max_C3H8 < x_max_O2:
        x_max = x_max_C3H8
    else:
        x_max = x_max_O2
     
    # Listes de quantités de matière
    x = np.arange(0, x_max, x_max/100)
    n_C3H8 = no_C3H8-nu_C3H8*x
    n_O2 = no_O2 - nu_O2*x
    n_CO2 = no_CO2 + nu_CO2*x
    n_H2O = no_H2O + nu_H2O*x
     
    # Cree le slider dans un ax dédié
    ax_slider = plt.axes([0.10, 0.05, 0.80, 0.03])
    s_C3H8 = Slider(ax_slider, 'Propane', 0, 10.0, valinit=no_C3H8)
     
    # Courbes
    l1, = main_ax.plot(x, n_C3H8, label="C3H8", lw=2)
    l2, = main_ax.plot(x, n_O2, label="O2")
    l3, = main_ax.plot(x, n_CO2, label="CO2")
    l4, = main_ax.plot(x, n_H2O, label="H2O")
     
    liste_des_n_max = [max(n_C3H8), max(n_O2), max(n_CO2), max(n_H2O)]
    n_max = 1.1*max(liste_des_n_max)
     
    main_ax.set_title("Evolution de la réaction de combustion")
    main_ax.set_xlabel("Avancement (mol)")
    main_ax.set_ylabel("Quantité de matière (mol)")
    main_ax.legend(loc='upper center')
    main_ax.grid()
     
    def update(val):
        C3H8 = s_C3H8.val
        l1.set_ydata(C3H8-nu_C3H8*np.arange(0, x_max, x_max/100))
        plt.draw()
     
    s_C3H8.on_changed(update)
     
    # Cree un bouton reset
    resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
    button = Button(resetax, 'Reset', hovercolor='0.975')
    button.on_clicked(lambda event: s_C3H8.reset())
     
    # Affichage
    plt.show()
    J'ai enlevé les parties commentées pour plus de lisibilité, et renommé certain ax. Mais c'est juste pour mieux voir.

    J

  3. #3
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci Julien.
    Cela m'a débloqué.
    Par contre, je m'en doutais, j'ai d'autres soucis.
    En effet, je souhaite pouvoir modifier chacun de les paramètres et que la mise à jour se fasse pour tous les paramètres (notamment que x_max varie)
    Cela ressembler à de la programmation événementielle j'imagine et je coince à nouveau.
    Je suis rendu là :
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.widgets import Slider, Button
     
    fig, main_ax = plt.subplots()
    plt.subplots_adjust(left=0.2, bottom=0.4)
     
    # coefficients stoechiométriques
    nu_C3H8 = 1
    nu_O2 = 5
    nu_CO2 = 3
    nu_H2O = 4
     
    # Quantités de matières initiales (en mol)
    no_C3H8 = 1
    no_O2 = 1
    no_CO2 = 0
    no_H2O = 0
     
    # Avancement maximal
    x_max_C3H8 = no_C3H8 / nu_C3H8
    x_max_O2 = no_O2 / nu_O2
    if x_max_C3H8 < x_max_O2:
        x_max = x_max_C3H8
    else:
        x_max = x_max_O2
     
    # Listes de quantités de matière
    x = np.arange(0, x_max, x_max/100)
    n_C3H8 = no_C3H8-nu_C3H8*x
    n_O2 = no_O2 - nu_O2*x
    n_CO2 = no_CO2 + nu_CO2*x
    n_H2O = no_H2O + nu_H2O*x
     
    # Cree le slider dans un ax dédié
    ax_slider_C3H8 = plt.axes([0.10, 0.05, 0.80, 0.03])
    ax_slider_O2 = plt.axes([0.10, 0.1, 0.80, 0.03])
    ax_slider_CO2 = plt.axes([0.10, 0.15, 0.80, 0.03])
    ax_slider_H2O = plt.axes([0.10, 0.2, 0.80, 0.03])
    s_C3H8 = Slider(ax_slider_C3H8, 'Propane', 0, 10.0, valinit=no_C3H8)
    s_O2 = Slider(ax_slider_O2, 'Dioxygène', 0, 10.0, valinit=no_O2)
    s_CO2 = Slider(ax_slider_CO2, 'Dioxyde de carbone', 0, 10.0, valinit=no_CO2)
    s_H2O = Slider(ax_slider_H2O, 'Eau', 0, 10.0, valinit=no_H2O)
     
    # Courbes
    l1, = main_ax.plot(x, n_C3H8, label="C3H8", lw=2)
    l2, = main_ax.plot(x, n_O2, label="O2")
    l3, = main_ax.plot(x, n_CO2, label="CO2")
    l4, = main_ax.plot(x, n_H2O, label="H2O")
     
    liste_des_n_max = [max(n_C3H8), max(n_O2), max(n_CO2), max(n_H2O)]
    n_max = 1.1*max(liste_des_n_max)
     
    main_ax.set_title("Evolution de la réaction de combustion")
    main_ax.set_xlabel("Avancement (mol)")
    main_ax.set_ylabel("Quantité de matière (mol)")
    main_ax.legend(loc='upper center')
    main_ax.grid()
     
    def update(val):
        C3H8 = s_C3H8.val
        O2 = s_O2.val
        CO2 = s_CO2.val
        H2O = s_H2O.val
        l1.set_ydata(C3H8-nu_C3H8*np.arange(0, x_max, x_max/100))
        l2.set_ydata(O2-nu_O2*np.arange(0, x_max, x_max/100))
        l3.set_ydata(CO2+nu_CO2*np.arange(0, x_max, x_max/100))
        l4.set_ydata(H2O+nu_H2O*np.arange(0, x_max, x_max/100))
        plt.draw()
     
    s_C3H8.on_changed(update)
    s_O2.on_changed(update)
    s_CO2.on_changed(update)
    s_H2O.on_changed(update) 
     
    # Cree un bouton reset
    resetax = plt.axes([0.8, -0.02, 0.1, 0.04])
    button = Button(resetax, 'Reset', hovercolor='0.975')
    button.on_clicked(lambda event: s_C3H8.reset())
     
    # Affichage
    plt.show()

  4. #4
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    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 : 662
    Par défaut
    Citation Envoyé par marco056 Voir le message
    En effet, je souhaite pouvoir modifier chacun de les paramètres et que la mise à jour se fasse pour tous les paramètres (notamment que x_max varie)
    x_max varie comment et quand? Dans ton code je ne vois nul part une modification de cette variable. Je me demande si ce n'est pas plus propre de définir autant de fonctions update() que de sliders. En tout cas ce serait plus léger pour matplotlib car dans ton exemple la modification d'une des variables entraine la mise à jour de toutes les courbes. Bon, ça n'a va pas changer la face du monde non plus.

    J

  5. #5
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    x_max est défini entre les lignes 20 et 28.
    Je vais réfléchir à ta proposition.

  6. #6
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    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 : 662
    Par défaut
    Je passe à côté de quelque chose. x_max dépend de no_C3H8, nu_C3H8, no_O2 et nu_O2. Mais je n'ai pas l'impression que ces valeurs soient mises à jour à un moment. Ou alors c'est un ajout prévu?

    Si le graph devient trop complexe en terme de widgets, tu peux envisager de coder une petite interface graphique en tkinter. Je me suis récemment intéressé aux widgets dans un notebook jupyter. ça pourrait aussi être une alternative. https://towardsdatascience.com/bring...s-bc12e03f0916

    J

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/08/2014, 21h25
  2. Widget MatplotLib : problème d'affichage
    Par mokochan dans le forum PyQt
    Réponses: 18
    Dernier message: 24/02/2014, 15h46
  3. Réponses: 0
    Dernier message: 17/08/2012, 16h24
  4. Widget Date Slider
    Par frAydjwe dans le forum Android
    Réponses: 0
    Dernier message: 02/09/2011, 15h57
  5. [SWT]Eclipse Java : swt.widgets.Table
    Par watson dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 01/10/2003, 09h07

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