Canvas 事件只有效一次
Canvas event works only once
我正在编写一个程序来处理一些数据并将结果显示为绘图。我将绘图附加到 canvas 以便它可以在同一个 Tkinter window 中显示,而不是在新的 Tkinter 中显示。当用户单击它时,我希望该图显示在单独的 window 中,使用 mpl_connect
。但是,它只工作一次。如果我第二次点击 canvas 没有任何反应。我也尝试制作一个按钮并将事件绑定到它,但同样的问题发生了:它只工作一次。
任何人都可以告诉我我犯了什么错误以及如何改正它吗?
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()
将尝试在应用程序的主循环中启动 另一个 Tk 主循环,在进程中锁定内容。
此外,您正在创建两个 canvas
es 并将它们附加到同一个图形。
plt.figure()
创建一个图形、一个 canvas 和一个图形管理器,然后将它们注册到全局 pyplot
状态。您只希望其中一件事情发生,因此您应该改为调用 fig = matplotlib.figure.Figure(...)
。 (或者 Figure
在你的情况下,因为这就是你导入它的方式)
好消息是这是一个两行修复。将 plt.figure(...)
更改为 Figure(...)
并且不要在您的点击事件中调用 plt.show()
。
我正在编写一个程序来处理一些数据并将结果显示为绘图。我将绘图附加到 canvas 以便它可以在同一个 Tkinter window 中显示,而不是在新的 Tkinter 中显示。当用户单击它时,我希望该图显示在单独的 window 中,使用 mpl_connect
。但是,它只工作一次。如果我第二次点击 canvas 没有任何反应。我也尝试制作一个按钮并将事件绑定到它,但同样的问题发生了:它只工作一次。
任何人都可以告诉我我犯了什么错误以及如何改正它吗?
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()
将尝试在应用程序的主循环中启动 另一个 Tk 主循环,在进程中锁定内容。
此外,您正在创建两个 canvas
es 并将它们附加到同一个图形。
plt.figure()
创建一个图形、一个 canvas 和一个图形管理器,然后将它们注册到全局 pyplot
状态。您只希望其中一件事情发生,因此您应该改为调用 fig = matplotlib.figure.Figure(...)
。 (或者 Figure
在你的情况下,因为这就是你导入它的方式)
好消息是这是一个两行修复。将 plt.figure(...)
更改为 Figure(...)
并且不要在您的点击事件中调用 plt.show()
。