我一直有與tkinter運行Matplotlib一致的問題。這發生在我的代碼和其他人身上,包括我從網上下載的示例代碼,這可能適用於其他人。與tkinter一起使用Matplotlib(TkAgg)
當我使用IPython控制檯但不是標準Python控制檯時,會發生matplotlib.use('TkAgg')
的初始用戶警告。我認爲這僅僅意味着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.
使用我按照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()
我跨過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
它多次失敗的tk.call,我認爲這是一個電話和Tcl。
我在這裏修改了代碼來捕獲TclError作爲變量,以便我可以在調試器中檢查它。它說:tclErr:無效的命令名稱「PyAggImagePhoto」
我該如何做到這一點?
你能提供一個最簡單的例子嗎?我的猜測是你用'--pylab'使用ipython? ? – tacaswell
我使用ipython,但沒有指定--pylab。不過,我在標準的Python控制檯中試過,並沒有得到用戶警告。儘管如此,他們都是在對canvas.show的調用中崩潰的。順便說一句我正在使用tkinter 8.6。在調試器中,我發現它是tkagg.py中的一個內部調用,它使用自己的內部數據從backend_tkagg.py中調用,而不是我的。它在嘗試顯示其位圖時調用tcl時失敗,即在兩種情況下都調用blit方法...調用tkagg版本的後端版本調用tcl –
您可以發佈實際運行代碼嗎?請閱讀[如何創建最小,完整和可驗證的示例](https://stackoverflow.com/help/mcve) – R4PH43L