2017-01-04 2 views
0

Ich Plotten von Daten auf einem tkinter App, matplotlib verwenden.Refresh matplotlib Figur in einem tkinter App

Solange ich das Plot mit einem Dataset starte, ist es in Ordnung, aber wenn ich versuche, das Dataset zu ändern, anstatt ein neues Plot anstelle des alten zu bekommen, wird ein neues Plot hinzugefügt , so enden sie gestapelt.

Wie aktualisiere ich die matplotlib Figur, mit neuen Daten-Set? Ich benutze eine Taste, um das Diagramm auszulösen und die Daten an die Funktion zu übergeben. Dies ist der relevante Teil der App:

class Application(Frame): 

    def __init__(self, master=None): 

     Frame.__init__(self, master) 
     matplotlib.rcParams["figure.figsize"] = [2,6] 
     self.data_set = [1,2,3,4,5,6] 
     self.initUI() 


    def initUI(self): 
     self.pack(fill=BOTH, expand=1) 
     self.style = Style() 
     self.style.theme_use("default") 

     plotbutton = Button(self, text="Plot Data", command=lambda: self.create_plot(self.data_set)) 
     calculatebutton.place(x=300, y=600) 

     quitbutton = Button(self, text="Quit", command=self.quit) 
     quitbutton.place(x=400, y=600) 

    def create_plot(self, dataset): 

     plt = Figure(figsize=(4, 4), dpi=100) 
     a = plt.add_subplot(211) 
     a.plot(dataset, '-o', label="Main response(ms)") 
     a.set_ylabel("milliseconds") 
     a.set_title("plot") 
     canvas = FigureCanvasTkAgg(plt, self) 
     canvas.show() 
     canvas.get_tk_widget().pack(fill=BOTH) 
     toolbar = NavigationToolbar2TkAgg(canvas, self) 
     toolbar.update() 
     canvas._tkcanvas.pack(fill=BOTH) 
     # generate a random list of 6 numbers for sake of simplicity, for the next plot 
     data_set = random.sample(range(30), 6) 
     return 


def main(): 

    root = Tk() 
    root.wm_title("generic app") 
    root.geometry("800x700+100+100") 

    app = Application(master=root) 
    app.mainloop() 

    return 0 
+0

matplotlib hat Funktion 'clear()' die alten Plot entfernen – furas

+0

Wann sollte ich es verwenden? in meiner Funktion create_plot, vor dem Aufruf von add_subplot? –

+0

Sie haben kein funktionierendes Beispiel erstellt, daher ist es schwer zu sagen. Aber ich habe eine eigene Version gemacht und jetzt sehe ich, dass dein Problem anders ist als ich dachte. – furas

Antwort

0

Sie haben altes Grundstück entfernen/zerstören, bevor Sie neue erstellen.

Es funktioniert für mich - vielleicht ist es das, was Sie

brauche ich

self.widget = None 
    self.toolbar = None 

Zugang zu halten verwenden, um Widgets

ich einige Zeilen Code kommentiert, weil es ohne sie funktioniert für mich .

import matplotlib 
matplotlib.use('TkAgg') 
from matplotlib.backends.backend_tkagg import Figure, FigureCanvasTkAgg, NavigationToolbar2TkAgg 
from tkinter import * 
import random 

class Application(Frame): 

    def __init__(self, master=None): 

     Frame.__init__(self, master) 
     matplotlib.rcParams["figure.figsize"] = [2,6] 
     self.data_set = [1,2,3,4,5,6] 
     self.initUI() 

     # to assign widgets 
     self.widget = None 
     self.toolbar = None 

    def initUI(self): 
     self.pack(fill=BOTH, expand=1) 

     plotbutton = Button(self, text="Plot Data", command=lambda: self.create_plot(self.data_set)) 
     plotbutton.place(x=300, y=600) 

     quitbutton = Button(self, text="Quit", command=self.quit) 
     quitbutton.place(x=400, y=600) 


    def create_plot(self, dataset): 

     # remove old widgets 
     if self.widget: 
      self.widget.destroy() 

     if self.toolbar: 
      self.toolbar.destroy() 

     # create new elements 

     plt = Figure(figsize=(4, 4), dpi=100) 

     a = plt.add_subplot(211) 
     a.plot(dataset, '-o', label="Main response(ms)") 
     a.set_ylabel("milliseconds") 
     a.set_title("plot") 

     canvas = FigureCanvasTkAgg(plt, self) 

     self.toolbar = NavigationToolbar2TkAgg(canvas, self) 
     #toolbar.update() 

     self.widget = canvas.get_tk_widget() 
     self.widget.pack(fill=BOTH) 

     #self.toolbars = canvas._tkcanvas 
     #self.toolbars.pack(fill=BOTH) 

     # generate a random list of 6 numbers for sake of simplicity, for the next plot 
     self.data_set = random.sample(range(30), 6) 


def main(): 

    root = Tk() 
    root.wm_title("generic app") 
    root.geometry("800x700+100+100") 

    app = Application(master=root) 
    app.mainloop() 

main() 

Oder vielleicht sollten Sie Abbildung/Leinwand/etc erstellen. nur einmal und ersetze Daten in Plot mit clear() und set_data()

+0

Ich sehe, vielen Dank für die Antwort! Tatsächlich habe ich jedes Mal einen neuen Plot hinzugefügt, auf diese Weise ist es viel einfacher, auch wenn ich jedes Mal das Plot-Objekt zerstören und neu erstellen muss. –