我使用tkinter在python中构建了一个简单的matplotlib绘图GUI。现在我想通过ginput从图中获取坐标。不幸的是,我一直收到以下错误:
AttributeError: 'FigureCanvasTkAgg' object has no attribute 'manager'
Figure.show works only for figures managed by pyplot, normally created by pyplot.figure().
似乎ginput对tkinter不起作用,如果我不使用tkinter并且只是从命令行生成一个绘图窗口,我可以使这段代码正常工作。
我知道有一种替代方法可以使用matplotlib中的事件选择函数来完成这类事情,但我似乎无法翻译我见过的关于此功能的示例。任何人都可以告诉我这个吗?
import numpy as np
from matplotlib.pyplot import *
from Tkinter import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
class App:
def __init__(self, master):
global frame
frame = Frame(master)
frame.pack(side=TOP)
self.quitbutton = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.quitbutton.grid(row=4,column=0,sticky=W)
self.hi_there = Button(frame, text="LOAD",command=self.loadfile)
self.hi_there.grid(row=0,column=0,sticky=W)
self.cutbutton = Button(frame, text="CUT", fg="purple",command=self.cut)
self.cutbutton.grid(row=1,column=0,sticky=W)
global canvas, ax, f
f = Figure(figsize=(20,4))
ax = f.add_subplot(111)
ax.set_xlabel('Time(s)',fontsize=20)
ax.set_ylabel('Current(nA)',fontsize=20)
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=1)
toolbar1 = NavigationToolbar2TkAgg( canvas, root )
toolbar1.update()
f.tight_layout()
def loadfile(self):
ax.clear()
self.data=rand(1000)
self.t=np.arange(0,len(self.data))
##############################################plot data
self.baseline=np.median(self.data)
self.var=2*std(self.data)
ax.plot(self.t,self.data,'b')
ax.set_xlabel('Time(s)',fontsize=20)
ax.set_ylabel('Current(nA)',fontsize=20)
ax.axhline(linewidth=2, y=self.baseline, color='g')
ax.set_xlabel('Time(s)',fontsize=20)
ax.set_ylabel('Current(nA)',fontsize=20)
canvas.draw()
def cut(self):
pts=np.array(f.ginput(2))
pts=pts[:,0]
print pts
self.data=np.delete(self.data,pts)
ax.clear()
self.baseline=np.median(self.data)
self.t=np.arange(0,len(self.data))
ax.plot(self.t,self.data,'b')
ax.axhline(linewidth=2, y=self.baseline, color='g')
canvas.draw()
root = Tk()
app = App(root)
root.mainloop()
root.destroy()
编辑:似乎问题在于图和图之间的区别
ginput似乎适用于figure()但不适用于Figure()。并且tkinter仅适用于图...有解决方法吗?
答案 0 :(得分:1)
进入python/Tkinter
.mainloop()
后,将 Tkinter
GUI输入基于鼠标点击事件,而不是MATLAB/pyplot
.ginput()
没有严肃的控制系统(而且Tkinter .mainloop()
是一个非常严重的控制系统)喜欢将它的控制缰绳移交给任何其他竞争(==阻塞)子系统。
经测试可以使用:
class App( Frame ): # The user interface:
def __init__( self, master = None ):
Frame.__init__( self, master )
self.fig = Figure( ( 6, 6 ), dpi = 100 )
canvas = FigureCanvasTkAgg( self.fig, master = self )
# ---------------------------------------------------# cover Tk.root
self.bind( "<Button-1>", # Tk Event type
self.showXY_handler # handler 2 call
)
# ----------------------------------------------------------------------
canvas.get_tk_widget().grid( row = 0, # this adds a plot
column = 0, # on Tk.root .grid()
columnspan = 4 # geometry manager
)
# ---------------------------------------------------cover graph area
canvas.get_tk_widget().bind( "<Button-1>",
self.showXY_handler
)
# -----------------------------------------------------------
#FINALLY THE INTERFACE TO A DEMO-HANDLER METHOD:
def showXY_handler( self, aHandledEVENT ):
print aHandledEVENT.x, aHandledEVENT.y
您也可以使用Class实例变量而不是global
- s
# global canvas, ax, f # rather to be avoided use of global-s
self.canvas = # instance variables, Class-wide visible
self.ax =
self.f =
答案 1 :(得分:0)
正如我所知,使用from module import *
这样的语法对于python来说并不是一个好习惯。最好导入全名。
此外,您还没有rand
和std
的导入。我想,最好不要在你的情况下使用global
变量。可能不是rand(1000)
,而是np.random.rand(1000)
?
您可以尝试另一种方式与MATLAB接口,例如pyqt 我尝试过我的项目。
我想,这个matplotlib
的问题可以帮助你mpl gitgub。但你应该像matplotlib.use('tkagg')
一样添加smth。