やりたいこと
x座標,y座標の情報を持つ2つのサイズの異なるオブジェクトが存在し,それらのx座標,y座標の状態遷移の様子をアニメーションとして作成し最終的にgifでの保存を果たしたいと考えています.
環境:
python3.6
ubuntu18.04
wsl1
用いるのライブラリはmatplotlibのArtistAnimationでお願いします.
イメージのためにコードを示します.
python3
1import matplotlib.pyplot as plt 2from matplotlib.animation import ArtistAnimation # アニメーション作成のためのメソッドをインポート 3import numpy as np 4 5#seedを固定して一個目のオブジェクトのx座標,y座標を生成 6np.random.seed(seed=0) 7n0_x = np.random.rand(100) 8n0_y = np.random.rand(100) 9#seedを固定して二個目のオブジェクトのx座標,y座標を生成 10np.random.seed(seed=1) 11n1_x = np.random.rand(60) 12n1_y = np.random.rand(60)
このように,それぞれのオブジェクトにはサイズの異なる座標情報を持つようにします.
これらをアニメーションで描画します.
その前にサイズが同じ時の描画方法
以下にサイズが同じ時の描画の成功例のコードを示します.
python3
1#ライブラリのimportだけ割愛 2#seedを固定して一個目のオブジェクトのx座標,y座標を生成 3np.random.seed(seed=0) 4n0_x = np.random.rand(100) 5n0_y = np.random.rand(100) 6#seedを固定して二個目のオブジェクトのx座標,y座標を生成 7np.random.seed(seed=1) 8n1_x = np.random.rand(100) #オブジェクト1と同じサイズにする 9n1_y = np.random.rand(100) 10fig = plt.figure() 11ax = fig.add_subplot(1,1,1) 12images = [] 13x0_kiseki = [] #軌道の軌跡を格納 14y0_kiseki = [] 15x1_kiseki = [] 16y1_kiseki = [] 17frame = len(n0_x) #サイズ 18for i in range(frame): 19 x0_kiseki.append(n0_x[i]) 20 y0_kiseki.append(n0_y[i]) 21 im0 = ax.plot([n0_x[i]],[n0_y[i]], 'o', x0_kiseki,y0_kiseki, '--', color='red' ,markersize=10, linewidth = 2, aa=True) 22 23 x1_kiseki.append(n1_x[i]) 24 y1_kiseki.append(n1_y[i]) 25 im1 = ax.plot([n1_x[i]],[n1_y[i]], 'o', x1_kiseki,y1_kiseki, '--', color='blue' ,markersize=10, linewidth = 2, aa=True) 26 images.append(im0 + im1) 27 28anim = ArtistAnimation(fig, images, interval=500 , repeat=False) 29anim.save('test1.gif', writer='imagemagick') #一つの変数animで管理しているからgifでの保存ができる 30plt.show()
以下のgifはファイルの大きさの関係上小さくしたものですがサイズが同じだとこのようになります.
このコードにライブラリをimportすると動きます.また,以下のようにしてgifを作成することが出来る
anim.save('test1.gif', writer='imagemagick') #一つの変数animで管理しているからgifでの保存ができる
では,オブジェクトのサイズが異なるときはどうしたのか....
オブジェクトのサイズの異なるときの描画方法
いろいろあくせくしながら結局できたのは,オブジェクトごとにanim変数を用意し,それぞれを連続でplt.show()すれば同じ軌道が得られるという結論になりました.
以下にコードを示します.
python3
1np.random.seed(seed=0) 2n0_x = np.random.rand(100) 3n0_y = np.random.rand(100) 4 5np.random.seed(seed=1) 6n1_x = np.random.rand(60) #オブジェクトサイズが異なるように 7n1_y = np.random.rand(60) 8 9fig = plt.figure() 10ax1 = fig.add_subplot(1,1,1) 11images = [] 12images1 = [] 13im0 = [] 14im1 = [] 15x0_kiseki = [] 16y0_kiseki = [] 17x1_kiseki = [] 18y1_kiseki = [] 19 20for i in range(len(n0_x)): 21 x0_kiseki.append(n0_x[i]) 22 y0_kiseki.append(n0_y[i]) 23 im0.append(ax1.plot([n0_x[i]],[n0_y[i]], 'o', x0_kiseki,y0_kiseki, '--', color='red' ,markersize=10, linewidth = 2, aa=True)) 24 25for i in range(len(n1_x)): 26 x1_kiseki.append(n1_x[i]) 27 y1_kiseki.append(n1_y[i]) 28 im1.append(ax1.plot([n1_x[i]],[n1_y[i]], 'o', x1_kiseki,y1_kiseki, '--', color='blue' ,markersize=10, linewidth = 2, aa=True)) 29 30for i in range(len(im0)): 31 images.append(im0[i]) 32for i in range(len(im1)): 33 images1.append(im1[i]) 34 35 36anim = ArtistAnimation(fig, images, interval=500 , repeat=False) 37anim1 = ArtistAnimation(fig, images1, interval=500, repeat=False) 38plt.show()
このようにすると同じ画面でオブジェクトのサイズの少ない方が途中でとまり,サイズの大きい方が動き続けるという目的を満たすことが出来るプログラムにはなっています.
[本題]知りたいこと
一応,上記のコードをshow()すれば目的のアニメーションはできた.
しかし,今回知りたいのはanimとanim1を同時に一つの変数で管理できないかということです.
これができないために,gifでの保存ができない.
他にも,このfigureに凡例を付けたいときや,時間遷移の様子をtextとして見たい時などにどうすればいいのかわからない.
一応,anim_all = anim + anim1とかやってみたが当然うまくいっていない.
上記の質問に対する回答をどうかよろしくお願いします.
参考記事:
https://qiita.com/Mshimon/items/0e7feddc12e7668834b0
https://matplotlib.org/stable/api/animation_api.html
あなたの回答
tips
プレビュー