Python:在 tkinter 中正确嵌入带有滑块的 matplotlib 图
问题描述:
我在 pyplot 中创建了这个图,它有一个滑块来查看特定范围的数据.
I have created this plot in pyplot which has a slider to view a certain range of the data.
import random
import matplotlib
import tkinter as Tk
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
y_values = [random.randrange(20, 40, 1) for _ in range(40)]
x_values = [i for i in range(40)]
l, = plt.plot(x_values, y_values)
plt.axis([0, 9, 20, 40])
ax_time = plt.axes([0.12, 0.1, 0.78, 0.03])
s_time = Slider(ax_time, 'Time', 0, 30, valinit=0)
def update(val):
pos = s_time.val
ax.axis([pos, pos+10, 20, 40])
fig.canvas.draw_idle()
s_time.on_changed(update)
#plt.show()
matplotlib.use('TkAgg')
root = Tk.Tk()
root.wm_title("Embedding in TK")
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
Tk.mainloop()
问题是,嵌入到 tkinter 窗口中时它似乎没有响应,尽管当我用 plt.show() 显示它时(意味着此后的代码已被注释)工作正常.正确的方法是什么?
The problem is, it seems unresponsive when embedded in a tkinter window, although when I show it with plt.show() (meaning the code after this, is commented) works correctly. What is the right way to do this?
答
我想出了这个.在创建图之前,需要将该图添加到画布上.
I figured this one out. The figure needs to be added to the canvas before creating the plot.
import random
import matplotlib
import tkinter as Tk
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
matplotlib.use('TkAgg')
root = Tk.Tk()
root.wm_title("Embedding in TK")
fig = plt.Figure()
canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
ax=fig.add_subplot(111)
fig.subplots_adjust(bottom=0.25)
y_values = [random.randrange(20, 40, 1) for _ in range(40)]
x_values = [i for i in range(40)]
ax.axis([0, 9, 20, 40])
ax.plot(x_values, y_values)
ax_time = fig.add_axes([0.12, 0.1, 0.78, 0.03])
s_time = Slider(ax_time, 'Time', 0, 30, valinit=0)
def update(val):
pos = s_time.val
ax.axis([pos, pos+10, 20, 40])
fig.canvas.draw_idle()
s_time.on_changed(update)
Tk.mainloop()