Animate a rotating 3D graph in matplotlib

前端 未结 3 1526
清歌不尽
清歌不尽 2021-01-30 11:17

I have a scatter plot set up and plotted the way I want it, and I want to create an .mp4 video of the figure rotating in space, as if I had used plt.show() and drag

相关标签:
3条回答
  • 2021-01-30 11:57

    Was looking into animating my plots with matplotlib when I stumbled upon this: http://zulko.wordpress.com/2012/09/29/animate-your-3d-plots-with-pythons-matplotlib/

    It provides simple function to animate around a plot and output in a number of formats.

    0 讨论(0)
  • 2021-01-30 12:02

    It's a bit of a hack, but if you are using Jupyter notebook you can use cell magics to run the command line version of ffmpeg directly from the notebook itself. In one cell run your script to generate raw frames

    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%d.png" % ii)
    

    Now, in a new notebook cell, enter the following and then run the cell

    %%bash 
    ffmpeg -r 30 -i movie%d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4
    
    0 讨论(0)
  • 2021-01-30 12:12

    If you want to learn more about matplotlib animations you should really follow this tutorial. It explains in great length how to create animated plots.

    Note: Creating animated plots require ffmpeg or mencoder to be installed.

    Here is a version of his first example changed to work with your scatterplot.

    # 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'])
    
    0 讨论(0)
提交回复
热议问题