2017-01-24 3 views
-1

Hier ist meine erste tkInter-Anwendung. Ich möchte eine Matplotlib-Figur auf einer Tkinter-Leinwand zeichnen. Ich las die folgenden Links, es zu bauen:Matplotlib in einem tkinter Canvas: Warum verhalten sich update() und draw() Methoden danach?

aber das Ergebnis ist nicht wirklich befriedigend: die Figur ist in der Callback-Methode nicht aktualisiert, sondern nur wenn ich den "Reset" -Button meiner App starte. Kann mir jemand sagen, wie man die Figur/Leinwand im "PlotCallback" aktualisieren kann?

Vielen Dank im Voraus!

#!/usr/bin/env python 
# -*- coding: utf8 -*- 
import os 
import numpy as np 
import Tkinter 
import matplotlib 
matplotlib.use('TkAgg') 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 
from matplotlib.figure import Figure 

import tkFileDialog 
import tkMessageBox 

#========================= 
# App Class 
#========================= 
class Visu(Tkinter.Frame): 
    """Main Frame for data visualization 
    """ 

    #------------------------------------ 
    def __init__(self, parent, **kwargs): 
     """Initialisation des widgets 
     """ 
     ### USED VARIABLES (for file and data processing) 
     self.dataToPlot = [] 
     self.itmsToPlot = [] 
     self.presentsItems = [] 
     self.chBtnVarLst = [] # list of "CheckButton" states for items selection 
     self.chBtnLst = []  # list of "CheckButton" labels 
     self.fic = "" 
     self.parent = parent 

     ### IHM ### 
     Tkinter.Frame.__init__(self, parent, **kwargs) 
     self.pack(fill=Tkinter.BOTH) 

     # Create Menu Bar 
     menuBar = Tkinter.Menu(self) 
     menuFic = Tkinter.Menu(menuBar) 
     menuFic.add_command(label="Open", command = self.OpenCallback) 
     menuFic.add_separator() 
     menuFic.add_command(label="Quit", command = self.quit) 
     menuHlp = Tkinter.Menu(menuBar) 
     menuHlp.add_command(label="Help", command = self.HelpCallback) 

     menuBar.add_cascade(label = "File", menu = menuFic) 
     menuBar.add_cascade(label = "Help", menu = menuHlp) 
     parent.config(menu = menuBar) 

     # Create the Canvas for the plot figure 
     self.fig = Figure() 
     self.ax = self.fig.add_subplot(111) 
     t = np.arange(0.0, 3.0, 0.01) 
     s = np.sin(2*np.pi*t) 
     self.ax.plot(t,s) 

     self.canvas = FigureCanvasTkAgg(self.fig, master = self) 
     self.canvas.show() 
     self.canvas.get_tk_widget().pack() 

     toolbar = NavigationToolbar2TkAgg(self.canvas, self) 
     toolbar.update() 
     self.canvas._tkcanvas.pack(side=Tkinter.TOP, expand=1) 

     # Create controls 
     self.dataFrame = Tkinter.LabelFrame(self, text = "Available data") 
     self.defButton = Tkinter.Checkbutton(self.dataFrame, 
               text = "Empty", 
               justify = Tkinter.LEFT, 
               state = Tkinter.DISABLED).pack() 
     self.dataFrame.pack() 

     # Create Buttons 
     self.BtnPlot = Tkinter.Button(self, text = "Plot", command = self.PlotCallback, state = Tkinter.DISABLED) 
     self.BtnPlot.pack(fill = Tkinter.BOTH, expand=1) 
     self.BtnRaZ = Tkinter.Button(self, text = "Reset", command = self.ResetCallback, state = Tkinter.DISABLED) 
     self.BtnRaZ.pack(fill = Tkinter.BOTH, expand=1) 


    #---------------------- 
    def OpenCallback(self): 
     """Open data file and add selection check buttons 
     """ 
     # Open file 
     options = {} 
     options['defaultextension'] = '.txt' 
     options['initialdir'] = '..' 
     options['title'] = 'Choix du fichier' 
     options['filetypes'] = [('text files', '.txt'),('all files', '.*')] 
     filename = tkFileDialog.askopenfilename(**options) 
     self.fic = os.path.basename(filename) 

     # Reader file header 
     f = open(filename) 
     self.presentsItems = f.readline().split() 
     f.close() 

     # Read data 
     self.dataToPlot = np.loadtxt(filename, skiprows=1) 



     #--- Frame to select items to be drawn --- 
     cnt = 0 
     for c in self.presentsItems: 
      cbVar = Tkinter.StringVar() 
      w = Tkinter.Checkbutton(self.dataFrame, 
           text = c, 
           variable = cbVar, 
           justify = Tkinter.LEFT, 
           onvalue = c) 
      w.deselect() 
      self.chBtnVarLst.append(cbVar) 
      self.chBtnLst.append(w) 
      w.grid(row = cnt % 10, column = cnt/10) 
      cnt += 1 

     # Buttons activation 
     self.BtnPlot['state'] = Tkinter.NORMAL 
     self.BtnRaZ['state'] = Tkinter.NORMAL 

    #---------------------- 
    def HelpCallback(self): 
     """Instructions on how to use the program 
     """ 
     tkMessageBox.showinfo("Usage", "Work in progress...") 

    #---------------------- 
    def PlotCallback(self): 
     # Read chosen items 
     for cbVar in self.chBtnVarLst: 
      if cbVar.get() != "0": 
       self.itmsToPlot.append(cbVar.get()) 

     # Plot those items 
     self.ax.cla() 
     self.fig.suptitle(self.fic) 
     for itm in self.itmsToPlot: 
      k = self.presentsItems.index(itm) 
      self.ax.plot(self.dataToPlot[:,k],label=itm) 
     self.ax.set_xlabel("Frame number") 
     self.ax.legend() 
     self.canvas.get_tk_widget().update() 
     self.update() 
     self.fig.canvas.draw() 

    #----------------------- 
    def ResetCallback(self): 
     """Forgets the items and data, destroy associated buttons 
     """ 
     for cb in self.chBtnLst: 
      cb.destroy() 
     self.dataToPlot = [] 
     self.itmsToPlot = [] 
     self.presentsItems = [] 
     self.chBtnLst = [] 
     self.chBtnVarLst = [] 
     self.fic = "" 

#======== 
# Main 
#======== 
if __name__=='__main__': 
    root = Tkinter.Tk() 
    root.wm_title("Visu XDE") 
    maVisu = Visu(root) 
    maVisu.mainloop() 

Getestet auf Ubuntu 12.04 (leider muss ich eine besondere nur in 12,04 bestehende Simulations-Framework) mit Python 2.7.3, matplotlib 1.1.1rc, Tkinter Revision: 81008.

+0

Ich habe vor kurzem die Codes veröffentlicht, um ein [LIVE-Matplotlib-Diagramm in einem tkinter-Fenster] zu erstellen (http://stackoverflow.com/questions/41629891/matplotlib-removing-patches-from-plot/41705020#41705020). Ist das was du brauchst? –

+0

Vielleicht könnten Sie ein [mcve] mit weniger Code schreiben und das hängt nicht von externen Dateien ab. – Goyo

Antwort

0

Eigentlich war das Problem nicht mit Matplotlib, aber mit einer Checkbutton nicht korrekt verarbeitet, die keine Ausnahme oder Fehler auslösen, aber die GUI nicht aktualisiert werden. Das Erstellen des Minimalen, Kompletten und Überprüfbaren Beispiels hat es offenbart ... Danke Sun Bear und Goyo für Ihre wertvolle Hilfe.