matplotlib动画:情节更新问题

时间:2014-04-22 15:08:41

标签: python animation matplotlib annotations

我正在测试带有随机数据的情节的matplotlib动画,我遇到了以下问题:

  • 轴范围 xlim ylim 几乎随机更新, 当我在程序窗口和其他窗口之间切换时。
  • 注释仅在xlim和ylim为时显示在框架上 更新后,他们会消除下一帧,直到更新图表 试。
  • 有时情节的默认菜单会冻结或消失。

这些问题可能出现在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 个答案:

答案 0 :(得分:2)

TL; DR关闭blitting,一切都会工作,但可能会很慢。

你正在尝试使用blitting在底层代码中做出的假设,唯一改变的是轴区域中的东西(即不是刻度),并且你将在固定的背景上重新绘制。 blitting的工作方式是在gui画布上创建一个图像副本,每次更新一个框架时,副本会被blit回到gui窗口(保存的状态是{{末尾的状态) 1}} init占用的函数。然后,您的函数返回的艺术家将在此保存的画布上绘制。以这种方式更新的区域是“内部”区域。你的轴。每次都不会重新绘制刻度标签,因为绘图文本很昂贵。

因此,您的刻度标签仅在系统触发完全重绘(由更改窗口触发)时更新,与注释相同,它们会显示,因为重绘会吸引所有艺术家。它们会在下一帧再次消失,因为它们不是a)在已保存的基础上&#39;画布和b)不包括在你的回调函数返回的事物列表中。

如果你真的必须使用blitting并且每次都要添加艺术家,你将需要做更多的工作并准确理解动画基础设施的运作方式。