matplotlib 动画:绘图更新问题

2 投票
1 回答
2046 浏览
提问于 2025-04-18 03:46

我正在测试用随机数据制作的matplotlib动画图表,遇到了一些问题:

  • 坐标轴的范围xlimylim几乎是随机更新的,而且当我在程序窗口和其他窗口之间切换时,这种情况更明显。
  • 注释只会在坐标轴范围更新的那一帧显示,之后的帧里就消失了,直到图表再次更新。
  • 有时候,图表的默认菜单会卡住或者消失。

这些问题在Linux和Windows上都有可能出现(表现得稍微不同)。

我应该使用线程处理,还是多进程?或者是其他什么原因呢?

# -*- coding: utf-8 -*-

import re
import time
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
import random


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

def animate(i):
    y = random.randint(750, 2000) 
    xdata.append(i)
    ydata.append(y)
    xmin, xmax = ax.get_xlim()
    ymin, ymax = ax.get_ylim()
    print xmin, xmax
    print ymin, ymax

    ###changing the xmax dynamically
    if i >= xmax:
        ax.set_xlim(xmin, xmax+(xmax/2))
        ax.figure.canvas.draw()

    ###changing the ymax dynamically
    if y >= ymax:
        ax.set_ylim(ymin, y+(y/10))
        ax.figure.canvas.draw()

    #line.set_data(x, y)
    line.set_data(xdata, ydata)

    if y < 900:
        annotation = ax.annotate('Min', xy=(i, y-5))

    return line, annotation
#------------------------------------------
#initial max x axis
init_xlim = 5
init_ylim = 2000

fig = plt.figure()
ax = plt.axes(xlim=(0, init_xlim), ylim=(0, init_ylim))
ax.grid()
line, = ax.plot([], [], lw=2)
xdata, ydata = [], []

annotation = ax.annotate('Min', xy=(-1,-1))
annotation.set_animated(True)

anim = animation.FuncAnimation(fig, animate, init_func=init,frames=2000, interval=1000, blit=True)
plt.show()

1 个回答

3

简而言之,关闭“blitting”功能,一切就会“正常运作”,但可能会比较慢。

你遇到的问题是因为底层代码在使用“blitting”时做了一些假设,认为只有坐标轴区域的内容会改变(也就是说,不包括刻度),而且你是在一个固定的背景上重新绘制。简单来说,“blitting”的工作原理是,每次你更新画面时,都会在图形界面上复制一张图像,然后把这张复制的图像放回到窗口里(保存的状态是init函数结束时的状态,这个函数是由FuncAnimation调用的)。你函数返回的绘图对象会在这个保存的画布上绘制。通过这种方式更新的区域就是你坐标轴“内部”的区域。刻度标签并不是每次都重新绘制,因为绘制文本是比较耗费资源的。

因此,刻度标签只有在系统触发完全重绘时才会更新(比如改变窗口时),注释也是如此,它们会出现是因为重绘时会绘制所有的绘图对象。但在下一帧时它们又会消失,因为它们不在保存的“基础”画布上,也不在你回调函数返回的绘制对象列表中。

如果你真的必须使用“blitting”并且每次都添加新的绘图对象,你就需要做更多的工作,并且要清楚动画的基础设施是如何运作的。

撰写回答