怎么将FuncAnimation生成的动图定格在最后一张图并且嵌入tkinter中
时间: 2024-03-07 11:49:26 浏览: 173
python 实现在tkinter中动态显示label图片的方法
要将 `FuncAnimation` 生成的动图定格在最后一张图并且嵌入 `tkinter` 中,可以使用 `FigureCanvasTkAgg` 类将 `matplotlib` 的画布嵌入 `tkinter` 中,并在 `tkinter` 窗口关闭时停止动画的更新。具体步骤如下:
1. 导入必要的库,包括 `matplotlib`、`numpy`、`animation` 和 `FigureCanvasTkAgg`。
```python
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
```
2. 创建 `tkinter` 窗口并设置窗口标题。
```python
root = tk.Tk()
root.title("Animated Plot")
```
3. 创建 `matplotlib` 的 `Figure` 和 `Axes` 对象,并设置初始图像。
```python
fig, ax = plt.subplots()
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
line, = ax.plot([], [])
```
4. 定义一个变量 `last_frame`,用于保存最后一帧的图像数据。
```python
last_frame = None
```
5. 修改 `update` 函数,判断是否为最后一帧,如果是则记录最后一帧的图像数据,并返回空值来停止动画更新。
```python
def update(num):
x = np.linspace(0, 10, 1000)
y = np.sin(num * x)
line.set_data(x, y)
if num == 99:
global last_frame
last_frame = ax.figure.canvas.copy_from_bbox(ax.bbox)
return None
return line,
```
6. 创建 `FuncAnimation` 对象时,将 `repeat` 参数设置为 `False`,以防止动画重复播放。
```python
ani = FuncAnimation(fig, update, frames=100, interval=50, blit=True, repeat=False)
```
7. 创建 `FigureCanvasTkAgg` 对象,用于将 `matplotlib` 的画布嵌入 `tkinter` 窗口中。
```python
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
```
8. 在 `tkinter` 窗口关闭时,停止动画的更新。
```python
def on_closing():
ani.event_source.stop()
root.destroy()
root.protocol("WM_DELETE_WINDOW", on_closing)
```
9. 在显示动画之前,先手动更新一次画布并记录最后一帧的图像数据。
```python
plt.draw()
last_frame = ax.figure.canvas.copy_from_bbox(ax.bbox)
```
10. 在显示动画之后,使用 `restore_region` 函数恢复最后一帧的图像数据,并使用 `blit` 函数将最后一帧的图像覆盖在当前画布上。
```python
ax.figure.canvas.restore_region(last_frame)
ax.draw_artist(line)
ax.figure.canvas.blit(ax.bbox)
```
完整代码如下:
```python
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
root = tk.Tk()
root.title("Animated Plot")
fig, ax = plt.subplots()
ax.set_xlim(0, 10)
ax.set_ylim(-1, 1)
line, = ax.plot([], [])
last_frame = None
def update(num):
x = np.linspace(0, 10, 1000)
y = np.sin(num * x)
line.set_data(x, y)
if num == 99:
global last_frame
last_frame = ax.figure.canvas.copy_from_bbox(ax.bbox)
return None
return line,
ani = FuncAnimation(fig, update, frames=100, interval=50, blit=True, repeat=False)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
def on_closing():
ani.event_source.stop()
root.destroy()
root.protocol("WM_DELETE_WINDOW", on_closing)
plt.draw()
last_frame = ax.figure.canvas.copy_from_bbox(ax.bbox)
plt.show()
ax.figure.canvas.restore_region(last_frame)
ax.draw_artist(line)
ax.figure.canvas.blit(ax.bbox)
```
运行代码,可以看到一个嵌入 `tkinter` 窗口中的动态图,并且在关闭窗口时停止了动画的更新。
阅读全文