This question already has an answer here:
Using FFmpeg and IPython
(1 answer)
Closed 7 years ago.
I'm using matplotlib to make an animated heatmap. I have data in a text file (rs_h) with 3 columns - x, y, z; i'm using scatterplot to make a simple heatmap, and then using the animation package to update the heatmap over time
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
data = pd.read_table('rs_h', header=None, sep=r"\s*")
frames = np.array_split(data, 9)
def main():
numframes = 9
numpoints = 75
x, y, c = np.random.random((3, numpoints))
fig = plt.figure()
scat = plt.scatter(x, y, c=c)#, s=100)
ani = animation.FuncAnimation(fig, update_plot, frames=xrange(numframes),
interval = 5)
#ani.save("movie.avi", codec='avi')
plt.show()
def update_plot(i):
frame = frames[i]
scat = plt.scatter(frame[0], frame[1], c=frame[2])
return scat,
main()
I'm having no trouble getting the animated heatmap; however, i run into an issue when i try to save the animation
/Users/Arjun/anaconda/lib/python2.7/site-packages/matplotlib/animation.py:695: UserWarning: MovieWriter ffmpeg unavailable
warnings.warn("MovieWriter %s unavailable" % writer)
Traceback (most recent call last):
File "heat_ani.py", line 29, in <module>
main()
File "heat_ani.py", line 21, in main
ani.save("movie.avi", codec='avi')
File "/Users/Arjun/anaconda/lib/python2.7/site-packages/matplotlib/animation.py", line 712, in save
with writer.saving(self._fig, filename, dpi):
AttributeError: 'str' object has no attribute 'saving'
Anyone know what the issue is and how to get around it?
EDIT: The issue was that i didn't have ffmpeg installed. A simple brew install allowed the code to work
I found a solution for Linux. Basically you need ffmpeg library or libav-tools
Open terminal and type as root
apt-get install ffmpeg
or
apt-get install libav-tools
Hope it might help.
Related
I've been trying to export an animated gif on my windows computer for several days.
Here is the basic code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro', animated=True)
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
ani.save("test.gif")
plt.show()
And the error:
>>> python .\anim_test.py
Traceback (most recent call last):
File ".\anim_test.py", line 22, in <module>
ani.save("test.gif")
File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 1063, in save
writer.grab_frame(**savefig_kwargs)
File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 336, in grab_frame
'with --verbose-debug.'.format(e, out, err))
IOError: Error saving animation to file (cause: [Errno 22] Invalid argument) Stdout: StdError: . It may help to re-run
with --verbose-debug.
PS C:\Users\ishma\Dropbox (SteinLab)\spectra\MassSpecPlot> python .\anim_test.py --verbose-debug
$HOME=C:\Users\ishma
matplotlib data path C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\mpl-data
*****************************************************************
You have the following UNSUPPORTED LaTeX preamble customizations:
Please do not ask for support with these customizations active.
*****************************************************************
loaded rc file C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\mpl-data\matplotlibrc
matplotlib version 2.0.2
verbose.level debug
interactive is False
platform is win32
loaded modules: <dictionary-keyiterator object at 0x0000000003EA0048>
CACHEDIR=C:\Users\ishma\.matplotlib
Using fontManager instance from C:\Users\ishma\.matplotlib\fontList.cache
backend Qt5Agg version 5.6
Animation.save using <class 'matplotlib.animation.FFMpegWriter'>
frame size in pixels is 640 x 480
MovieWriter.run: running command: ffmpeg -f rawvideo -vcodec rawvideo -s 640x480 -pix_fmt rgba -r 5.0 -i pipe: -vcodec h
264 -pix_fmt yuv420p -y test.gif
MovieWriter.grab_frame: Grabbing frame.
findfont: Matching :family=sans-serif:style=normal:variant=normal:weight=400:stretch=normal:size=10.0 to DejaVu Sans (u'
C:\\Users\\ishma\\Anaconda2\\lib\\site-packages\\matplotlib\\mpl-data\\fonts\\ttf\\DejaVuSans.ttf') with score of 0.0000
00
MovieWriter.grab_frame: Grabbing frame.
MovieWriter -- Error running proc:
None
None
MovieWriter -- Command stdout:
None
MovieWriter -- Command stderr:
None
Traceback (most recent call last):
File ".\anim_test.py", line 22, in <module>
ani.save("test.gif")
File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 1063, in save
writer.grab_frame(**savefig_kwargs)
File "C:\Users\ishma\Anaconda2\lib\site-packages\matplotlib\animation.py", line 336, in grab_frame
'with --verbose-debug.'.format(e, out, err))
IOError: Error saving animation to file (cause: [Errno 22] Invalid argument) Stdout: None StdError: None. It may help to
re-run with --verbose-debug.
If I switch the output file type to mp4, the code works. After reading many threads from people with errors producing video files, I feel like I have tried every combination of different writers (including FFMpegWriter, ImageMagickWriter, AVConvWriter, and the FileWriters as well), made sure the relevant programs are in my PATH, changed settings in matplotlibrc, and tried multiple computers. I'm stumped.
I've found only one thread referencing this exact error:
https://stackoverflow.com/questions/46562938/oserror-errno-22-invalid-argument-error-saving-animation-to-file
But following the advice in the comments there haven't solved my problem.
Any ideas? Thanks for any help.
With the code from the question you are basically asking to produce an animated gif using the MPEG writer. The MPEG writer however is only able to produce videos.
The standard way to produce an animated gif through the matplotlib animation module is to use ImageMagick.
So first change your line to
ani.save("test.gif",writer="imagemagick")
Now for this to work the rcParam animation.convert_path must point to the ImageMagick's convert program.
It seems you are on windows here, so it's best to include the complete path to it. Hence, before the saving, set
plt.rcParams["animation.convert_path"] = "C:\ProgramFiles\ImageMagick\convert.exe"
or whatever your path to the convert.exe may be.
Now it may apparently happen that convert.exe is not part of newer versions of imageMagick anymore. The documentation says
If these tools are not available, you can simply append them to the magick tool like this:
magick convert.
For the matplotlib animation this means that you would need to set an extra argument. Set the path to
plt.rcParams["animation.convert_path"] = "C:\ProgramFiles\ImageMagick\magick.exe"
then call
ani.save("test.gif",writer="imagemagick", extra_args="convert")
The following piece of code works fine when I run the script in pycharm
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.patches as mpatches
c1 = mpatches.Patch(color="green",label="No Traffic")
c2 = mpatches.Patch(color="red",label="Traffic")
df = predict_df.limit(100).toPandas()
colors = {0:"red",1:"green"}
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df["avgSpeed"],df["vehicleCount"],df["avgMeasuredTime"],c=df["prediction"].apply(lambda x: colors[x]),s=100,marker="o")
ax.set_xlabel('avgMeasuredTime')
ax.set_ylabel('avgSpeed')
ax.set_zlabel('vehicleCount')
plt.title("BiKmeans Traffic Data")
plt.legend(handles=[c1,c2])
plt.show()
I have installed matplotlib using pip, also based on some similar questions tried to install as sudo apt-get install python-matplotlib
but I get the same error in Zepplin,
File "/home/benjamin/.local/lib/python2.7/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 280, in <lambda>
key=lambda col: col.do_3d_projection(renderer), AttributeError: 'PathCollection' object has no attribute 'do_3d_projection'
The version of matplotlib is 2.2.0
I am trying to learn Python. I am using the following program, which creates the image OK, but I want to save it. I tried some instructions I found on this site, but am getting the error message at the bottom. Any help would be appreciated.
Program:
import sys
import random
import matplotlib as plt
from graphics import *
def main():
m=1
n=2
offset=50
win = GraphWin("MyWin",500, 500)
win.setBackground(color_rgb(0,0,0))
for i in range(1,1000,1):
r= random.uniform(0,1)
q= int(3*r)
m = (m/2) + q*(q-1)*75
n = (n/2) + q*(3-q)*75
pt = Point(m + offset,n + offset)
pt.setOutline(color_rgb(255,255,0))
pt.draw(win)
print("graphic done")
plt.savefig("figure.png")
win.getMouse()
win.close()
if __name__ == '__main__':
main()
Error Message:
graphic done
Traceback (most recent call last):
File "fractal_1.py", line 29, in <module>
main()
File "fractal_1.py", line 24, in main
plt.savefig("figure.png")
AttributeError: module 'matplotlib' has no attribute 'savefig'
The call to plt.savefig("figure.png") will only work if you have imported as follows:
import matplotlib.pyplot as plt.
I believe your error lies with plt and what it actually references. If you imported like this:import matplotlib as plt
then you would need to call the required function like this: plt.pyplot.savefig("figure.png")
If you imported like this:import matplotlib.pyplot as plt
then you can call the required function like this: plt.savefig("figure.png")
Thanks for including the error, but what that's saying is that matplotlib doesn't have a savefig() function.
I think it's matplotlib.pyplot.savefig() as per this link: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.savefig.html
Edit your code to say: plt.pyplot.savefig().
I am using Zeppelin and matplotlib to visualize some data. I try them but fail with the error below. Could you give me some guidance how to fix it?
%pyspark
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()
And here is the error I've got
Traceback (most recent call last):
File "/tmp/zeppelin_pyspark-3580576524078731606.py", line 235, in <module>
eval(compiledCode)
File "<string>", line 1, in <module>
File "/usr/lib64/python2.6/site-packages/matplotlib/pyplot.py", line 78, in <module>
new_figure_manager, draw_if_interactive, show = pylab_setup()
File "/usr/lib64/python2.6/site-packages/matplotlib/backends/__init__.py", line 25, in pylab_setup
globals(),locals(),[backend_name])
File "/usr/lib64/python2.6/site-packages/matplotlib/backends/backend_gtkagg.py", line 10, in <module>
from matplotlib.backends.backend_gtk import gtk, FigureManagerGTK, FigureCanvasGTK,\
File "/usr/lib64/python2.6/site-packages/matplotlib/backends/backend_gtk.py", line 8, in <module>
import gtk; gdk = gtk.gdk
File "/usr/lib64/python2.6/site-packages/gtk-2.0/gtk/__init__.py", line 64, in <module>
_init()
File "/usr/lib64/python2.6/site-packages/gtk-2.0/gtk/__init__.py", line 52, in _init
_gtk.init_check()
RuntimeError: could not open display
I also try to add these lines, but still cannot work
import matplotlib
matplotlib.use('Agg')
The following works for me with Spark & Python 3:
%pyspark
import matplotlib
import io
# If you use the use() function, this must be done before importing matplotlib.pyplot. Calling use() after pyplot has been imported will have no effect.
# see: http://matplotlib.org/faq/usage_faq.html#what-is-a-backend
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def show(p):
img = io.StringIO()
p.savefig(img, format='svg')
img.seek(0)
print("%html <div style='width:600px'>" + img.getvalue() + "</div>")
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
show(plt)
The Zeppelin documentation suggests that the following should work:
%python
import matplotlib.pyplot as plt
plt.figure()
(.. ..)
z.show(plt)
plt.close()
This doesn't work for me with Python 3, but looks to be addressed with the soon-to-be-merged PR #1213.
Note that as of Zeppelin 0.7.3, matplotlib integration is much more seamless, so the methods described here are no longer necessary. https://zeppelin.apache.org/docs/latest/interpreter/python.html#matplotlib-integration
As per #eddies suggestion, I tried and this is what worked for me on Zeppelin 0.6.1 python 2.7
%python
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.figure()
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
z.show(plt, width='500px')
plt.close()
Change this:
import matplotlib
matplotlib.use('Agg')
with
import matplotlib.pyplot as plt; plt.rcdefaults()
plt.switch_backend('agg')
Complete code example Spark 2.2.0 + python3(anaconda3.5):
%spark.pyspark
import matplotlib.pyplot as plt; plt.rcdefaults()
plt.switch_backend('agg')
import numpy as np
import io
def show(p):
img = io.StringIO()
p.savefig(img, format='svg')
img.seek(0)
print ("%html <div style='width:600px'>" + img.getvalue() + "</div>")
# Example data
people=('Tom', 'Dick', 'Harry', 'Slim', 'Jim')
y_pos=np.arange(len(people))
performance=3 + 10 * np.random.rand(len(people))
error=np.random.rand(len(people))
plt.barh(y_pos, performance, xerr=error, align='center', alpha=0.4)
plt.yticks(y_pos, people)
plt.xlabel('Performance')
plt.title('How fast do you want to go today?')
show(plt)
I would suggest you to use IPython/IPySpark interpreter in zeppelin 0.8.0 which will be released soon. The matplotlib integration in ipython is almost the same as jupyter. There's one tutorial https://www.zepl.com/viewer/notebooks/bm90ZTovL3pqZmZkdS9lN2Q3ODNiODRkNjA0ZjVjODM1OWZlMWExZjM4OTk3Zi9ub3RlLmpzb24
This is my first post so please be forgiving.
I am trying to create an animation using matplotlib, and I could do this perfectly well until a few days ago, until I upgraded to OS X Mavericks, upon which all hell broke loose. Note, the below code worked in OS X Lion.
Suddenly I was getting an error message whilst trying to run this code in Mavericks:
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import pandas as pd
import mpl_toolkits.mplot3d.axes3d as p3
#----->READ AND FORMAT DATA-----------------------------------------------#
.
.
.
.
#-------------------------------------------------------------------------#
# Set up figure & 3D axis for animation
fig = plt.figure(figsize=(10,10))
ax = fig.add_axes([0, 0, 1, 1], projection='3d') # Correct way to make 3D plots
# set up lines and points
lines = sum([ax.plot([], [], [], '-')], [])
pts = sum([ax.plot([], [], [], 'o')], [])
# Setting the axes properties
ax.set_xlim3d([-2000, 2000])
ax.set_xlabel('X')
ax.set_ylim3d([1350, 1400])
ax.set_ylabel('Y')
ax.set_zlim3d([-340, 600])
ax.set_zlabel('Z')
# set point-of-view: specified by (altitude degrees, azimuth degrees)
ax.view_init(40, 0)
ax.set_title('animation')
ax.grid() # add grid
# Initialisation function: plot the background of each frame
def init():
for line, pt in zip(lines, pts):
# Lines
line.set_data([], [])
line.set_3d_properties([])
# Points
pt.set_data([], [])
pt.set_3d_properties([])
return lines + pts
# Animation function. This will be called sequentially with the frame number
def animate(i):
# we'll step two time-steps per frame. This leads to nice results.
i = (2.5 * i)
for line, pt, dat in zip(lines, pts, data):
x, y, z = dat[:i].T
# Lines
line.set_data(x, y)
line.set_3d_properties(z)
# Points
pt.set_data(x[-1:], y[-1:])
pt.set_3d_properties(z[-1:])
ax.view_init(45, i)
fig.canvas.draw()
return lines + pts
#----->ANIMATION-----------------------------------------------------------#
# Creating the Animation object
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=120, interval=30, blit=True)
# Save as mp4. This requires mplayer or ffmpeg to be installed
# anim.save('one_marker_3D.mp4', fps=15, extra_args=['-vcodec', 'libx264'])
plt.show()
This produces the following error message:
Traceback (most recent call last):
File "shoulder_animation_walking_straight_3D.py", line 26, in <module>
fig = plt.figure(figsize=(10,10))
File "/Users/me/anaconda/lib/python2.7/site-packages/matplotlib/pyplot.py", line 423, in figure
**kwargs)
File "/Users/me/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 79, in new_figure_manager
return new_figure_manager_given_figure(num, figure)
File "/Users/me/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 87, in new_figure_manager_given_figure
window = Tk.Tk()
File "/Users/me/anaconda/lib/python2.7/lib-tk/Tkinter.py", line 1745, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
Now as you can hopefully see, I have attempted to use the TkAgg backend instead of the 'Agg' backend, as recommended by the documentation (https://wiki.python.org/moin/TkInter). This seems to cause problems with the new version of OS X because X11 is not supported anymore, and XQuartz has to be installed instead. This I have done too. But it still give me that same error.
I also tried installing py33-tkinter using macports, but that didn't work either, but perhaps I did not do it properly. I simply did
sudo port py33-tkinter
I am still fairly new to python and unix in general.
UPDATE (22/12/13):
I did the following
Python 2.7.5 |Anaconda 1.8.0 (x86_64)| (default, Oct 24 2013, 07:02:20)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import Tkinter
Then ran the Tkinter test
>>> Tkinter._test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/me/anaconda/lib/python2.7/lib-tk/Tkinter.py", line 3770, in _test
root = Tk()
File "/Users/me/anaconda/lib/python2.7/lib-tk/Tkinter.py", line 1745, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
>>>
Might be helpful to someone who knows this better than me.
SOLUTION
This was solved by doing the following, which was caused by a problem with XQuartz;
launchctl load -w /Library/LaunchAgents/org.macosforge.xquartz.startx.plist
I thought that a reinstall of XQuartz would re-enable launchd, but apparently that did not happen. Now it all works.
This was solved by doing the following
matplotlib.use('Agg')
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg')
above this two lines must be in the top codes