はじめに
この記事は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を使って雨のシミュレーションを実装することができます。雨粒の位置をランダムに生成し、アニメーションフレームごとに位置を更新することで、リアルな雨の降り方を表現できます。パラメータを調整することで、雨の強さや速度なども変更可能です。
参考

コメント