I am testing matplotlib animation of a plot with random data, I am experiencing the following issues:

  • The axes ranges xlim, ylim are updated almost randomly, and when I switch between the program window and other windows.
  • 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.
  • Sometimes the default menu of the plot freezes or disapear.

These issues could appear on both linux and windows (slightly differently).

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; DR Turn blitting off and everything will 'work', but it might be slow.

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). 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.

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top