복붙노트

[PYTHON] Matplotlib 3D scatter 애니메이션

PYTHON

Matplotlib 3D scatter 애니메이션

스타 클러스터에서 위치를 그래프로 나타낼 때 데이터는 x, y, z 위치 및 시간 인덱스가있는 데이터 프레임에 있습니다.

3D 산란 플롯을 생성 할 수 있었고 회전 플롯을 만들려고했습니다. 다소 성공적 이었지만 애니메이션 API를 통해 어려움을 겪었습니다.

내 "update_graph"함수가 새로운 ax.scatter ()를 반환하는 경우 전체 그래프를 다시 작성하지 않으면 이전 그래프가 계속 표시됩니다. 그건 비효율적 인 것 같습니다. 또한 간격을 다소 높게 설정하거나 애니메이션을 건너 뛸 때마다 애니메이션을 건너 뛰기 때문에 성능이 다소 나쁘다. 마지막으로 나는 "blit = False"를 사용하도록 강요 받았는데, 3d scatter 플롯을위한 iterator를 얻을 수 없었기 때문이다. 분명히 "graph.set_data ()"가 작동하지 않고 "graph.set_3d_properties"를 사용할 수 있지만 새로운 z 좌표 만 허용됩니다.

그래서 나는 커수를 모으고있다. (내가 사용한 데이터는 https://www.kaggle.com/mariopasquato/star-cluster-simulations 아래로 스크롤)

또한 저는 100 점 (데이터 = 데이터 [data.id <100])만을 계획하고 있습니다.

내 (작업) 코드는 다음과 같습니다.

def update_graph(num):
     ax = p3.Axes3D(fig)
     ax.set_xlim3d([-5.0, 5.0])
     ax.set_xlabel('X')
     ax.set_ylim3d([-5.0, 5.0])
     ax.set_ylabel('Y')
     ax.set_zlim3d([-5.0, 5.0])
     ax.set_zlabel('Z')
     title='3D Test, Time='+str(num*100)
     ax.set_title(title)
     sample=data0[data0['time']==num*100]
     x=sample.x
     y=sample.y
     z=sample.z
     graph=ax.scatter(x,y,z)
     return(graph)

fig = plt.figure()
ax = p3.Axes3D(fig)

# Setting the axes properties
ax.set_xlim3d([-5.0, 5.0])
ax.set_xlabel('X')
ax.set_ylim3d([-5.0, 5.0])
ax.set_ylabel('Y')
ax.set_zlim3d([-5.0, 5.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
data=data0[data0['time']==0]
x=data.x
y=data.y
z=data.z
graph=ax.scatter(x,y,z)

# Creating the Animation object
line_ani = animation.FuncAnimation(fig, update_graph, 19, 
                               interval=350, blit=False)
plt.show()

해결법

  1. ==============================

    1.3D의 산점도는 mpl_toolkits.mplot3d.art3d.Path3DCollection 객체입니다. 이것은 튜플 (x, y, z)를 호스트하는 _offsets3d 속성을 제공하며 scatter point의 좌표를 업데이트하는 데 사용할 수 있습니다. 따라서 애니메이션 반복마다 전체 플롯을 작성하지 않고 대신 해당 포인트 만 업데이트하는 것이 좋습니다.

    3D의 산점도는 mpl_toolkits.mplot3d.art3d.Path3DCollection 객체입니다. 이것은 튜플 (x, y, z)를 호스트하는 _offsets3d 속성을 제공하며 scatter point의 좌표를 업데이트하는 데 사용할 수 있습니다. 따라서 애니메이션 반복마다 전체 플롯을 작성하지 않고 대신 해당 포인트 만 업데이트하는 것이 좋습니다.

    다음은이를 수행하는 방법에 대한 작업 예제입니다.

    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()
    

    이 솔루션은 블리 팅을 허용하지 않습니다. 그러나 사용 사례에 따라 분산 형 플롯을 전혀 사용하지 않아도됩니다. 다음 예제에서 볼 수 있듯이 정상적인 플롯을 사용하는 것이 똑같이 가능하여 블리 팅이 가능합니다.

    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()
    
  2. ==============================

    2.Jupyter Notebook을 사용하는 경우 % matplotlib 노트북을 사용하는 것을 잊지 마시고 % matplotlib 인라인을 사용하지 마십시오.

    Jupyter Notebook을 사용하는 경우 % matplotlib 노트북을 사용하는 것을 잊지 마시고 % matplotlib 인라인을 사용하지 마십시오.

  3. from https://stackoverflow.com/questions/41602588/matplotlib-3d-scatter-animations by cc-by-sa and MIT license