Matplotlib におけるアニメーション付き 3D ランダムウォーク

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、Python の Matplotlib ライブラリを使ってアニメーション付きの 3D ランダムウォークプロットを作成する方法を学びます。3D プロットを作成し、3D 空間でランダムに移動する 40 個の粒子でランダムウォークをシミュレートします。

VM のヒント

VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。

時々、Jupyter Notebook が読み込み終わるまで数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。

学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。

必要なライブラリをインポートする

まずは必要なライブラリをインポートします。乱数を生成するためにnumpyを、プロットを作成するためにmatplotlibを使用します。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation

ランダムウォーク関数を定義する

与えられたステップ数と最大ステップサイズでランダムウォークを生成する関数を定義します。この関数は 2 つの入力を受け取ります。num_stepsはランダムウォークの合計ステップ数で、max_stepは各ステップの最大サイズです。ステップの乱数を生成するためにnumpy.randomを、最終位置を取得するためにステップの累積和を計算するためにnumpy.cumsumを使用します。

def random_walk(num_steps, max_step=0.05):
    """Return a 3D random walk as (num_steps, 3) array."""
    start_pos = np.random.random(3)
    steps = np.random.uniform(-max_step, max_step, size=(num_steps, 3))
    walk = start_pos + np.cumsum(steps, axis=0)
    return walk

更新関数を定義する

アニメーションの各フレームに対してプロットを更新する関数を定義します。この関数は 3 つの入力を受け取ります。numは現在のフレーム番号、walksはすべてのランダムウォークのリスト、linesはプロット内のすべての線のリストです。各線とウォークに対して、現在のフレーム番号までの線の x、y、z 座標のデータを更新します。x-y 座標と z 座標をそれぞれ更新するためにline.set_data()line.set_3d_properties()を使用します。

def update_lines(num, walks, lines):
    for line, walk in zip(lines, walks):
        ## NOTE: there is no.set_data() for 3 dim data...
        line.set_data(walk[:num, :2].T)
        line.set_3d_properties(walk[:num, 2])
    return lines

ランダムウォークを生成する

先ほど定義したrandom_walk()関数を使って、それぞれ 30 ステップの 40 個のランダムウォークを生成します。すべてのランダムウォークをwalksという名前のリストに格納します。

## Data: 40 random walks as (num_steps, 3) arrays
num_steps = 30
walks = [random_walk(num_steps) for index in range(40)]

3D プロットを作成する

matplotlibを使って 3D プロットを作成します。各ランダムウォークに対して空の線をプロットに追加します。x 軸、y 軸、z 軸の範囲を 0 から 1 の間に設定します。

## Attaching 3D axis to the figure
fig = plt.figure()
ax = fig.add_subplot(projection="3d")

## Create lines initially without data
lines = [ax.plot([], [], [])[0] for _ in walks]

## Setting the axes properties
ax.set(xlim3d=(0, 1), xlabel='X')
ax.set(ylim3d=(0, 1), ylabel='Y')
ax.set(zlim3d=(0, 1), zlabel='Z')

アニメーションを作成する

matplotlib.animationFuncAnimationクラスを使ってアニメーションを作成します。FuncAnimationコンストラクタに、グラフオブジェクト、更新関数、フレームの総数(ランダムウォークのステップ数に等しい)、すべてのランダムウォークのリスト、およびすべての線のリストを引数として渡します。

## Creating the Animation object
ani = animation.FuncAnimation(
    fig, update_lines, num_steps, fargs=(walks, lines), interval=100)

アニメーションを表示する

最後に、plt.show()を使ってアニメーションを表示します。

plt.show()

まとめ

Python の Matplotlib ライブラリを使って、アニメーション付きの 3D ランダムウォークプロットを作成する方法を学びました。ランダムウォークを生成し、アニメーションの各フレームに対してプロットを更新しました。この技術は、3 次元空間における粒子の動き、拡散、その他の確率過程を視覚化するために使用できます。