我使用this post中的方法创建了一个带有可滚动图形的tkinter窗口。基本上,我加载一个相对较大的图像,我希望使用tk.Scale可以调整大小,但我希望包含图形的窗口保持恒定的大小。问题是,一旦我的身材达到~16x16英寸,程序就会变得难以忍受。任何想法都将不胜感激。
特别慢的行是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 :(得分:0)
所以我没有专门使用matplotlib
但是通过代码阅读它看起来就像每次调用draw
命令时缩放图像一样,这意味着每次都会重新缩放图像它动了。我可能错了,但如果是这种情况也是你的问题。
重新扩展是一个非常耗费流程的过程,可能会使您的程序变慢。因此,将缩放后的图像保存为自己的对象,以便缩放一次,然后在您想要调用绘图时随时参考缩放图像。
但正如我所说,我没有与matplotlib
合作,所以我可能会误解你的代码在做什么,所以请随意忽略我:)
答案 1 :(得分:0)
因此,通过浏览,似乎Matplotlib不擅长快速做事,特别是对于大图像。要在Tkinter中拥有一个可滚动的大图像,使用PIL和TkImage会更好。我处理了一个描述here的例子,我的结果得到了很大改善。
这是Scott Harden的代码示例(来自链接),用于创建一个带有可滚动图像的窗口:
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()