Python 在 tkinter (TkAgg) 中使用 Matplotlib
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35829961/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Matplotlib with tkinter (TkAgg)
提问by r mosher
I have been having consistent problems running Matplotlibwith tkinter. This happens with my code, and with others, including sample code that I have downloaded from the web, that presumably works for others.
我一直在使用tkinter运行Matplotlib时遇到问题。这发生在我的代码和其他代码中,包括我从网上下载的示例代码,这些代码可能适用于其他人。
The initial user warning from matplotlib.use('TkAgg')
occurs when I use the IPythonconsole, but not the standard Python console. I think this just means IPython is more verbose, because in either case the program crashes on canvas.show()
. The complete code that I have been trying to run is from the Matplotlib web site:
matplotlib.use('TkAgg')
当我使用IPython控制台而不是标准 Python 控制台时,会出现初始用户警告。我认为这只是意味着 IPython 更加冗长,因为在任何一种情况下,程序都会在canvas.show()
. 我一直在尝试运行的完整代码来自 Matplotlib 网站:
#!/usr/bin/env python
import matplotlib
matplotlib.use('TkAgg')
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# Implement the default mpl key bindings
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
root = Tk.Tk()
root.wm_title("Embedding in TK")
f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0, 3.0, 0.01)
s = sin(2*pi*t)
a.plot(t, s)
# A tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def on_key_event(event):
print('you pressed %s' % event.key)
key_press_handler(event, canvas, toolbar)
canvas.mpl_connect('key_press_event', on_key_event)
def _quit():
root.quit() # Stops mainloop
root.destroy() # This is necessary on Windows to prevent
# Fatal Python Error: PyEval_RestoreThread: NULL tstate
button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)
Tk.mainloop()
# If you put root.destroy() here, it will cause an error if
# the window is closed with the window manager.
Using the debugger I follow canvas.show into tkinter (backend_tkagg.py):
使用调试器,我跟随 canvas.show 进入 tkinter (backend_tkagg.py):
def draw(self):
FigureCanvasAgg.draw(self)
tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
self._master.update_idletasks()
I step over FigureCanvasAgg.draw ok and step into tkagg.blit... notice none of the data passed to tkagg.blit is application data. This call takes me to tkagg.py, namely:
我越过 FigureCanvasAgg.draw ok 并进入 tkagg.blit ... 注意传递给 tkagg.blit 的数据都不是应用程序数据。这个调用将我带到 tkagg.py,即:
def blit(photoimage, aggimage, bbox=None, colormode=1):
tk = photoimage.tk
if bbox is not None:
bbox_array = bbox.__array__()
else:
bbox_array = None
data = np.asarray(aggimage)
try:
tk.call("PyAggImagePhoto", photoimage,
id(data), colormode, id(bbox_array))
except Tk.TclError:
try:
try:
_tkagg.tkinit(tk.interpaddr(), 1)
except AttributeError:
_tkagg.tkinit(id(tk), 0)
tk.call("PyAggImagePhoto", photoimage,
id(data), colormode, id(bbox_array))
except (ImportError, AttributeError, Tk.TclError):
raise
where it fails repeatedly on the tk.call, which I think is a call into Tcl.
它在 tk.call 上反复失败,我认为这是对 Tcl 的调用。
I modified the code here to catch the TclError as a variable so I could inspect it in the debugger. It said: tclErr: invalid command name "PyAggImagePhoto"
我修改了此处的代码以将 TclError 作为变量捕获,以便我可以在调试器中检查它。它说:tclErr:无效的命令名称“PyAggImagePhoto”
What do I make of this?
我该怎么办?
回答by tacaswell
To summarize:
总结一下:
- the issue with the OP is a packaging issue due to dependencies (not) being installed at build time.
- This has been fixed upstream by https://github.com/matplotlib/matplotlib/pull/6442and mpl >= 1.5.2 should not have this problem.
- 由于在构建时安装了依赖项(未安装),OP 的问题是打包问题。
- 这已由https://github.com/matplotlib/matplotlib/pull/6442上游修复,mpl >= 1.5.2 不应该有这个问题。