2017-10-19 16 views
0

これは、tkinterのMatplotlib機能に関する私の他のquestionのフォローアップです。私はモデルを訓練するときにプロットを含む複数のウィンドウを開くプログラムを開発しようとしています。値は辞書としてaveCRに格納され、各キーは複数の配列を格納します。各キーについて、私は新しいウィンドウで配列をプロットしているため、forループを使って新しいウィンドウを開きます(これが良い方法であるかどうかは分かりません)。Matplotlib/tkinter:複数のウィンドウを開くときの凡例のイベントピックアップ

問題は、各ウィンドウの凡例にあります。ラインのオン/オフを切り替える機能は、最終的なウィンドウでのみ利用可能です。新しいウィンドウを開くたびに、この機能を利用できます。私はself.linedがforループの最終プロットで上書きされることを知っていますが、これをforループに追加する必要があるかどうかはわかりません。

私はaveCRのために以下のダミー数字を追加しましたので、コードを実行できます。これに近づくためのアドバイスをいただければ幸いです!

import matplotlib.pyplot as plt 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 
import numpy as np 

import tkinter as tk 

class App: 
    def __init__(self,master): 
     self.master = master 
     # Frame for the training values 
     buttonFrame = tk.Frame(master) 
     buttonFrame.pack() 

     self.buttonGenerate = tk.Button(master=buttonFrame, 
             text='Train', 
             command=self.train) 
     self.buttonGenerate.grid(column=2,row=0) 


    def train(self): 

     aveCR = {0:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])}, 
      1:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])}} 

     legend = {0: ['A', 'AB'], 1: ['A', 'AB']} 

     for i in range(len(aveCR)): 
      t = tk.Toplevel(self.master) 
      # Frame for the plot 
      plotFrame = tk.Frame(t) 
      plotFrame.pack() 

      f = plt.Figure() 
      self.ax = f.add_subplot(111) 
      self.canvas = FigureCanvasTkAgg(f,master=plotFrame) 
      self.canvas.show() 
      self.canvas.get_tk_widget().pack() 
      self.canvas.mpl_connect('pick_event', self.onpick) 

      # Plot 
      lines = [0] * len(aveCR[i]) 
      for j in range(len(aveCR[i])):   
       X = range(0,len(aveCR[i][j])) 
       lines[j], = self.ax.plot(X,aveCR[i][j],label=legend[i][j]) 
      leg = self.ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,ncol=2, borderaxespad=0.) 

     self.lined = dict() 
     for legline, origline in zip(leg.get_lines(), lines): 
      legline.set_picker(5) # 5 pts tolerance 
      self.lined[legline] = origline 


    def onpick(self, event): 
     # on the pick event, find the orig line corresponding to the 
     # legend proxy line, and toggle the visibility 
     legline = event.artist 
     origline = self.lined[legline] 
     vis = not origline.get_visible() 
     origline.set_visible(vis) 
     # Change the alpha on the line in the legend so we can see what lines 
     # have been toggled 
     if vis: 
      legline.set_alpha(1.0) 
     else: 
      legline.set_alpha(0.2) 
     self.canvas.draw() 



root = tk.Tk() 
root.title("hem") 
app = App(root) 
root.mainloop() 

答えて

0

これはおそらく設計上の問題です。各プロットウィンドウにクラスを使用することをお勧めします。 Appクラスは、必要な数のプロットウィンドウをインスタンス化して、それぞれのデータを引数として提供することができます。各プロットウィンドウは、凡例とそれ自身のイベントを管理します。

import matplotlib.pyplot as plt 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 
import numpy as np 

import Tkinter as tk 

class Plotwindow(): 
    def __init__(self, master, data, legend): 
     t = tk.Toplevel(master) 
     # Frame for the plot 
     plotFrame = tk.Frame(t) 
     plotFrame.pack() 

     f = plt.Figure() 
     self.ax = f.add_subplot(111) 
     self.canvas = FigureCanvasTkAgg(f,master=plotFrame) 
     self.canvas.show() 
     self.canvas.get_tk_widget().pack() 
     self.canvas.mpl_connect('pick_event', self.onpick) 

     # Plot 
     lines = [0] * len(data) 
     for j in range(len(data)):   
      X = range(0,len(data[j])) 
      lines[j], = self.ax.plot(X,data[j],label=legend[j]) 
     leg = self.ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,ncol=2, borderaxespad=0.) 
     self.lined = dict() 
     for legline, origline in zip(leg.get_lines(), lines): 
      legline.set_picker(5) # 5 pts tolerance 
      self.lined[legline] = origline 

    def onpick(self, event): 
     # on the pick event, find the orig line corresponding to the 
     # legend proxy line, and toggle the visibility 
     legline = event.artist 
     origline = self.lined[legline] 
     vis = not origline.get_visible() 
     origline.set_visible(vis) 
     # Change the alpha on the line in the legend so we can see what lines 
     # have been toggled 
     if vis: 
      legline.set_alpha(1.0) 
     else: 
      legline.set_alpha(0.2) 
     self.canvas.draw() 

class App: 
    def __init__(self,master): 
     self.master = master 
     # Frame for the training values 
     buttonFrame = tk.Frame(master) 
     buttonFrame.pack() 

     self.buttonGenerate = tk.Button(master=buttonFrame, 
             text='Train', 
             command=self.train) 
     self.buttonGenerate.grid(column=2,row=0) 

    def train(self): 

     aveCR = {0:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])}, 
      1:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])}} 

     legend = {0: ['A', 'AB'], 1: ['A', 'AB']} 

     self.windows = [] 
     for i in range(len(aveCR)): 
      data = aveCR[i] 
      self.windows.append(Plotwindow(self.master,data, legend[i])) 


root = tk.Tk() 
root.title("hem") 
app = App(root) 
root.mainloop() 
+0

ありがとうございました! –

関連する問題