Matplotlib.FuncAnimation工作正常,但使用`interval = ... <200`时出现奇怪的异常

时间:2018-08-24 12:25:46

标签: python animation matplotlib

我正在尝试使用Matplotlib展示行波动画(双色型)。该函数在下面介绍,并且可以正常工作,但是当我们将interval=...参数设置为小于默认值200时,会出现一个奇怪的错误。为什么以及如何删除它?谢谢。

anim = FuncAnimation(fig, update, frames=numpy.linspace(0, 60, 20*60),
                    init_func=init, blit = True, interval = 10)`

错误提示:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
    return self.func(*args)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 599, in callit
    func(*args)
  File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 147, in _on_timer
    TimerBase._on_timer(self)
  File "/usr/lib/python3/dist-packages/matplotlib/backend_bases.py", line 1305, in _on_timer
    ret = func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 1021, in _step
    still_going = Animation._step(self, *args)
  File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 827, in _step
    self._draw_next_frame(framedata, self._blit)
  File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 845, in _draw_next_frame
    self._pre_draw(framedata, blit)
  File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 858, in _pre_draw
    self._blit_clear(self._drawn_artists, self._blit_cache)
  File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 898, in _blit_clear
    a.figure.canvas.restore_region(bg_cache[a])
KeyError: <matplotlib.axes._subplots.AxesSubplot object at 0xb1599eac>

导入:

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy

cos = numpy.cos; sin = numpy.sin;

主要功能:

def bichromatic_wave_anim():

    amp = [1, 2]
    mode = ['cos', 'cos']
    phase_speed = [0.6, 0.8]
    frq = [35, 38]

    def func(x, amp, mode, frq, shift):
        y = [ amp*getattr(numpy, mode)(frq*(i-shift)) \
              for i in x ]
        return y

    N = 2000
    xl = 0; xr = 10
    dx = (xr-xl)/(N-1)
    x = [ xl + i*(xr-xl)/(N-1) for i in range(N) ]
    buoy_point = 2

    fig, ax = plt.subplots(2, 1)

    plot1, = ax[0].plot(x, func(x, amp[0], mode[0], frq[0], 0), \
                            '-', color = 'blue', lw = 1, \
                            animated = True)
    plot2, = ax[0].plot(x, func(x, amp[1], mode[1], frq[1], 0), \
                            '-', color = 'red', lw = 1, \
                            animated = True)
    bichromplot, = ax[1].plot(x, [ i+j for i,j in zip(func(x, amp[0], mode[0], frq[0], 0), func(x, amp[1], mode[1], frq[1], 0)) ], \
                                  '-', color = 'purple', lw = 2, \
                                  animated = True)
    buoy, = ax[1].plot([buoy_point], func([buoy_point], amp[0], mode[0], frq[0], 0)[0] + \
                                     func([buoy_point], amp[1], mode[1], frq[1], 0)[0], \
                                  marker = 'o', markeredgecolor = (0,0,0,0), ms = 12, color = 'orange', \
                                  animated = True)

    def init():
        ax[0].set_xlabel(r'$x$')
        ax[1].set_xlabel(r'$x$')

        ax[0].set_ylabel('Two monochromatic waves', \
                  )
        ax[1].set_ylabel(r'A bichromatic wave: ${}\{}({}x) + {}\{}({}x)$'.format(amp[0], mode[0], frq[0], amp[1], mode[1], frq[1]),\
                   )

        ax[0].legend(labels = [ r'${}\{}({}x)$'.format(i, j, k) for i, j, k in zip(amp, mode, frq) ])

        return [plot1, plot2, bichromplot, buoy]

    def update(frame):
        y1 = func(x, amp[0], mode[0], frq[0], phase_speed[0]*frame)
        y2 = func(x, amp[1], mode[1], frq[1], phase_speed[1]*frame)
        ybichrom = [ i+j for i,j in zip(func(x, amp[0], mode[0], frq[0], phase_speed[0]*frame), func(x, amp[1], mode[1], frq[1], phase_speed[1]*frame)) ]
        ybuoy = func([buoy_point], amp[0], mode[0], frq[0], phase_speed[0]*frame)[0] + \
                                     func([buoy_point], amp[1], mode[1], frq[1], phase_speed[1]*frame)[0] 
        plot1.set_data(x, y1)
        plot2.set_data(x, y2)
        bichromplot.set_data(x, ybichrom)
        buoy.set_data([buoy_point], ybuoy)

        return [plot1, plot2, bichromplot, buoy]

    anim = FuncAnimation(fig, update, frames=numpy.linspace(0, 60, 20*60),
                    init_func=init, blit = True, interval = 10) ## 'interval' can only be greater than 200 in order to remove the Error.

    fig.tight_layout()
    fig.show()

    return anim

anim = bichromatic_wave_anim()

0 个答案:

没有答案