简体   繁体   English

在 tkinter (TkAgg) 中使用 Matplotlib

[英]Using Matplotlib with tkinter (TkAgg)

I have been having consistent problems running Matplotlib with tkinter.我一直在使用tkinter运行Matplotlib时遇到问题。 This happens with my code, and with others, including sample code that I have downloaded from the web, that presumably works for others.这发生在我的代码和其他代码中,包括我从网上下载的示例代码,这些代码可能适用于其他人。

The initial user warning from matplotlib.use('TkAgg') occurs when I use the IPython console, but not the standard Python console.来自matplotlib.use('TkAgg')的初始用户警告发生在我使用IPython控制台而不是标准 Python 控制台时。 I think this just means IPython is more verbose, because in either case the program crashes on canvas.show() .我认为这只是意味着 IPython 更加冗长,因为在任何一种情况下,程序都会在canvas.show()上崩溃。 The complete code that I have been trying to run is from the Matplotlib web site:我一直在尝试运行的完整代码来自 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.我越过 FigureCanvasAgg.draw ok 并进入 tkagg.blit ... 注意传递给 tkagg.blit 的数据都不是应用程序数据。 This call takes me to tkagg.py, namely:这个调用将我带到 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.我修改了此处的代码以将 TclError 作为变量捕获,以便我可以在调试器中检查它。 It said: tclErr: invalid command name "PyAggImagePhoto"它说:tclErr:无效的命令名称“PyAggImagePhoto”

What do I make of this?我该怎么办?

To summarize:总结一下:

This code worked for me once I replaced替换后,此代码对我有用

NavigationToolbar2TkAgg

With

NavigationToolbar2Tk

And also replaced而且还换了

canvas.show()

With

canvas.draw()

Note, I use Anaconda 4.8.3, Matplotlib 3.2.1, Tkinter 8.6, and Windows 10.请注意,我使用 Anaconda 4.8.3、Matplotlib 3.2.1、Tkinter 8.6 和 Windows 10。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM