Matplotlib 动画 - 元组对象不可调用

1 投票
1 回答
4630 浏览
提问于 2025-04-20 15:24

我在使用matplotlib的FuncAnimation函数时遇到了一些问题。代码如下:

import time
from matplotlib import pyplot as plt
from matplotlib import animation
from ppbase import *

plt.ion()

#This is just essentially a stream of data
Paramater = PbaProObject("address of object")

fig = plt.figure()
ax = plt.axes(xlim=(0,2), ylim=(-90, 90))
line, = ax.plot([], [], lw=2)

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

def animate(Parameter):
  x = time.time()
  y = Parameter.ValueStr
  line.set_data(x, y)
  return line, 

anim = animation.FuncAnimation(fig, animate(Parameter), init_func=init,
                               frames=200, interval=2, blit=True)
plt.show()

然后出现的错误是:

Traceback (most recent call last):
File "C:\Anaconda\lib\site-packages\matplotlib\backend_bases.py", line 1203, in _on_timer
ret = func(*args, **kwargs)
File "C:\Anaconda\lib\site-packages\matplotlib\animation.py", line 876, in _step
still_going = Animation._step(self, *args)
File "C:\Anaconda\lib\site-packages\matplotlib\animation.py", line 735, in _step self._draw_frame(framedata)
File "C:\Anaconda\lib\site-packages\matplotlib\animation.py", line 754, in _draw_next_frame self._draw_frame(framedata, self._blit)
File "C:\Anaconda\lib\site-packages\matplotlib\animation.py", line 1049, in _draw_frame self._drawn_artists = self._func(framedata, *self._args)
TypeError: 'tuple' object is not callable

我今天早上一直在查资料,发现通常情况下plt.plot会被一个元组覆盖,所以我检查了一下,但觉得我没有在任何地方这样做。我也把blit设置为false,但这也没有帮助。我还想要能互动地更新x轴,之前在animate函数里有一行代码: ax = plt.axes(xlim((x-10), (x+10)), ylim=(-90, 90)) 但我把它去掉了,想看看这样会不会有变化。

我觉得问题主要是因为我对元组的理解不太好。另外,我对FuncAnimation函数的理解是它每次更新图表时都会调用animate(),所以我以为可以用它来更新坐标轴。但可能并不是这样。

任何帮助都很感激。

1 个回答

1

你需要传入的是函数本身,而不是调用函数后的结果。你可以把一个生成器传给 frames(这个可能只在1.4.0及以上版本有效)。

# turn your Parameter object into a generator
def param_gen(p):
    yield p.ValueStr

def animate(p):
    # get the data the is currently on the graph
    old_x = line.get_xdata()
    old_y = line.get_ydata()
    # add the new data to the end of the old data
    x = np.r_[old_x, time.time()]
    y = np.r_[old_y, p]
    # update the data in the line
    line.set_data(x, y)
    # return the line2D object so the blitting code knows what to redraw
    return line, 


anim = animation.FuncAnimation(fig, animate, init_func=init,
                           frames=param_gen(Parameter), interval=2, blit=True)

我还修复了你动画函数中的一个问题,你应该使用4个空格来缩进,而不是2个。

撰写回答