Matplotlib 3D scatter animations

后端 未结 2 2091
伪装坚强ぢ
伪装坚强ぢ 2020-11-29 10:12

I am graphing out positions in a star cluster, my data is in a dataframe with x,y,z positions as well as a time index.

I am able to produce a 3d scatter plot and was

相关标签:
2条回答
  • 2020-11-29 10:53

    The scatter plot in 3D is a mpl_toolkits.mplot3d.art3d.Path3DCollection object. This provides an attribute _offsets3d which hosts a tuple (x,y,z) and can be used to update the scatter points' coordinates. Therefore it may be beneficial not to create the whole plot on every iteration of the animation, but instead only update its points.

    The following is a working example on how to do this.

    import numpy as np
    from matplotlib import pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.animation
    import pandas as pd
    
    
    a = np.random.rand(2000, 3)*10
    t = np.array([np.ones(100)*i for i in range(20)]).flatten()
    df = pd.DataFrame({"time": t ,"x" : a[:,0], "y" : a[:,1], "z" : a[:,2]})
    
    def update_graph(num):
        data=df[df['time']==num]
        graph._offsets3d = (data.x, data.y, data.z)
        title.set_text('3D Test, time={}'.format(num))
    
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    title = ax.set_title('3D Test')
    
    data=df[df['time']==0]
    graph = ax.scatter(data.x, data.y, data.z)
    
    ani = matplotlib.animation.FuncAnimation(fig, update_graph, 19, 
                                   interval=40, blit=False)
    
    plt.show()
    

    This solution does not allow for blitting. However, depending on the usage case, it may not be necessary to use a scatter plot at all; using a normal plot might be equally possible, which allows for blitting - as seen in the following example.

    import numpy as np
    from matplotlib import pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.animation
    import pandas as pd
    
    
    a = np.random.rand(2000, 3)*10
    t = np.array([np.ones(100)*i for i in range(20)]).flatten()
    df = pd.DataFrame({"time": t ,"x" : a[:,0], "y" : a[:,1], "z" : a[:,2]})
    
    def update_graph(num):
        data=df[df['time']==num]
        graph.set_data (data.x, data.y)
        graph.set_3d_properties(data.z)
        title.set_text('3D Test, time={}'.format(num))
        return title, graph, 
    
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    title = ax.set_title('3D Test')
    
    data=df[df['time']==0]
    graph, = ax.plot(data.x, data.y, data.z, linestyle="", marker="o")
    
    ani = matplotlib.animation.FuncAnimation(fig, update_graph, 19, 
                                   interval=40, blit=True)
    
    plt.show()
    
    0 讨论(0)
  • 2020-11-29 11:12

    If using Jupyter Notebook remember to use %matplotlib notebook don't use %matplotlib inline.

    0 讨论(0)
提交回复
热议问题