我正在开发一个Tkinter-GUI,以交互方式生成Matplotlib图,具体取决于用户输入。为此,需要在用户更改输入后重新绘制。
我原则上已将其付诸实践,但希望包含NavigationToolbar
。但是,我似乎无法更新NavigationToolbar
才能正常工作。
以下是代码的基本工作版本(没有用户输入条目):
# Import modules
from Tkinter import *
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# global variable: do we already have a plot displayed?
show_plot = False
# plotting function
def plot(x, y):
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.plot(x,y)
return fig
def main():
x = np.arange(0.0,3.0,0.01)
y = np.sin(2*np.pi*x)
fig = plot(x, y)
canvas = FigureCanvasTkAgg(fig, master=root)
toolbar = NavigationToolbar2TkAgg(canvas, toolbar_frame)
global show_plot
if show_plot:
#remove existing plot and toolbar widgets
canvas.get_tk_widget().grid_forget()
toolbar_frame.grid_forget()
toolbar_frame.grid(row=1,column=1)
canvas.get_tk_widget().grid(row=0,column=1)
show_plot=True
# GUI
root = Tk()
draw_button = Button(root, text="Plot!", command = main)
draw_button.grid(row=0, column=0)
fig = plt.figure()
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().grid(row=0,column=1)
toolbar_frame = Frame(root)
toolbar_frame.grid(row=1,column=1)
root.mainloop()
按“Plot!” 一旦生成情节和NavigationToolbar
。
再次按下它会重新创建,但会生成秒 NavigationToolbar
(每次按下“Plot!”时会生成另一个!)。听起来像grid_forget()
的声音不起作用。
但是,当我改变
if show_plot:
#remove existing plot and toolbar widgets
canvas.get_tk_widget().grid_forget()
toolbar_frame.grid_forget()
toolbar_frame.grid(row=1,column=1)
canvas.get_tk_widget().grid(row=0,column=1)
show_plot=True
到
if show_plot:
#remove existing plot and toolbar widgets
canvas.get_tk_widget().grid_forget()
toolbar_frame.grid_forget()
else:
toolbar_frame.grid(row=1,column=1)
canvas.get_tk_widget().grid(row=0,column=1)
show_plot=True
然后当{Plot!'时NavigationToolbar
消失了。第二次被按下(但是,正如预期的那样,没有新的NavigationToolbar
替换旧的grid_forget()
。所以NavigationToolbar
正在工作,只是没有预期的那样。
我做错了什么?有更好的方法来更新canvas = FigureCanvasTkAgg(fig, master=root)
toolbar_frame = Frame(root)
global show_plot
if show_plot: # if plot already present, remove plot and destroy NavigationToolbar
canvas.get_tk_widget().grid_forget()
toolbar_frame.destroy()
toolbar_frame = Frame(root)
toolbar = NavigationToolbar2TkAgg(canvas, toolbar_frame)
toolbar_frame.grid(row=21,column=4,columnspan=3)
canvas.get_tk_widget().grid(row=1,column=4,columnspan=3,rowspan=20)
show_plot = True
吗?
任何帮助非常感谢! Lastalda
修改
我发现如果您销毁NavigationToolbar而不是忘记它,这将有效。但是你必须在之后再次完全重新创建小部件:
destroy()
然而,下面的Hans所显示的更新方法更好,因为你不必破坏和重新创建任何东西。我只是想强调我的方法的问题(除了不优雅和性能)可能是我没有使用{{1}}。
答案 0 :(得分:4)
稍微不同的方法可能是通过清除& amp;重新绘制它。这样,你就不必破坏&不重新生成图形和工具栏:
from Tkinter import Tk, Button
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# plotting function: clear current, plot & redraw
def plot(x, y):
plt.clf()
plt.plot(x,y)
# just plt.draw() won't do it here, strangely
plt.gcf().canvas.draw()
# just to see the plot change
plotShift = 0
def main():
global plotShift
x = np.arange(0.0,3.0,0.01)
y = np.sin(2*np.pi*x + plotShift)
plot(x, y)
plotShift += 1
# GUI
root = Tk()
draw_button = Button(root, text="Plot!", command = main)
draw_button.grid(row=0, column=0)
# init figure
fig = plt.figure()
canvas = FigureCanvasTkAgg(fig, master=root)
toolbar = NavigationToolbar2TkAgg(canvas, root)
canvas.get_tk_widget().grid(row=0,column=1)
toolbar.grid(row=1,column=1)
root.mainloop()
答案 1 :(得分:0)
当您按下“Plot!”时按钮调用main
。 main
创建导航工具栏。因此,每次按下按钮都会出现一个工具栏。我对matplot了解不多,但很明显为什么你会得到多个工具栏。
顺便说一句,grid_forget
不会破坏小部件,只是将其从视图中删除。即使你没有看到它,它仍然在记忆中。
通常在GUI中,您只需创建一次所有窗口小部件,而不是一遍又一遍地重新创建相同的窗口小部件。