matplotlib plot automatisch in tkinter GUI refreshen

Fragen zu Tkinter.
Antworten
pencky
User
Beiträge: 1
Registriert: Donnerstag 11. Juni 2015, 09:22

Hallo Leute,

ich möchte gerne einen Polarplot in einer tkinter GUI refreshen. Dazu habe ich bisher folgenden Code erstellt:

Code: Alles auswählen

import matplotlib
matplotlibl.use('TkAgg')
import numpy as np
import matplotlib.pyplot as plt
from matplorlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
import tkinter.ttk as ttk

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self,master)
        self.createWidgets()

    def create Widgets(self):
       fig=plt.figure(figsize=(8,8))
       ax=fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
       canvas=FigureCanvasTkAgg(fig,master=root)
       canvas.get_tk_widget().grid(row=0,column=1)
       canvas.show()

       self.plotbutton=tk.Button(master=root, text="plot", command=self.plot)
       self.plotbutton.grid(row=0,column=0)

    def plot(self):
       for line in stdout: #infinite loop, reads data of a subprocess
           theta=line[1]
           r=line[2]
           ax.plot(theta,r,linestyle="None",maker='o')
           plt.show(block=False)
           plt.pause(0.001)
           plt.cla()
           #here set axes

root=tk.Tk()
app=Application(master=root)
app.mainloop()
In der for loop werden Daten in einer Endlosschleife aus einem Subprozess ausgelesen. Aus Gründen der Übersichtlichkeit hier weggelassen.
Nun ist momentan das Problem, dass er das ax-Objekt nicht kennt. Wenn ich nun der Funktion plot das canvas und ax-Objekt übergebe, funktionieren die Befehle .show() und pause() nicht mehr. Deshalb habe ich sie wie folgt umgeändert und plt.cla() auskommentiert:

Code: Alles auswählen

canvas.show()
canvas.get_tk_widget().update_idletasks()
Nun bekomm ich aber meine GUI nicht mehr zu sehen, sondern nur den Polarplot der eigentlich zu langsam Daten plottet und diese auch nicht nach jedem Durchgang löscht.
Mein Ziel ist es, dass zunächst einfach nur die GUI aufgerufen wird, in der man einige Buttons und das Plotfenster sieht (funktioniert auch). Sobald man nun den Knopf "Plot" drückt. Sollen die Daten in derselben Figure innerhalb der GUI geplotet werden und nach jedem theta-Umlauf refreshed werden.
Gibt es auch eine elegantere Lösung? Zwei Endlosschleifen ineinander ist vermutlich nicht die beste Lösung. Vielleicht das man nach jedem theta-Umlauf ein break setzt in der for Schleife und die Funktion plot erneut startet nach kurzer Zeit, so dass der Plotvorgang auch durch den GUI-Nutzer angehalten werden kann?

Vielen Dank schon mal!

Beste Grüße!
Antworten