質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1770閲覧

任意の点と点を結ぶ線をアニメーションで表示させたい。

TomoHashi

総合スコア1

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/29 03:11

編集2021/10/29 03:36

前提・実現したいこと

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部分をループで回さずに描けば残像は残らないのですが、ポイント数を増やしたり、任意の点と点を繋げられるような汎用性を持たせたいため、この方法は適切でないと思っています。

アドバイスいただければ幸いです。よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

おやりになりたいことはこういうことでしょうか?

Python

1def motion_view(dat): 2 l_lst = [[0, 1], [0, 2]] 3 fig_anime = plt.figure(figsize=(8, 8)) 4 ax = fig_anime.add_subplot(111, projection='3d') 5 ax.set_xlim(-1000, 1000) 6 ax.set_ylim(-1000, 1000) 7 ax.set_zlim(0, 3000) 8 9 ims = [] 10 for i in range(0, len(dat[0][:]), 5): 11 for nline in range(len(l_lst)): 12 stp = l_lst[nline][0] 13 enp = l_lst[nline][1] 14 line1, = ax.plot([dat[stp][i][0], dat[enp][i][0]], [dat[stp][i][1], dat[enp][i][1]], 15 [dat[stp][i][2], dat[enp][i][2]], color="b", linewidth=2.0) 16 dx, dy, dz = zip(*[(dat[j][i][0], dat[j][i][1], dat[j][i][2]) for j in range(3)]) 17 pnt = ax.scatter(dx, dy, dz, color="r", linewidth=0.1) 18 image = [pnt] + [line1] 19 ims.append(image) 20 21 ani = anm.ArtistAnimation(fig_anime, ims, interval=100, blit=True) 22 plt.show() 23

投稿2021/10/29 04:54

lehshell

総合スコア1147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomoHashi

2021/10/29 08:37

ありがとうございます!とても見やすくなり,大変参考になりました.
guest

0

とりあえずlin = []の位置をfor i in range(0, len(dat[0][:]), 5):の外側ではなく、内側に移動すると「試したこと」と同じ結果になります。

投稿2021/10/29 04:10

can110

総合スコア38234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomoHashi

2021/10/29 08:38

ありがとうございます!こちらの方法で改善することができました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問