2016-03-06 852 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