前提・実現したいこと
Pythonの初学者です。
ArtistAnimationを使ってプロットとその結線が動くアニメーションを作っています。
最終的には、任意の座標データを選び、特定の部分にのみ結線を表示させたアニメーションを作製しようとしています。
発生している問題・エラーメッセージ
読み込んでいるexcelファイルの中身は画像のとおりです。 3次元の座標値で、3点あり、それぞれx,y,z座標のデータが3点分並んでいます。 行方向が時系列データ、列方向が座標データです。 scatterとplotを用いてこれら3点を表示させるとともに、任意の点を選び、結線を表示させています。 scatterの部分は問題なく表示されるのですが、点と点を任意に繋ぐ結線の描写をplotで実行する際、前フレームの残像が残ってしまいます。 ループ処理をしている部分で余分にデータを描写してしまっているような気はするのですが、解決方法が分からず困っております。
該当のソースコード
Python
1import pandas as pd 2import matplotlib.pyplot as plt 3import matplotlib.animation as anm 4 5def data_read(file_name): 6 df = pd.read_excel(file_name) 7 data = df.to_numpy() 8 pnt = [r[0:] for r in data] 9 point_num = int(len(pnt[0][0:]) / 3) 10 11 pnt_data = [] 12 for i in range(point_num): 13 pnt_data.append([r[3 * i:3 * i + 3][:] for r in pnt]) # pnt_data[ポイント番号][フレーム番号][xyz座標] 14 return pnt_data 15 16 17def motion_view(dat): 18 l_lst = [[0, 1], [0, 2]] 19 fig_anime = plt.figure(figsize=(8, 8)) 20 ax = fig_anime.add_subplot(111, projection='3d') 21 ax.set_xlim(-1000, 1000) 22 ax.set_ylim(-1000, 1000) 23 ax.set_zlim(0, 3000) 24 25 ims = [] 26 lin = [] 27 for i in range(0, len(dat[0][:]), 5): 28 29 for nline in range(len(l_lst)): 30 stp = l_lst[nline][0] 31 enp = l_lst[nline][1] 32 line1, = ax.plot([dat[stp][i][0], dat[enp][i][0]], [dat[stp][i][1], dat[enp][i][1]], 33 [dat[stp][i][2], dat[enp][i][2]], color="b", linewidth=2.0) 34 35 lin.append(line1) 36 37 dx = [] 38 dy = [] 39 dz = [] 40 for j in range(3): 41 tmp_x = dat[j][i][0] 42 tmp_y = dat[j][i][1] 43 tmp_z = dat[j][i][2] 44 dx.append(tmp_x) 45 dy.append(tmp_y) 46 dz.append(tmp_z) 47 48 pnt = ax.scatter(dx, dy, dz, color="r", linewidth=0.1) 49 50 image = [pnt] + lin 51 ims.append(image) 52 53 ani = anm.ArtistAnimation(fig_anime, ims, interval=1, blit=True) 54 plt.show() 55 56 57file_name = 'sample01.xlsx' 58pnt_data = data_read(file_name) 59 60motion_view(pnt_data)
試したこと
Python
1def motion_view(l_lst, dat): 2 fig_anime = plt.figure(figsize=(8, 8)) 3 ax = fig_anime.add_subplot(111, projection='3d') 4 ax.set_xlim(-1000, 1000) 5 ax.set_ylim(-1000, 1000) 6 ax.set_zlim(0, 3000) 7 8 ims = [] 9 for i in range(0, len(dat[0][:]), 5): 10 line1 = ax.plot([dat[0][i][0], dat[1][i][0]], [dat[0][i][1], dat[1][i][1]], 11 [dat[0][i][2], dat[1][i][2]], color="b", linewidth=2.0) 12 line2 = ax.plot([dat[0][i][0], dat[2][i][0]], [dat[0][i][1], dat[2][i][1]], 13 [dat[0][i][2], dat[2][i][2]], color="b", linewidth=2.0) 14 15 dx = [] 16 dy = [] 17 dz = [] 18 for j in range(3): 19 tmp_x = dat[j][i][0] 20 tmp_y = dat[j][i][1] 21 tmp_z = dat[j][i][2] 22 dx.append(tmp_x) 23 dy.append(tmp_y) 24 dz.append(tmp_z) 25 26 pnt = ax.scatter(dx, dy, dz, color="r", linewidth=0.1) 27 28 image = [pnt] + line1 + line2 29 ims.append(image) 30 31 ani = anm.ArtistAnimation(fig_anime, ims, interval=1, blit=True) 32 plt.show()
上記のように、plot部分をループで回さずに描けば残像は残らないのですが、ポイント数を増やしたり、任意の点と点を繋げられるような汎用性を持たせたいため、この方法は適切でないと思っています。
アドバイスいただければ幸いです。よろしくお願い致します。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/29 08:37