Python 画布事件只工作一次

Python 画布事件只工作一次,python,numpy,matplotlib,tkinter,event-handling,Python,Numpy,Matplotlib,Tkinter,Event Handling,我正在写一个程序,处理一些数据,并将结果显示为绘图。我将绘图附加到画布上,以便它可以显示在同一Tkinter窗口中,而不是显示在新窗口中。我希望当用户使用mpl\u connect单击图形时,该图形显示在单独的窗口中。然而,它只能工作一次。如果我第二次单击画布,什么也不会发生。我还尝试制作一个按钮并将一个事件绑定到它,但同样的问题发生了:它只工作一次 有谁能告诉我我犯了什么错误以及如何改正 import matplotlib matplotlib.use('TkAgg') import nump

我正在写一个程序,处理一些数据,并将结果显示为绘图。我将绘图附加到画布上,以便它可以显示在同一Tkinter窗口中,而不是显示在新窗口中。我希望当用户使用
mpl\u connect
单击图形时,该图形显示在单独的窗口中。然而,它只能工作一次。如果我第二次单击画布,什么也不会发生。我还尝试制作一个按钮并将一个事件绑定到它,但同样的问题发生了:它只工作一次

有谁能告诉我我犯了什么错误以及如何改正

import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from Tkinter import *

class mclass:
    def __init__(self,  window):
        self.window = window
        self.leftframe= Frame (self.window)
        self.rightframe= Frame (self.window)
        self.leftframe.pack (side= LEFT, anchor=N)
        self.rightframe.pack (side=RIGHT, anchor=N)

        self.box = Entry(self.leftframe)
        self.button = Button (self.leftframe, text="check", command=self.plot)
        self.plotlabel= Label (self.leftframe, text="The following is the plot")
        self.box.grid (row=1, column=1)
        self.button.grid(row=2, column= 1)
        self.plotlabel.grid (row=3, column=1)

    def plot (self):
        x=np.array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        v= np.array ([16,16.31925,17.6394,16.003,17.2861,17.3131,19.1259,18.9694,22.0003,22.81226])
        p= np.array ([16.23697,     17.31653,     17.22094,     17.68631,     17.73641 ,    18.6368,
            19.32125,     19.31756 ,    21.20247  ,   22.41444   ,  22.11718  ,   22.12453])

        fig = plt.figure(figsize=(6,6))
        a = fig.add_subplot(111)
        a.scatter(v,x,color='red')
        a.plot(p, range(2 +max(x)),color='blue')
        a.invert_yaxis()

        a.set_title ("Estimation Grid", fontsize=16)
        a.set_ylabel("Y", fontsize=14)
        a.set_xlabel("X", fontsize=14)

        canvas = FigureCanvasTkAgg(fig, master=self.rightframe)
        canvas.get_tk_widget().grid(row=1, column= 2)
        canvas.draw()
        cid= fig.canvas.mpl_connect('button_press_event', lambda event: plt.show())

window= Tk()
start= mclass (window)
window.mainloop()

正如@tcaswell所指出的,在嵌入时,不能使用
plt.figure
plt.show

您只需单击一次就可以工作的原因是您正在“on click”回调中调用
plt.show()
plt.show()
将尝试在应用程序的mainloop内启动另一个Tk mainloop,并在此过程中锁定内容

另外,您正在创建两个
canvas
es并将它们附加到同一个图形上

plt.figure()
创建一个地物、画布和地物管理器,然后将它们注册到全局
pyplot
状态。您只希望发生其中一种情况,因此应该调用
fig=matplotlib.figure.figure(…)
。(或者在您的情况下是
,因为这就是您导入它的方式)



好消息是这是一个两行修复。将
plt.figure(…)
更改为
figure(…)
,并且不要在单击事件中调用
plt.show()

怀疑您遇到了
pyplot
中固有的全局状态问题。我会不惜一切代价避免使用
pyplot
+嵌入。非常感谢Joe,我可以调用什么来代替plt.show?
plt.show()
相当于您的
window.mainloop()
。在按钮按下回调的内部调用是没有意义的。您希望回调做什么?谢谢,画布已经显示在应用程序的主窗口中,单击时,我希望它显示在一个单独的窗口中,如plt。show在一个单独的窗口中显示图形,用户可以将其最大化和最小化。我该怎么做?谢谢