LoginSignup
14
18

More than 5 years have passed since last update.

Plotly.pyで3次元のムービーを作成

Posted at

概要

前回(PythonコードをCythonで高速化してFortranに近づける)からの続きで、今回は可視化の話。
せっかくなので、前回の計算結果のプラズマの運動をPythonでかっこよく可視化しようと思い、Plotly.pyに行き着いた。
試行錯誤で3次元のアニメーションを作ってみたので紹介。

Plotly.pyを用いたアニメーション

まずは結果の動画から → https://youtu.be/1OFHpvSOsUM

Plotly.pyのofflineモードでは、html形式のファイルでリンクのようなアニメーションが作成できる。
また、Play&Pauseボタンを設置できたり、Pause中に図をグリグリ動かすことが可能。
(実際は動画よりもプラズマは速く動くのだが、動画撮影による処理落ち(?)によってスピードが落ちている)

パラメータ設定

リンクの動画は、前回の数値計算において物理パラメータを以下のように設定した場合の結果。

N(反復回数) Δt m q E B
100,000 0.001 1 -1 (0, 0, 0.005) (0, 0, 1)

電場と磁場は、空間3次元(x, y, z)に対応。qのマイナスは、プラズマが電子(物理の定義では電子の電荷がマイナスなので)ということを意味している。パラメータの絶対量は基本的に適当だが、厳密なシミュレーションではないのでOK。
10万の計算反復の、100ステップごとにプラズマの位置データを保存し、100ステップごとの図をつなげることでリンクのアニメーションが作成されている。

可視化方法

今回の動画の生成用コードを以下に示す。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import plotly.offline as offline
import plotly.graph_objs as go
import numpy as np


if __name__ == '__main__':

    load_data = np.loadtxt('gyro_motion_EparaB.dat', delimiter=',', skiprows=1)

    x = load_data[:, 0]
    y = load_data[:, 1]
    z = load_data[:, 2]

    scatter = go.Scatter3d(x=x, y=y, z=z, mode='lines', line=dict(width=2, color='blue'))

    data = [scatter, scatter]

    layout = dict(xaxis=dict(range=[x.min(), x.max()], autorange=False, zeroline=False),
                  yaxis=dict(range=[y.min(), y.max()], autorange=False, zeroline=False),
                  zaxis=dict(range=[z.min(), z.max()], autorange=False, zeroline=False),
                  title='Gyro Motion of Electron', hovermode='closest',
                  autosize=True,
                  scene=dict(
                            aspectratio=dict(x=0.4, y=0.4, z=1.6),
                            # aspectratio=dict(x=2, y=0.4, z=0.4), # ExB用
                            ),
                  updatemenus=[{'type': 'buttons',
                                'buttons': [{'label': 'Play',
                                             'method': 'animate',
                                             'args':[None, dict(frame=dict(duration=0, redraw=False),
                                                     transition=dict(duration=0),
                                                     fromcurrent=True,
                                                     mode='immediate')]

                                             },
                                            {
                                                'args': [[None], {'frame': {'duration': 0, 'redraw': False},
                                                                  'mode': 'immediate',
                                                                  'transition': {'duration': 0}}],
                                                'label': 'Pause',
                                                'method': 'animate'
                                            }
                                            ]}])

    frames = [dict(data=[dict(x=[x[k]],
                              y=[y[k]],
                              z=[z[k]],
                              mode='markers',
                              marker=dict(color='red', size=4)
                              )
                         ]) for k in range(len(x))]
    figure = dict(data=data, layout=layout, frames=frames)
    offline.plot(figure, filename='EparaB.html')


基本的な利用方法は、公式サイトや他のページにも紹介されているので割愛させていただき、ここでは3次元アニメーションの作成方法の要点を(コードの逆順で)紹介する。

最終的に、offline.plot(figure, filename='EparaB.html')の部分で動画を作成しているため、ここの引数figureを準備する必要がある。そして、figuredata, layout, framesという情報をディクショナリ形式で持つようにする。

  • framesには、プラズマのステップごとの位置データをリスト形式で溜め込んでおく。mode='markers'は、プラズマを点として描くという意味。
  • layoutは、図の設定情報をコードのように入れておく。軸の設定や、動画の再生・停止ボタンを設置することなどが可能。
  • dataには、プラズマの3次元の軌跡を、plotly.graph_objsのScatter3dメソッド用いて保存しておく。その際、コードのようにdata = [scatter, scatter]と2要素にしておく必要がある(data = [scatter]では不十分だった。軌跡として認められないため?)。プラズマの3次元の軌跡の画像を準備しておいて、そこにframesでプラズマを描いていくというイメージだと思われる。

まとめ

簡単にだが、Plotly.pyを用いて3次元の動画を描けるようになった。まだまだPlotly初心者なので、さらにかっこいい動画を作れるようになりたい。コメントや質問等頂ければ幸いです。

補足 ~プラズマ物理~

上記のプラズマの運動は、磁場に沿った方向にかかる電場によって、電子が(電場と逆方向に)加速されつつ、円運動(ジャイロ運動)をするという基本的な物理過程を表している(高校の物理を思い出してください)。

では、電場が磁場と垂直にかかるような場合はどうなるのであろうか。
例えば、電場を以下のように、y成分のみ持つようにした場合について。

N(反復回数) Δt m q E B
100,000 0.001 1 -1 (0, 0.1, 0) (0, 0, 1)

答えはこちら → https://youtu.be/GNTKQ3iMcZg

この運動は、電場と磁場の外積の方向に、プラズマがジャイロ運動しながら動いていくので、プラズマ物理学分野でExB drift (イークロスビードリフト)と呼ばれる。

14
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
18