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

Tkinter Python Discussion :

Graphique en temps réel


Sujet :

Tkinter Python

  1. #1
    Membre du Club
    Femme Profil pro
    Etudiante
    Inscrit en
    Mai 2016
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Etudiante

    Informations forums :
    Inscription : Mai 2016
    Messages : 87
    Points : 43
    Points
    43
    Par défaut Graphique en temps réel
    Bonjour,

    Je souhaite afficher un graphique en temps réel de valeurs provenant d'un convertisseur et ceci sur une interface graphique Tkinter.

    Je sais qu'il existe un module matplotlib permettant la création de graphique.

    Ce qui m'améne à vous demander, comment afficher toutes mes valeurs en fonction du temps de facon continu, dans mon interface Tkinter?

    Merci d'avance.

    Cordialement.

  2. #2
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2013
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 156
    Points : 218
    Points
    218
    Par défaut
    Bonjour,

    Je ne connais pas la volumétrie des données que tu veux afficher en temps réel, mais matplotlib n'est pas réputé pour être bon en temps réel. ( J'utilise plutôt PyQtGraph, mais je pense pas que ça marche avec TKinter)

    Ensuite pour ce qui est du comment, bha ça dépend de ton besoin.

    Une boucle while ? Des signaux ? ça dépend de ta source de données, de la fréquence de réception ...
    Une recherche google avec ces mots clef : "python real time graph" donne déjà pas mal d'exemple notamment avec MatplotLib

    https://pythonprogramming.net/python...dating-graphs/
    https://www.lebsanft.org/?p=48
    ...

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par Cerise22 Voir le message
    Je sais qu'il existe un module matplotlib permettant la création de graphique.

    Ce qui m'améne à vous demander, comment afficher toutes mes valeurs en fonction du temps de facon continu, dans mon interface Tkinter?
    Par défaut, matplotlib fait ses graphiques avec Tkinter. Pour voir les animations qu'on peut réaliser voir les exemples..

    Pour ce qui est de Tkinter, les graphiques se réalisent avec le widget Canvas. Et si vous voulez que çà "bouge", il suffit de mettre à jour l'affichage plus ou moins rapidement. Les techniques sont identiques quelques soient le type d'animation (jeu, coubes,...). Voir par exemple cette discussion récente.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre du Club
    Femme Profil pro
    Etudiante
    Inscrit en
    Mai 2016
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Etudiante

    Informations forums :
    Inscription : Mai 2016
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Bonjour,

    Merci pour votre retour.

    J'ai commencé à réaliser ce programme ci-dessous, mais le probléme est que je ne sais pas si la méthode que j'applique pour afficher le graph dans le canvas est correct? Et aussi, concernant les valeurs en abscisses, je souhaiterais mettre un écrat tous les 0.5s car je fais l'acquisition toutes les 0.5s, comment faire?

    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
     
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    import time
    import tkinter
    from tkinter import *
     
     
    valueADCx= []
    valadc=[]
    def ADC ():
        global  valueADC, valueADCx, valadc
     
        #Initialisation du deque
        SIZE = 10
        fil = deque(maxlen=SIZE)
     
        for i in range(10):
            vals= adc.read_adc(1, gain=GAIN)
            fil.appendleft(vals)
            if len(fil) == SIZE:  #Une fois remplie, calcul de la moyenne
                valueADCx= sum(fil)/SIZE
                valueADCy= valueADCx 
                valueADC.set('%6.1f'%valueADCy)
                time.sleep(0.5)
     
        label9.after(100,ADC)
        #Création variable qui sera affiché dans fichier texte
        valadc.append(round(valueADCx,1))
     
     
    def animate ():
        fig = plt.figure()
        ax = fig.add_subplot(1,1,1)
     
        #temps abscisses, comment récuperer?
        x=
        y=valadc.append(round(valueADCx,1))
        xlabel("Temps (s)")
        ylabel("Valeurs ADC")
        xar = []
        yar = []
        #Affichage continu valeurs
        xar.append(int(x))
        yar.append(int(y))
        ax.plot(xar,yar)
        #Afficher valeur toutes les 0.5s
        ani = animation.FuncAnimation(fig, animate, interval=500)
        figure.canvas.draw()
        plt.show()
     
     
    fenetre = Tk()
     
    #Bouton Afficher les valeurs du capteurs deplacement
    bouton3=Button(frame1,text="ADC", command= ADC, padx=10, pady=10, width=10)
    bouton3.config(font=('arial', 12, 'bold'))
    bouton3.grid(row=2, column=1)
    valueADC=StringVar()
    label9=Label(frame1, textvariable=valueADC, width=12, height=2)
    label9.config(font=('arial', 15, 'bold'))
    label9.grid(row=2, column=2)
    #label9.config(text=valueADC)
     
    #Generation du graphique 
    bouton2=Button(fenetre, text='Graphique', command=animate)
    bouton2.grid(row=0,column=1)
     
     
    # Création d'un widget Canvas (zone graphique)
    Canevas = Canvas(fenetre)
    Canevas.grid(row=0, column=2)
     
    #Bouton quitter
    bouton4=Button(fenetre,text="Quitter", command=fenetre.destroy,width=10, height=2, padx=10, pady=10)
    bouton4.config(font=('arial', 12, 'bold'))
    bouton4.grid(row=1,column=1)
     
    fenetre.mainloop()
    En vous remerciant par avance.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Tout cela est fort compliqué pourquoi ne pas partir de cet exemple. Vous paramétrez l'appel à la fonction "anim" via interval (qui doit être en Ms) qui fera lecture et mise à jour des données à afficher.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre du Club
    Femme Profil pro
    Etudiante
    Inscrit en
    Mai 2016
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Etudiante

    Informations forums :
    Inscription : Mai 2016
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Je ne vois pas comment appliquer concretement cet exemple à mon cas...


    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
     
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
     
    fig, ax = plt.subplots()
     
    x = np.arange(0, 2*np.pi, 0.01)        # x-array
    line, = ax.plot(x, np.sin(x))
     
    def animate(i):
        line.set_ydata(np.sin(x+i/10.0))  # update the data
        return line,
     
    #Init only required for blitting to give a clean slate.
    def init():
        line.set_ydata(np.ma.array(x, mask=True))
        return line,
     
    ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init, interval=25, blit=True)
    plt.show()
    Pourriez vous m'aider?

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par Cerise22 Voir le message
    Je ne vois pas comment appliquer concretement cet exemple à mon cas...


    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
     
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
     
    fig, ax = plt.subplots()
     
    x = np.arange(0, 2*np.pi, 0.01)        # x-array
    line, = ax.plot(x, np.sin(x))
     
    def animate(i):
        line.set_ydata(np.sin(x+i/10.0))  # update the data
        return line,
     
    #Init only required for blitting to give a clean slate.
    def init():
        line.set_ydata(np.ma.array(x, mask=True))
        return line,
     
    ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init, interval=25, blit=True)
    plt.show()
    Pourriez vous m'aider?
    Oubliez un peu le code que vous voulez faire.
    Essayez de vous approprier ce que fait cet exemple.
    Vous pourriez commencer par remplacer np.sin par une fonction à vous y = f(x) qui sera appelée par "anim" (toutes les 0.5s).
    note: Si vous écrivez une fonction style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def f(x):
          ...
          return y
    Ca n'en voudra pas car çà travaille avec des tableaux. Il faudra emballer votre "f" par "g" définit:
    Au bout du bout, votre fonction "f" ira lire la valeur suivante dans la balance (mais çà c'est pour plus tard...)

    Une fois que vous aurez un peu compris comment çà fonctionne, vous allez pouvoir simplifier pour afficher directement une liste de valeurs qui bougent à la place d'un array numpy...
    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
    ## import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
     
    COUNT = 10
     
    fig, ax = plt.subplots()
     
    values = [ x * 0.1 for x in range(COUNT) ] 
    x = [ 0.5*x for x in range(COUNT*3) ]
     
    ## ax.set_xticks(x[:COUNT])
    ## ax.set_xticklabels(x[:COUNT])
    line, = ax.plot(x[:COUNT], values)
     
    def animate(i):
        values.append(values.pop(0))
        line.set_ydata(values)
     
        ## x.append(x.pop(0))
        ## ax.set_xticklabels(x[:COUNT])  
        return line,
     
    ani = animation.FuncAnimation(fig, animate, interval=500)
     
    plt.show()
    Une fois arrivé là, vous pourrez voir comment intégrer votre liste.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre du Club
    Femme Profil pro
    Etudiante
    Inscrit en
    Mai 2016
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Etudiante

    Informations forums :
    Inscription : Mai 2016
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Bonjour,

    Je récapitule l'objet de mon projet:
    Je fais l'acquisition de donnée (en continu) d'un capteur de déplacement via L'ADC. Pour ce faire, j'utilise la méthode "readADC" pour lire la valeur sur la voie 1 de mon ADC. Je fais la moyenne glissante sur 10 valeurs, tous le 0.5s, la nouvelle valeur aquise se rajoute à gauche de ma variable list (via la methode deque). Ensuite, j'affiche cette valeur moyenne dans un label via Tkinter.
    Pour la suite de ce projet, je souhaite afficher la représentation graphique de ces valeurs moyennées en fonction du temps, sur la même interface graphique.

    Après plusieurs difficultés rencontrées et après de longue réflexion, j'ai décidé (comme vous me l'avez conseillé wiztricks) de commencer par un programme simple. J'ai donc mis en place un programme permettant l'affichage d'une courbe provenant de la géneration de nombres aléatoire, pour ensuite l'appliquer à mon cas (lecture des données ADC).

    Résultats:
    J'ai réussi à affficher dans le graph les valeurs générées par l'ADC, mais lorsque je souhaite afficher la valeur provenant du résultat de la moyenne sur 10 valeurs: j'obtient un message d'erreur: "ValueError: x and y must have same first dimension". Note: j'ai bien déclaré la variable moyenne en globale) Comment faire pour afficher ces valeurs 'moyenne'?

    Et aussi, au lieu d'afficher en abscisse la varibale "SIZE", je voudrais afficher le "temps entre chaque affichage", soit 0.5s, donc anim =FuncAnimation(fig, compute_average, interval=500)... mais je ne sais pas comment faire non plus pour avoir un rafraichissement toutes les 0.5s du graph?

    Dans mon programme j'ai indiqué une limte d'axe (400), mais je voudrais que la limites des axes se fasse automatiquement, selon les valeurs obtenue, comment faire?

    Si vous pouviez m'aider svp à résoudre ces points?

    Voici le programme:

    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
     
    import tkinter as tk
    from random import randint
    from collections import deque
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    from matplotlib.animation import FuncAnimation
    from matplotlib import style
    """
    import Adafruit_ADS1x15
     
    #Configuration ports:
    # Creation de ADS1015 ADC (12-bit)
    adc = Adafruit_ADS1x15.ADS1015()
    adc = Adafruit_ADS1x15.ADS1015(address=0x49, busnum=1)
    GAIN = 1
    """
     
    SIZE = 10
    def ADC(dt):
     
        #vals= adc.read_adc(1, gain=GAIN) #Lecture ADC, test sans nbr aléatoire
        #valeurs.appendleft(vals)
     
        valeurs.appendleft(randint(1, 100)) #Géneration nombres aléatoire, test sans ADC
     
     
        moyenne = sum(valeurs) / len(valeurs)
        listbox.delete(0, tk.END)
        for val in valeurs:
            listbox.insert(tk.END, val)
        moyenne_texte.set("Moyenne : {:.2f}".format(moyenne))
        line.set_data(range(SIZE), valeurs)
     
     
     
    app = tk.Tk()
    app.wm_title("Lecture de valeurs en continu")
    valeurs = deque([0] * SIZE, maxlen=SIZE)
     
    moyenne_texte = tk.StringVar()
    moyenne_texte.set("Moyenne :")
    moyenne_label = tk.Label(app, textvariable=moyenne_texte, font=('', 16),
        fg="sea green")
    moyenne_label.grid(row=0, column=0, padx=5, pady=5)
     
    listbox = tk.Listbox(app)
    listbox.grid(row=1, column=0, sticky=tk.N+tk.EW, padx=5, pady=5)
     
    style.use("ggplot")
    fig = Figure(figsize=(8, 5), dpi=96)
    ax = fig.add_subplot(111)
    ax.set_xlim(0, SIZE)
    ax.set_ylim(0, 400)
    ax.set_xlabel("Temps (s)")
    ax.set_ylabel("Valeur (points)")
    line, = ax.plot(range(len(valeurs)), valeurs, 'b-o')
    fig.set_tight_layout(True)
     
    canvas = FigureCanvasTkAgg(fig, master=app)
    canvas.show()
    canvas.get_tk_widget().grid(row=0, column=1, rowspan=2, sticky=tk.NSEW)
     
    app.grid_columnconfigure(0, weight=1)
    app.grid_columnconfigure(1, weight=1)
    app.grid_rowconfigure(1, weight=1)
     
    anim = FuncAnimation(fig, ADC, interval=500)
    app.mainloop()
    Merci d'avance.

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par Cerise22 Voir le message
    Après plusieurs difficultés rencontrées et après de longue réflexion, j'ai décidé (comme vous me l'avez conseillé wiztricks) de commencer par un programme simple. J'ai donc mis en place un programme permettant l'affichage d'une courbe provenant de la géneration de nombres aléatoire, pour ensuite l'appliquer à mon cas (lecture des données ADC).
    Dan737 s'est fait plaisir à vous écrire ce code sur le forum OCR où vous avez ouvert une discussion en demandant de vous aider à modifier le code que vous avez récupéré ici. Le seul seul intérêt de ces codes est de vous montrer qu'on peut le faire pour vous motiver à ouvrir la documentation et comprendre comment çà fonctionne.

    Si vous vous amusez à le modifier avant d'avoir compris, c'est comme l'éléphant dans un magasin de porcelaine: çà craint.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre du Club
    Femme Profil pro
    Etudiante
    Inscrit en
    Mai 2016
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Etudiante

    Informations forums :
    Inscription : Mai 2016
    Messages : 87
    Points : 43
    Points
    43
    Par défaut
    Oui en effet, je me suis basé sur l'exemple qu'il m'a gentillement proposé. Que j'ai ensuite essayer de comprendre pour le modifier et l'appliquer à mon projet...

    Concernant, le message d'erreur obtenue: je pense qu'il faut mettre les deux variables x et y donc moyenne et le temps en type list, ai je tort?

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par Cerise22 Voir le message
    Concernant, le message d'erreur obtenue: je pense qu'il faut mettre les deux variables x et y donc moyenne et le temps en type list, ai je tort?
    Vous essayez et si çà ne fonctionne pas, vous relisez la documentation.
    note: Si en une semaine vous n'avez pas été capable d'écrire cela par vous même, ce n'est pas en une demi journée que vous allez comprendre le code qu'on vous a donné: si c'était le cas, vous seriez un peu plus sûre de vous...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [AJAX] Tracer graphique en temps réel
    Par Emcy dans le forum Général JavaScript
    Réponses: 22
    Dernier message: 19/02/2009, 11h33
  2. Interface Graphique en Temps réel
    Par masenco dans le forum C++Builder
    Réponses: 14
    Dernier message: 18/04/2008, 15h40
  3. bibliothèques AJAX pour graphiques en temps réel
    Par clebig dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 07/02/2008, 20h08
  4. Création fenêtre graphique en temps réel
    Par Juanes dans le forum Visual C++
    Réponses: 1
    Dernier message: 26/06/2007, 14h57
  5. Bibliothèque graphique 2D temps réel
    Par gk14fire dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 25/05/2007, 10h27

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