2017-12-14 35 views
-1

this postのメソッドを使用してスクロール可能なFigureを含むtkinterウィンドウを作成しました。基本的には、私はtk.Scaleを使ってサイズ変更可能な比較的大きなイメージをロードしますが、Figureを含むウィンドウを一定の大きさにしたい。問題は、私の人物が〜16x16インチに達すると、プログラムは堪えがたく遅くなるということです。どんなアイデアでも大歓迎です。matplotlibの大きなスクロール可能図形が極端に遅い

特にスローラインはfigure.set_size_inches([factor * s for s in oldSize])

ここでウィンドウの全体のコードですされています

import matplotlib 
matplotlib.use("TkAgg") 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 
from matplotlib.figure import Figure 
import tkinter as tk 
from tkinter import ttk 

class MacroWindow(tk.Tk): 
    def __init__(self, controller, *args, **kwargs):  
     tk.Tk.__init__(self, *args, **kwargs) #initialize regular Tk stuff 

     #set properties for main window 
     tk.Tk.wm_title(self, "Macro View") 
     tk.Tk.geometry(self, newGeometry = '600x700+200+200') 
     #define container for what's in the window 
     self.controller = controller 
     self.figSize_inches = [8,8] 
     self.addScrollingFigure() 
     frame_buttons = ttk.Frame(self) 
     frame_buttons.grid(row = 1, column = 0, sticky = 'nsew') 
     button_loadMacroImage = ttk.Button(frame_buttons,text = "Load Test Macro Image", command = 
          lambda: self.loadMacroImage()) 
     button_loadMacroImage.grid(row = 0, column = 0, padx = 10, pady = 10, sticky = 'nw') 
     self.scale_zoom = tk.Scale(self, orient = tk.VERTICAL) 
     self.scale_zoom.grid(row = 2, column = 0, sticky = 'ew') 
     self.scale_zoom.config(command = self.changeSize, from_=.1, to=5, resolution = .1) 

    def addScrollingFigure(self): 
     self.frame_canvas = ttk.Frame(self) 
     self.frame_canvas.grid(row = 0, column = 0, sticky = 'nsew') 
     # set up canvas with scrollbars 
     canvas = tk.Canvas(self.frame_canvas) 
     canvas.grid(row = 0, column = 0, sticky = 'nsew') 
     xScrollbar = tk.Scrollbar(self.frame_canvas, orient = tk.HORIZONTAL) 
     yScrollbar = tk.Scrollbar(self.frame_canvas, orient = tk.VERTICAL) 
     xScrollbar.grid(row = 1, column = 0, sticky = 'ew') 
     yScrollbar.grid(row = 0, column = 1, sticky = 'ns') 
     canvas.config(xscrollcommand = xScrollbar.set) 
     xScrollbar.config(command = canvas.xview) 
     canvas.config(yscrollcommand = yScrollbar.set) 
     yScrollbar.config(command = canvas.yview) 

     #create figure and axis 
     f_wholeCellFig = Figure(figsize = self.figSize_inches, dpi = fig_dpi) 
     a=f_wholeCellFig.add_subplot(1,1,1) 
     f_wholeCellFig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1, wspace = 0.02, hspace = 0) 

     self.wholeCellFig = f_wholeCellFig 
     self.wholeCellAx = a 

     #plug in the figure 
     figAgg = FigureCanvasTkAgg(f_wholeCellFig,canvas) 
     mplCanvas = figAgg.get_tk_widget() 
     self.mplCanvas = mplCanvas 
     self.canvas = canvas 
     # and connect figure with scrolling region 
     self.cwid = canvas.create_window(0, 0, window=mplCanvas, anchor='nw') 
     self.changeSize(1.0) 


    def changeSize(self,factor): 
     if not isinstance(factor,float): 
      factor = self.scale_zoom.get() 
     figure = self.wholeCellFig 
     oldSize = self.figSize_inches 
     figure.set_size_inches([factor * s for s in oldSize]) 
     wi,hi = [i*figure.dpi for i in figure.get_size_inches()] 
     self.mplCanvas.config(width = wi, height = hi) 
     self.canvas.itemconfigure(self.cwid, width = wi, height = hi) 
     self.canvas.config(scrollregion = self.canvas.bbox('all'), width = 500, height = 500) 
     figure.subplots_adjust(left = 0, bottom = 0, top = 1, right = 1) 
     figure.canvas.draw() 

    def loadMacroImage(self): 
     if simulation: 
      image = io.imread('../testing/macroImage.tif') 
     a = self.wholeCellAx 
     a.clear() 
     a.axis('equal') 
     a.axis('off') 
     self.volume = image 
     self.multi_slice_viewer() 

    def multi_slice_viewer(self): 
     ax = self.wholeCellAx 
     self.scale_z.config(command = self.scaleCallback, from_=0, to=self.volume.shape[0]-1) 
     ax.index = self.volume.shape[0] // 2 
     self.scale_z.set(ax.index) 
     ax.imshow(self.volume[ax.index]) 
     self.wholeCellFig.canvas.draw() 

