简体   繁体   English

matplotlib动画:情节更新问题

[英]matplotlib animation: plot update issues

I am testing matplotlib animation of a plot with random data, I am experiencing the following issues: 我正在使用随机数据测试绘图的matplotlib动画,遇到以下问题:

  • The axes ranges xlim , ylim are updated almost randomly, and when I switch between the program window and other windows. 当我在程序窗口和其他窗口之间切换时, xlimylim轴范围几乎是随机更新的。
  • The annotations are shown only on the frame when xlim and ylim are updated they disapear the next frames until the plot is updated again. 仅当更新xlim和ylim时, 注释才会显示在框架上,它们会消失下一帧,直到再次更新绘图。
  • Sometimes the default menu of the plot freezes or disapear. 有时,情节的默认菜单会冻结或消失。

These issues could appear on both linux and windows (slightly differently). 这些问题可能同时在linux和Windows上出现(略有不同)。

Should I implement threading or eventually multiprocessing? 我应该实现线程化还是最终实现多处理? or is it something else? 或者是别的什么?

# -*- 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()

TL; TL; DR Turn blitting off and everything will 'work', but it might be slow. DR关闭提示音,一切都会正常运行,但是速度可能很慢。

You are running into assumptions made in the underlying code using blitting that the only thing changing will be be the stuff in the axes area (ie, not the ticks) and that you will be re-drawing on a fixed background. 您会碰到在底层代码中做出的假设,即唯一的更改将是轴区域中的内容(即不是刻度线),并且您将在固定的背景上重新绘制。 The way that blitting works is that a copy of the image on the gui canvas is made, each time you update a frame that copy is blitted back into the gui window (the state that is saved is the state at the end of the init function that FuncAnimation takes). blitting的工作方式是在gui画布上制作图像的副本,每次更新框架时,副本都会被blit到gui窗口中(保存的状态是init函数结尾的状态FuncAnimation需要)。 The artists returned by your function are then drawn on top of this saved canvas. 然后,由您的函数返回的艺术家将被绘制在此保存的画布上。 The region that gets updated this way is the region 'inside' your axes. 以这种方式更新的区域是轴“内部”的区域。 The tick label are not re-drawn every time because drawing text is expensive. 由于绘图文本价格昂贵,因此不会每次都重新绘制刻度标签。

Hence, your tick labels only update when the system triggers a full-redraw (triggered by changing windows), same with the annotations, they show up because the re-draw draws all artists. 因此,您的勾号标签仅在系统触发完全重画(通过更改窗口触发)时更新,与注解相同,它们会显示,因为重画会绘制所有艺术家。 They go away again on the next frame because they are not a) on the saved 'base' canvas and b) not included in the list of things to draw returned by your call back function. 它们在下一帧再次消失,因为它们不是a)在已保存的“基本”画布上,并且b)未包含在回调函数返回的要绘制的事物列表中。

If you really must use blitting and add artists each time through you will have to do a bit more work and understand exactly how the animation infrastructure works. 如果您真的必须每次使用blitting并添加艺术家,那么您将需要做更多的工作并确切了解动画基础结构的工作方式。

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

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