简体   繁体   English

在嵌入 tkinter 的按钮按下时暂停/停止 matplotlib 的 animation

[英]Pause/Stop animation of matplotlib on button press embedded in tkinter

I am using the following code from Tutorials Point.我正在使用来自教程点的以下代码。 Here the Quit button stops the program, but I want to pause the animation on another button press.这里退出按钮停止程序,但我想在另一个按钮按下时暂停 animation。 I found other resources that work on onclick() in the figure, but I want to do this from a Pause button.我在图中找到了在 onclick() 上工作的其他资源,但我想通过暂停按钮执行此操作。

How can I implement that?我该如何实施?

import tkinter
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib import pyplot as plt, animation
import numpy as np

plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True

root = tkinter.Tk()
root.wm_title("Embedding in Tk")

plt.axes(xlim=(0, 2), ylim=(-2, 2))
fig = plt.Figure(dpi=100)
ax = fig.add_subplot(xlim=(0, 2), ylim=(-1, 1))
line, = ax.plot([], [], lw=2)

canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()

toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()

canvas.mpl_connect(
    "key_press_event", lambda event: print(f"you pressed {event.key}"))
canvas.mpl_connect("key_press_event", key_press_handler)

button = tkinter.Button(master=root, text="Quit", command=root.quit)
button.pack(side=tkinter.BOTTOM)

toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    x = np.linspace(0, 2, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,frames=200, interval=20, blit=True)

tkinter.mainloop()

I based my answer on the answer here , which has a great explanation of using a click to pause the animation (which you had already researched).我的答案基于此处的答案,其中很好地解释了使用单击暂停 animation(您已经研究过)。 The functionality of my answer is the same as the example, just modifying the pause function to be driven by a tkinter button instead of a mouse click and implementing it in your code.我的答案的功能与示例相同,只是将暂停 function 修改为由 tkinter 按钮驱动,而不是单击鼠标并在代码中实现它。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
import tkinter as tkinter
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler

plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True

root = tkinter.Tk()
root.wm_title("Embedding in Tk")

plt.axes(xlim=(0, 2), ylim=(-1, 1))
fig = plt.Figure(dpi=100)
ax = fig.add_subplot(xlim=(0, 2), ylim=(-1, 1))
line, = ax.plot([], [], lw=2)

canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()

toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()

canvas.mpl_connect(
    "key_press_event", lambda event: print(f"you pressed {event.key}"))
canvas.mpl_connect("key_press_event", key_press_handler)

button = tkinter.Button(master=root, text="Quit", command=root.quit)
button.pack(side=tkinter.BOTTOM)

# Pause button and function
pause = False
def pause_animation():
    global pause
    pause ^= True
button2 = tkinter.Button(master=root, text="Pause", command=pause_animation)
button2.pack(side=tkinter.BOTTOM)

toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

def animation_data():
    tMax = 100  # 0.01*tMax/dt needs to be an int for smooth animation
    dt = 1      # Changing dt changes the "speed" that the curve moves on the plot
    y = 0.0
    t = 0
    x = np.linspace(0, 2, 1000)
    while t<tMax:   # This is included to reset t so it doesn't get too large for long runs
        if not pause:
            y = np.sin(2 * np.pi * (x - 0.01 *t))
            t = t + dt
        yield x, y

def animate(animation_data):
    x, y = animation_data[0], animation_data[1]
    line.set_data(x, y)
    return line,

ani = animation.FuncAnimation(fig, animate, animation_data, blit=True, interval=10,
    repeat=True)

tkinter.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM