Unable to save Matplotlib animations using ffmpeg - python

I have installed ffmpeg and added it to path, and checked it works in command prompt, but I am still unable to save animations. I have tried creating a sin wave that will animate when I don't try to save it, but throws an error when I do to demonstrate;
from __future__ import division
import numpy as numpy
from matplotlib import pyplot as pyplot
from matplotlib import animation
fig = pyplot.figure()
ax = pyplot.axes(xlim=(0, 2), ylim=(-2, 2))
line, = ax.plot([], [], lw=2)
def init():
line.set_data([], [])
return line,
def animate(i):
x = numpy.linspace(0, 2, 1000)
y = numpy.sin(2 * numpy.pi * (x - 0.01 * i))
line.set_data(x, y)
return line,
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200,
interval=20, blit=True, repeat=False)
FFwriter = animation.FFMpegWriter()
anim.save('animation_testing.mp4', writer = FFwriter)
pyplot.show()
When I try to run this it throws the same errors over and over again, I assume as it iterates through each frame;
Traceback (most recent call last):
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\backends\backend_wx.py", line 212, in _on_timer
TimerBase._on_timer(self)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\backend_bases.py", line 1273, in _on_timer
ret = func(*args, **kwargs)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\animation.py", line 910, in _step
still_going = Animation._step(self, *args)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\animation.py", line 769, in _step
self._draw_next_frame(framedata, self._blit)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\animation.py", line 787, in _draw_next_frame
self._pre_draw(framedata, blit)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\animation.py", line 800, in _pre_draw
self._blit_clear(self._drawn_artists, self._blit_cache)
File "c:\users\james\appdata\local\enthought\canopy\user\lib\site-
packages\matplotlib\animation.py", line 840, in _blit_clear
a.figure.canvas.restore_region(bg_cache[a])
KeyError: <matplotlib.axes._subplots.AxesSubplot object at 0x0000000009C04DD8>
Since it mentioned an error in _blit_clear I tried changing blit to False in FuncAnimation, but then it wouldn't animate in the pyplot.show() when I didn't try to save.
I'm unsure as to where the error could be and so can't work out how to fix this.
I'm using Windows 10, python 2.7.6 and matplotlib version 1.4.2
Many Thanks!

Adding;
pyplot.switch_backend('backend')
where backend is either TkAgg or Qt4Agg solved my problem.
Thank you to ImportanceOfBeingErnest for solving this for me!

Related

How to animate a rectangle on a polar plot in Matplotlib

I have been trying to animate a polar plot in which I have a one degree wide wedge sweep all the way around the plot in a circle. I tried using the code below, but for some reason, it gives me the error AttributeError: 'NoneType' object has no attribute 'canvas'. I was trying to initialize the wedge as a rectangle patch that starts off on the right side of the plot and increases in x (angle), so I thought I should update the x-coordinate in the animate function, but for some reason, whenever I return patch (the rectangle) from animation, it gives me an error. Any tips? Thanks!
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.patches import Rectangle
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
_, rlim = ax.get_ylim()
patch = Rectangle((0,0), np.radians(1), rlim)
def init():
ax.add_patch(patch)
return patch,
def animate(i):
patch.set_xy((np.radians(i), 0))
return patch,
ani = animation.FuncAnimation(fig, animate, frames=360, interval=30, blit=True)
plt.show()
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib64/python3.6/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/usr/lib64/python3.6/tkinter/__init__.py", line 749, in callit
func(*args)
File "/usr/lib64/python3.6/site-packages/matplotlib/backends/_backend_tk.py", line 114, in _on_timer
TimerBase._on_timer(self)
File "/usr/lib64/python3.6/site-packages/matplotlib/backend_bases.py", line 1187, in _on_timer
ret = func(*args, **kwargs)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1449, in _step
still_going = Animation._step(self, *args)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1169, in _step
self._draw_next_frame(framedata, self._blit)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1189, in _draw_next_frame
self._post_draw(framedata, blit)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1212, in _post_draw
self._blit_draw(self._drawn_artists, self._blit_cache)
File "/usr/lib64/python3.6/site-packages/matplotlib/animation.py", line 1229, in _blit_draw
bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
AttributeError: 'NoneType' object has no attribute 'canvas'

edgecolors='None' causes error on animated 3d scatterplot

I'm trying to make a 3d scatterplot with fading points over time, similar to this question. However, when I apply the colormap to the data, then the face of the marker changes color but the edge remains solid.
I've tried using the edgecolors='None', edgecolor='none' kwargs, the marker='o' kwarg as per this example, and the edgecolor='face' kwarg. I've also tried using post creation methods such as scat3D.set_edgecolor("None") etc. The first attempts throw an error, and the latter have no effect.
Error from setting kwargs:
Traceback (most recent call last):
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 230, in saving
yield self
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 1156, in save
writer.grab_frame(**savefig_kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/animation.py", line 384, in grab_frame
dpi=self.dpi, **savefig_kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/figure.py", line 2180, in savefig
self.canvas.print_figure(fname, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_qt5agg.py", line 88, in print_figure
super().print_figure(*args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 2082, in print_figure
**kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 442, in print_raw
FigureCanvasAgg.draw(self)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/backends/backend_agg.py", line 388, in draw
self.figure.draw(self.renderer)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/figure.py", line 1709, in draw
renderer, self, artists, self.suppressComposite)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/image.py", line 135, in _draw_list_compositing_images
a.draw(renderer)
File "/home/max/.local/lib/python3.6/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 292, in draw
reverse=True)):
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 291, in <lambda>
key=lambda col: col.do_3d_projection(renderer),
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py", line 545, in do_3d_projection
ecs = (_zalpha(self._edgecolor3d, vzs) if self._depthshade else
File "/home/max/.local/lib/python3.6/site-packages/mpl_toolkits/mplot3d/art3d.py", line 847, in _zalpha
rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4))
File "<__array_function__ internals>", line 6, in broadcast_to
File "/home/max/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 182, in broadcast_to
return _broadcast_to(array, shape, subok=subok, readonly=True)
File "/home/max/.local/lib/python3.6/site-packages/numpy/lib/stride_tricks.py", line 127, in _broadcast_to
op_flags=['readonly'], itershape=shape, order='C')
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (0,4) and requested shape (100,4)
(There's a during the handling the above exception another occured error after that, but my post was flagged as spam so I didn't include it)
Here's the code without the error (adding a kwarg listed above causes the error):
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.patches as mpatches
total = 10
num_whatever = 100
to_plot = [np.random.rand(num_whatever, 3) for i in range(total)]
colors = np.linspace(0, 1, num_whatever)
fig = plt.figure()
ax3d = Axes3D(fig)
scat3D = ax3d.scatter([],[],[], s=10, cmap="Blues", vmin=0, vmax=1)
scat3D.set_cmap("Blues") # cmap argument above is ignored, so set it manually
ttl = ax3d.text2D(0.05, 0.95, "", transform=ax3d.transAxes)
def update_plot(i):
print( i, to_plot[i].shape)
ttl.set_text('PCA on 3 components at step = {}'.format(i*20))
scat3D._offsets3d = np.transpose(to_plot[i])
scat3D.set_array(colors)
return scat3D,
def init():
scat3D.set_offsets([[],[],[]])
plt.style.use('ggplot')
ani = animation.FuncAnimation(fig, update_plot, init_func=init,
blit=False, interval=300, frames=range(total))
ani.save("ani.gif", writer="imagemagick")
plt.show()
Here's the plot with the marker edges not hidden:
Plot
You can see that the faded points still have the marker edges not colormapped. I would expect that setting edgecolor would be unnecessary in the first place, since the 2d animation clearly doesn't need it. But why would adding that kwarg cause me to get a operands could not be broadcast togeather error? I don't have any array with shape (0, 4), so it's not clear where this is coming from.
The problem is that if c (as the color argument) is not specified, it is not a priori clear if a colormapping should happen or not. This leads to some internal confusion about which arguments to obey to. But we can specify c as an empty list to get around that.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
total = 10
num_whatever = 100
to_plot = [np.random.rand(num_whatever, 3) for i in range(total)]
colors = np.linspace(0, 1, num_whatever)
fig = plt.figure()
ax3d = Axes3D(fig)
scat3D = ax3d.scatter([], [], [], s=10, c=[], cmap="Blues", vmin=0, vmax=1,
depthshade=False)
ttl = ax3d.text2D(0.05, 0.95, "", transform=ax3d.transAxes)
def update_plot(i):
print( i, to_plot[i].shape)
ttl.set_text('PCA on 3 components at step = {}'.format(i*20))
scat3D._offsets3d = np.transpose(to_plot[i])
scat3D.set_array(colors)
return scat3D,
def init():
scat3D.set_offsets([[],[],[]])
plt.style.use('ggplot')
ani = animation.FuncAnimation(fig, update_plot, init_func=init,
blit=False, interval=300, frames=range(total))
ani.save("ani.gif", writer="imagemagick")
plt.show()

Matplotlib problems with converting string into date readable format cannot be compiled

