2017-01-11 12 views
1

私はスタークラスタ内の位置をグラフ表示しています。私のデータは時間インデックスとともにx、y、z位置のデータフレームにあります。Matplotlib 3Dスキャッタアニメーション

3次元散布図を作成でき、回転プロットを作成しようとしていましたが、やや成功しましたが、アニメーションAPIを苦労しました。

"update_graph"関数が単に新しいax.scatter()を返す場合、グラフ全体を再構築しない限り、古いものはプロットされたままです。それは非効率的だ。また、インターバルをかなり高く設定するか、アニメーションを1フレームおきにスキップする必要があるため、パフォーマンスが悪いと言います。最後に、私は3D散布図のイテレータを得ることができないので、 "blit = False"を使用するように強制されます。どうやら、 "graph.set_data()"は機能せず、 "graph.set_3d_properties"を使うことができますが、これは新しいz座標のみを許可します。

は、だから私は一緒に石畳いるcluuge--私は100ポイント(データ=データ[data.id < 100])

をプロットしています。また

(私が使用したデータは下へ https://www.kaggle.com/mariopasquato/star-cluster-simulations スクロールです)次のように

マイ(作業)コードである:

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

答えて

6

3Dで散布図mpl_toolkits.mplot3d.art3d.Path3DCollectionオブジェクトです。これにより、タイル(x,y,z)をホストする属性_offsets3dが提供され、スキャッタポイントの座標を更新するために使用できます。したがって、アニメーションの反復ごとにプロット全体を作成するのではなく、その点を更新するだけで有益な場合があります。

以下は、これを行う方法の実例です。

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

このソリューションでは、ブリッティングができません。ただし、使用状況によっては、散布図をまったく使用する必要はありません。 通常のplotを使用することも同様に可能であり、以下の例のように、ブリッティングが可能です。 Jupyterノートブックを使用している場合

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

それは私が必要としていたことです - 私はすべてを再描画することは正しいとは知っていませんでしたが、私は働くことができる唯一のものでした。 "魚を釣る人を教える"ということに続き、私はmatplotの文書を精査し、_offsets3dの言及は見つかりませんでした。将来の参照のためにgithubとコード自体を含める必要がありますか? – RDS

+1

これは良い点です。上の解は '_offsets3d'を使います。これはプライベートメソッドです(前の' _'で示されています)。それらは文書化されていません。 [ソースコード](https://github.com/matplotlib/matplotlib)を調べるか、オンラインで使用例を見つけることで見つけられます。ドキュメンテーションが解決策を提供しない場合は、ソースを参照すると役立つことがよくあります。忘れないで、特定の質問をしたように、 '_offsets3d'のような隠された宝石を見つけるのにも役立ちます。 ;-)しかし、プライベート関数もバージョン間で変更される可能性があるので、その使用は一般的に避けるべきです。 – ImportanceOfBeingErnest

0

%matplotlib notebook%matplotlib inlineを使用していない使用することを忘れないでください。

関連する問題