root = tk.Tk() 
window = MacroWindow(root) 
root.mainloop() 

答えて

0

だから私は、具体的matplotlibを使用していませんでしたが、あなたのコードを読んで、それはあなたがあなたを呼び出すたびのように見えますdrawコマンドを使用して画像を拡大縮小すると、移動するたびに画像のサイズが変更されます。私はそれについて間違っているかもしれませんが、それがあなたの問題でもある場合はそうです。

リスケーリングは処理が非常に集中し、プログラムのクロールを遅くする可能性があります。スケーリングされたイメージを独自のオブジェクトとして保存して、一度スケールし、描画を呼び出すときはいつでもスケーリングされたイメージを参照してください。

しかし、私が言ったように、私はので、私は私を無視して自由に感じるあなたのコードはそうやっていることを誤解される可能性があります:)

0

だから、周りの閲覧からmatplotlibで働いていませんでした、matplotlibのはただではないようですすばやく、特に大きな画像を使って、すばやくやり遂げることができますTkinterで大きなスクロール可能な画像を表示するには、PILとTkImageを使用する方がよいでしょう。私はhereと記載された例を取り除き、私の結果は大きく改善されました。

ここでは、スクロール可能なイメージを持つウィンドウを作成するには(リンクから)スコット・ハーデンのコードサンプルです:

from Tkinter import * 
import Image, ImageTk 

class ScrolledCanvas(Frame): 
    def __init__(self, parent=None): 
      Frame.__init__(self, parent) 
      self.master.title("Spectrogram Viewer") 
      self.pack(expand=YES, fill=BOTH) 
      canv = Canvas(self, relief=SUNKEN) 
      canv.config(width=400, height=200) 
      #canv.config(scrollregion=(0,0,1000, 1000)) 
      #canv.configure(scrollregion=canv.bbox('all')) 
      canv.config(highlightthickness=0) 

      sbarV = Scrollbar(self, orient=VERTICAL) 
      sbarH = Scrollbar(self, orient=HORIZONTAL) 

      sbarV.config(command=canv.yview) 
      sbarH.config(command=canv.xview) 

      canv.config(yscrollcommand=sbarV.set) 
      canv.config(xscrollcommand=sbarH.set) 

      sbarV.pack(side=RIGHT, fill=Y) 
      sbarH.pack(side=BOTTOM, fill=X) 

      canv.pack(side=LEFT, expand=YES, fill=BOTH) 
      self.im=Image.open("./1hr_original.jpg") 
      width,height=self.im.size 
      canv.config(scrollregion=(0,0,width,height)) 
      self.im2=ImageTk.PhotoImage(self.im) 
      self.imgtag=canv.create_image(0,0,anchor="nw",image=self.im2) 

ScrolledCanvas().mainloop() 
関連する問題