I've got a problem with programming live - changing plot and histogram from csv file, where the data is saved - the record contains date ('%Y-%M-%D %H:%m:%S') and the time seperated, by tabulator sign '\t'.
However, I was searching through several toturials and documentation and simply can't fix it. Below, there are links I came across:
https://github.com/etsy/skyline/issues/123
How to fix AttributeError: 'Series' object has no attribute 'find'?
https://docs.python.org/3.4/library/datetime.html
Python/Numpy: problems with type conversion in vectorize and item
I did not find answer there and other similar websites, including sentdex toturials on YT. The code below is going to be compiled and used at Raspberry Pi 3 B+, but it was created on Ubuntu OS on standard PC - this code works perfectly there:
import serial
import pandas as pd
import matplotlib.pyplot as plt
import csv
import datetime
import matplotlib.animation as animation
fig, axes = plt.subplots(nrows=1, ncols=2)
ax1, ax2 = axes.flatten()
def update(i):
file_data = pd.read_csv("/home/pi/Desktop/score_board3", delimiter="\t",
parse_dates=[0], header=None, usecols=[0, 1])
ax1.clear()
ax2.clear()
ax1.plot(file_data[0].astype(float), file_data[1])
ax2.hist([file_data[1],], bins='auto', histtype='bar', facecolor='#FF8C00', edgecolor='red')
ax1.set_title('History')
ax1.set_xlabel('Measurement time')
ax1.set_ylabel('Reaction time [s]')
ax2.set_title('Histogram')
ax2.set_xlabel('Reaction time [s]')
ax2.set_ylabel('Number of results')
ani = animation.FuncAnimation(fig, update, interval=1000)
plt.show()
arduino = serial.Serial('/dev/ttyACM0', 9600)
file = open ('/home/pi/Desktop/Noc_Naukowcow/score_board3', 'r+')
try:
while True:
file.read(1)
new_score = arduino.readline()
print(new_score)
score = new_score.decode('utf-8').strip() + "\n"
score_time = '{:%Y-%M-%D %H:%m:%S}'.format(datetime.datetime.now())
file.write(score_time)
file.write('\t')
file.write(score)
file.flush()
except KeyboardInterrupt:
print("KeyboardInterrupt has been caught.")
file.close()
scores_to_read.close()
After compiling that code, I receive a lot of errors found:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
return self.func(*args)
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 280, in resize
self.show()
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_tkagg.py", line 351, in draw
FigureCanvasAgg.draw(self)
File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_agg.py", line 464, in draw
self.figure.draw(self.renderer)
File "/usr/lib/python3/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/figure.py", line 1150, in draw
self.canvas.draw_event(renderer)
File "/usr/lib/python3/dist-packages/matplotlib/backend_bases.py", line 1815, in draw_event
self.callbacks.process(s, event)
File "/usr/lib/python3/dist-packages/matplotlib/cbook.py", line 549, in process
proxy(*args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/cbook.py", line 416, in __call__
return mtd(*args, **kwargs)
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 831, in _start
self._init_draw()
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 1490, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "/usr/lib/python3/dist-packages/matplotlib/animation.py", line 1512, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
File "/home/pi/Desktop/kod testowy.py", line 16, in update
parse_dates=[0], header=None, usecols=[0, 1])
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 678, in parser_f
return _read(filepath_or_buffer, kwds)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 440, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 787, in __init__
self._make_engine(self.engine)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1014, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1756, in __init__
_validate_usecols_names(usecols, self.names)
File "/home/pi/.local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1134, in _validate_usecols_names
"columns expected but not found: {missing}".format(missing=missing)
ValueError: Usecols do not match columns, columns expected but not found: [1]
UPDATE:
I think I've just overcame that problem using thread library. However I need to figure out how to set up them together:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import serial
import datetime
import threading
fig, axes = plt.subplots(nrows=2, ncols=1)
ax1, ax2 = axes.flatten()
scores_to_read = serial.Serial ('/dev/ttyACM0', 9600)
file = open ("/home/pi/Desktop/Noc_Naukowcow/score_board.csv", 'r+')
def update(i):
file_data = pd.read_csv("/home/pi/Desktop/Noc_Naukowcow/score_board.csv", delimiter="\t",
parse_dates=[0], header=None, usecols=[0, 1])
ax1.clear()
ax2.clear()
ax1.plot(file_data[0],file_data[1])
ax2.hist([file_data[1],], bins='auto', histtype='bar')
#ax1.set_title('History')
ax1.set_xlabel('Measurement time')
ax1.set_ylabel('Reaction time [s]')
#ax2.set_title('Histogram')
ax2.set_xlabel('Reaction time [s]')
ax2.set_ylabel('Number of results')
ani = animation.FuncAnimation(fig, update, interval=1000)
plt.plot()
def serial_port(file):
file.read()
new_score = scores_to_read.readline()
print(new_score)
score = new_score.decode('utf-8').strip() + "\n"
score_time = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())
file.write(score_time)
file.write('\t')
file.write(score)
file.flush()
thread1 = threading.Thread(target=serial_port, args=(file))
thread1.start()

