2016-03-06 854 views
4

我一直有与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”

我该如何做到这一点?

+0

你能提供一个最简单的例子吗?我的猜测是你用'--pylab'使用ipython? ? – tacaswell

+0

我使用ipython,但没有指定--pylab。不过,我在标准的Python控制台中试过,并没有得到用户警告。尽管如此,他们都是在对canvas.show的调用中崩溃的。顺便说一句我正在使用tkinter 8.6。在调试器中,我发现它是tkagg.py中的一个内部调用,它使用自己的内部数据从backend_tkagg.py中调用,而不是我的。它在尝试显示其位图时调用tcl时失败,即在两种情况下都调用blit方法...调用tkagg版本的后端版本调用tcl –

+0

您可以发布实际运行代码吗?请阅读[如何创建最小,完整和可验证的示例](https://stackoverflow.com/help/mcve) – R4PH43L

回答

0

总结:

+0

您可以在高分辨率显示器上对Matplotlib TKAgg的问题发表评论吗?请参阅http://stackoverflow.com/questions/41370779/using-matplotlib-with-tkagg-backend-on-4k-screen – wigging