在Tkinter GUI中导入Matplotlib图形。在show()方法中出现错误。

4
我是一个有用的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我想在我的tkinter GUI中嵌入一个matplotlib图形。尝试了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. 

上面的示例给我返回了这个错误:

Traceback (most recent call last):
  File "<tmp 1>", line 34, in <module>
    canvas.show()
  File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 350, in draw
    tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
  File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\tkagg.py", line 24, in blit
    tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
_tkinter.TclError

另一个例子:

#!/usr/bin/env python
# -*- noplot -*-

import matplotlib as mpl
import numpy as np
import sys
if sys.version_info[0] < 3:
    import Tkinter as tk
else:
    import tkinter as tk
import matplotlib.backends.tkagg as tkagg
from matplotlib.backends.backend_agg import FigureCanvasAgg


def draw_figure(canvas, figure, loc=(0, 0)):
    """ Draw a matplotlib figure onto a Tk canvas

    loc: location of top-left corner of figure on canvas in pixels.

    Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
    """
    figure_canvas_agg = FigureCanvasAgg(figure)
    figure_canvas_agg.draw()
    figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
    figure_w, figure_h = int(figure_w), int(figure_h)
    photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)

    # Position: convert from top-left anchor to center anchor
    canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)

    # Unfortunatly, there's no accessor for the pointer to the native renderer
    tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)

    # Return a handle which contains a reference to the photo object
    # which must be kept live or else the picture disappears
    return photo

# Create a canvas
w, h = 300, 200
window = tk.Tk()
window.title("A figure in a canvas")
canvas = tk.Canvas(window, width=w, height=h)
canvas.pack()

# Generate some example data
X = np.linspace(0, 2.0*3.14, 50)
Y = np.sin(X)

# Create the figure we desire to add to an existing canvas
fig = mpl.figure.Figure(figsize=(2, 1))
ax = fig.add_axes([0, 0, 1, 1])
ax.plot(X, Y)

# Keep this handle alive, or else figure will disappear
fig_x, fig_y = 100, 100
fig_photo = draw_figure(canvas, fig, loc=(fig_x, fig_y))
fig_w, fig_h = fig_photo.width(), fig_photo.height()

# Add more elements to the canvas, potentially on top of the figure
canvas.create_line(200, 50, fig_x + fig_w / 2, fig_y + fig_h / 2)
canvas.create_text(200, 50, text="Zero-crossing", anchor="s")

# Let Tk take over
tk.mainloop()

这个代码让我出现了错误:
 Traceback (most recent call last):
      File "<tmp 2>", line 56, in <module>
        fig_photo = draw_figure(canvas, fig, loc=(fig_x, fig_y))
      File "<tmp 2>", line 32, in draw_figure
        tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
      File "C:\pyzo2015a\lib\site-packages\matplotlib\backends\tkagg.py", line 24, in blit
        tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
    _tkinter.TclError

我不明白为什么这些示例不起作用。请有人帮助我吗?


1
你在使用Anaconda吗? - shivsn
我曾经遇到过类似的问题。虽然我使用的是PyQt作为GUI,而不是Tkinter。不过,我相信我的问题解决方案也可以帮助你。请查看这里:https://dev59.com/6Zbfa4cB1Zd3GeqPpSM-#36669876。 - K.Mulier
@shivsn,不是的,我在使用Pyzo。我尝试了Spyder中的示例代码,它可以正常工作...所以,如果我想在Pyzo中嵌入图形到tk中,我该怎么做? - Concetto Cantone
@shivsn,非常感谢...看起来它可以工作。它能够处理从matplotlib网站获取的示例。现在我需要测试是否适用于我的代码。我会告诉你! - Concetto Cantone
@ConcettoCantone,这个代码对你有用吗? - shivsn
@shivsn 是的!它运行良好...谢谢! - Concetto Cantone
1个回答

1

我遇到了类似的问题,这个方法对我有用, 如果你使用的是Windows系统,建议卸载pillowmatplotlib,然后从这里重新安装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接