Animating 3D scatter plot using Python mplotlib via serial data

I am trying to animate a 3D scatter plot using mplotlib in Python. I am able to graph the data and redraw every time, but this results in a frame rate of less than 1 FPS, and I need to scale to upwards of 30 FPS. When I run my code:
import serial
import numpy
import matplotlib.pyplot as plt #import matplotlib library
from mpl_toolkits.mplot3d import Axes3D
from drawnow import *
import matplotlib.animation
import time
ser = serial.Serial('COM7',9600,timeout=5)
ser.flushInput()
time.sleep(5)
ser.write(bytes(b's1000'))
x=list()
y=list()
z=list()
#plt.ion()
fig = plt.figure(figsize=(16,12))
ax = fig.add_subplot(111, projection="3d")
graph = ax.scatter(x,y,z, c='r',marker='o')
ax.set_xlim3d(-255, 255)
ax.set_ylim3d(-255, 255)
ax.set_zlim3d(-255, 255)
def generate():
while True:
try:
ser_bytes = ser.readline()
data = str(ser_bytes[0:len(ser_bytes)-2].decode("utf-8"))
xyz = data.split(", ")
dx = float(xyz[0])
dy = float(xyz[1])
dz = float(xyz[2].replace(";",""))
x.append(dx);
y.append(dy);
z.append(dz);
graph._offset3d(x,y,z, c='r',marker='o')
except:
print("Keyboard Interrupt")
ser.close()
break
return graph,
ani = matplotlib.animation.FuncAnimation(fig, generate(), interval=1, blit=True)
plt.show()
I get the following error:
Traceback (most recent call last):
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook\__init__.py", line 388, in process
proxy(*args, **kwargs)
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook\__init__.py", line 228, in __call__
return mtd(*args, **kwargs)
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1026, in _start
self._init_draw()
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1750, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1772, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
TypeError: 'tuple' object is not callable
Traceback (most recent call last):
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook\__init__.py", line 388, in process
proxy(*args, **kwargs)
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook\__init__.py", line 228, in __call__
return mtd(*args, **kwargs)
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1308, in _handle_resize
self._init_draw()
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1750, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Users\bunti\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1772, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
TypeError: 'tuple' object is not callable
I am receiving x, y, z coordinates from a lidar module connected to an Arduino, which sends the coordinates over serial to the Python script.
A possible problem with your code is that the animation function (generate) is not supposed to run in an infinite loop. Furthermore, you are supposed to pass a reference to that function to FuncAnimate, but instead you are calling the function (i.e. you need to omit the parentheses in FuncAnimation(..., generate, ...)
The second problem is that you are treating graph._offset3d as if it was a function, when it is merely a tuple of lists. You should assign a new tuple to it, instead of trying to call the function (which I believe is what the error message alludes to).
I simplified your code and the following works fine:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
def update_lines(num):
dx, dy, dz = np.random.random((3,)) * 255 * 2 - 255 # replace this line with code to get data from serial line
text.set_text("{:d}: [{:.0f},{:.0f},{:.0f}]".format(num, dx, dy, dz)) # for debugging
x.append(dx)
y.append(dy)
z.append(dz)
graph._offsets3d = (x, y, z)
return graph,
x = [0]
y = [0]
z = [0]
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111, projection="3d")
graph = ax.scatter(x, y, z, color='orange')
text = fig.text(0, 1, "TEXT", va='top') # for debugging
ax.set_xlim3d(-255, 255)
ax.set_ylim3d(-255, 255)
ax.set_zlim3d(-255, 255)
# Creating the Animation object
ani = animation.FuncAnimation(fig, update_lines, frames=200, interval=50, blit=False)
plt.show()

Matplotlib animation - tuple object is not callable

having issues with the FuncAnimantion function in matplotlib. Code is as follows:
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()
And the error is:
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
Been reading around all morning and it seems commonly plt.plot is overwritten by a tuple, so I checked for that but don't think I have done it anywhere. I've also turned blit to false but that didn't help either. I do also want to interactively update the x-axis, I had line:
ax = plt.axes(xlim((x-10), (x+10)), ylim=(-90, 90))
in the animate function but took that out to see if it made any difference.
I think mostly the problems stem from not really understanding tuples too well. Also my understanding of the FuncAnimation function is that it calls the animate() each time it updates the plot - hence why I though that I could use it to update the axis' also. But this may not be the case.
Any help appreciated.
You need to pass in the function object not the result of the calling the function and you can pass a generator to frames (this might only work on 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)
I also fixed a problem with your animation function and you should use 4 space indents, not 2.

Categories

Resources