2013-08-20 8 views
15

У меня есть график рассеивания и построены так, как я хочу, и я хочу создать видео .mp4 фигуры, вращающейся в пространстве, как если бы я использовал plt.show() и перетащил вокруг.Анимация вращающегося 3D-графика в matplotlib

This answer - это почти то, что я хочу, кроме как сохранить фильм, который мне нужно будет вручную вызвать в FFMpeg с папкой изображений. Вместо сохранения отдельных кадров я предпочел бы использовать встроенную поддержку анимации Matplotlib. Код приводится ниже:

from mpl_toolkits.mplot3d import Axes3D 
ax = Axes3D(fig) 
ax.scatter(xx,yy,zz, marker='o', s=20, c="goldenrod", alpha=0.6) 
for ii in xrange(0,360,1): 
    ax.view_init(elev=10., azim=ii) 
    savefig("movie"%ii+".png") 
+0

Работал отлично, спасибо! – Nate

ответ

20

Если вы хотите узнать больше о matplotlib анимации вы действительно должны следовать this tutorial. Это объясняет в значительной степени, как создавать анимированные сюжеты.

Примечание: Для создания анимированных участков требуется установка ffmpeg или mencoder.

Вот версия его первого примера, измененная для работы с вашей диаграммой рассеяния.

# First import everthing you need 
import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
from mpl_toolkits.mplot3d import Axes3D 

# Create some random data, I took this piece from here: 
# http://matplotlib.org/mpl_examples/mplot3d/scatter3d_demo.py 
def randrange(n, vmin, vmax): 
    return (vmax - vmin) * np.random.rand(n) + vmin 
n = 100 
xx = randrange(n, 23, 32) 
yy = randrange(n, 0, 100) 
zz = randrange(n, -50, -25) 

# Create a figure and a 3D Axes 
fig = plt.figure() 
ax = Axes3D(fig) 

# Create an init function and the animate functions. 
# Both are explained in the tutorial. Since we are changing 
# the the elevation and azimuth and no objects are really 
# changed on the plot we don't have to return anything from 
# the init and animate function. (return value is explained 
# in the tutorial. 
def init(): 
    ax.scatter(xx, yy, zz, marker='o', s=20, c="goldenrod", alpha=0.6) 
    return fig, 

def animate(i): 
    ax.view_init(elev=10., azim=i) 
    return fig, 

# Animate 
anim = animation.FuncAnimation(fig, animate, init_func=init, 
           frames=360, interval=20, blit=True) 
# Save 
anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264']) 
+1

Извините, я надеюсь, вы на самом деле не оскорблены. Не уверен, что я согласен с вами в отношении отсутствия возвращаемых ценностей. Я думаю, что 'blit' нуждается в их правильной работе, но этот раздел библиотеки по-прежнему остается черным ящиком для меня. (Я проголосовал за ответ). – tacaswell

+1

Конечно, нет! : D Я действительно очень уважаю ваши комментарии, так как они исходят от опытного разработчика «matplotlib»! И я стараюсь учиться у них и вести себя в соответствии с вашими предложениями (вчера о вопросительном знаке). Поэтому, пожалуйста, ** DO ** исправьте меня каждый раз, когда вы думаете, что я сделал что-то неправильно :). Это как в интересах сообщества SO, так и моего собственного процесса обучения. Просто случилось, что у нас было небольшое методологическое несогласие по предыдущему вопросу, поэтому я добавил это как шутку, так как знал, что вы прочитаете все вопросы «matplotlib» :) –

+0

О возвращаемом значении. В блоге Джейк сказал: «Важно, чтобы эта функция возвращала объект линии, потому что это говорит аниматору, который объекты на графике обновляется после каждого кадра». Но поскольку ни один из объектов на сюжете не изменился, я предположил, что ничего не нужно возвращать. Я отредактирую сообщение, если это неверное предположение. –