[matplotlib animation] 22. 雨(Rain simulation)

matplotlib Animation

はじめに

この記事はmatplotlibのFuncAnimationを使用して雨のシミュレーションアニメーションを作成する方法を解説します。

コード

解説

モジュールのインポート

グラフの設定

図の大きさは、figsize(7,7)の正方形に設定しています。

add_axes(0,0,1,1)では、(left, bottom, width, height)の形式で表示位置と比率を指定できます。左端と下端を0、幅と高さを1に設定することで、図全体にグラフを描画しています。

ax.set_xlim(0, 1)とax.set_xticks([])

を使用して、x軸の表示範囲を0〜1に設定し、x軸の目盛りラベルを非表示にしています。y軸についても同様の設定をしています。

データの生成

このrain_dropsはNumPyの構造化配列で、dtypeによってそれぞれの名前、フォーマット、サイズを指定しています。

np.random.uniformを使用すると、指定した範囲内の乱数を生成できます。np.random.uniform(low, high, size)の形式で使用するため、positionは(50,2)の形状で0〜1の間の値を要素とする配列になり、growthは50個の要素を持つ50〜200の間の値からなる配列になります。

アニメーション表示するグラフの設定

散布図のアニメーションを作成します。まず、positionの0列目をx座標、1列目をy座標としてプロットします。パラメータ「s」で散布図の点の大きさを指定できるため、sizeの値を設定しています。「lw」はlinewidth(線幅)の略で、線の太さを0.5に設定しています。「edgecolor」は点の輪郭の色を指定し、構造化配列のcolorを適用しています。「facecolor」は点の塗りつぶし色を指定するパラメータで、Noneに設定しているため輪郭のみで塗りつぶしなしで描画されます。

アニメーションの設定

アニメーションで変化させる要素の設定

アニメーションで変化させる要素は、current_index = frame_number % n_dropsという計算で求めています。これは、frame_numberをn_drops=50で割った際の余りを取得するものです。

雨の輪郭が薄くなっていく設定

時間の経過に伴って雨の輪郭が薄くなる効果は、colorの3番目の要素である透明度(アルファ値)を変化させることで表現しています。frame_numberが増加するたびにアルファ値から1.0/len(rain_drops)を減算することで、徐々に透明にしていきます。

アルファ値が0以下になった場合には、np.clip(rain_drops[‘color’][:, 3], 0, 1)を使用して0に制限しています。これにより、透明度が適切な範囲(0〜1)に保たれます。

雨の輪郭の拡大の設定

散布図の点のサイズ’size’に’growth’を加算することで、frame_numberが増加するにつれて雨の輪郭が拡大する効果を表現しています。

新しい雨粒の作成

current_indexの位置にある古い雨粒をリセットし、新しい雨粒を作成しています。positionとgrowthは初期設定と同じくランダムに設定され、sizeは5、colorは(0,0,0,1)となっているため完全不透明の黒い雨粒になります。colorは(r,g,b,α)形式で指定するため、例えば(1,0,0,1)と設定すると赤い雨を表現できます。

値の更新

scat.set_XXXでデータの更新を行っています。

アニメーションの表示

animation = FuncAnimation(fig, update, interval=10)では、figに対してupdateを100回実行し、intervalを10 msに設定するため、全体で1秒のアニメーションとなります。

from IPython.display import HTML
HTML(animation.to_html5_video())

とすればjupyter notebook上にアニメーションを表示できます。

まとめ

matplotlib FuncAnimationを使って雨のシミュレーションを実装することができます。雨粒の位置をランダムに生成し、アニメーションフレームごとに位置を更新することで、リアルな雨の降り方を表現できます。パラメータを調整することで、雨の強さや速度なども変更可能です。

参考

NumPyの使い方(12) 乱数、random - Remrinのpython攻略日記
乱数を発生させるライブラリは主に2つ。randomライブラリとNumPyのrandom 2つのライブラリの一番の違いは乱数の発生個数。 乱数の発生個数 randomモジュール :乱数1個 numpyは配列の形をsize=~の形のキーワード引...
numpyで数値が指定範囲にいない場合に、指定範囲のmin/maxに置き換えたい : mwSoft blog

コメント