ヒントとコツ

ここでは,Mayavi2を使用する際に役立つヒントをいくつか紹介します.

JupyterノートブックでのMayaviの利用

JupyterノートブックにMayaviの可視化を埋め込むには3つの方法があります.最善の方法は,(これがデフォルトです.)バックエンドを使用することである.このバックエンドはMayavi 4.7 .0で初めて導入されました.このバックエンドを使用するには, ipywidgetsipyevents packagesをインストールする必要があります.通常のMayavi UIウィンドウとほとんど同じように動作し,Mayavi/VTKの表示をサポートし,完全にインタラクティブです.このバックエンドはVTKのオフスクリーンサポートに依存しており,VTKの設定方法によってはウィンドウシステムが必要になることがあります.このオプションは,基本的に可視化のサーバーサイドレンダリングを実行します.

もう一つの非常に強力なバックエンドは 'itk' バックエンドで,クライアントサイドのアプローチ (WebGL を使用してブラウザ上でレンダリングします) を使用し,VTK のオフスクリーンサポートには依存しません. このためには itkwidgets パッケージがインストールされている必要があります.ウェブベースのノートブックが主な用途であれば,おそらくこれが最も便利なバックエンドでしょう.この機能はMayavi-4.8.0で初めて導入されました.

ノートブックインターフェースを示す簡単なサンプルノートブックは,こちらで入手できます: https://github.com/enthought/mayavi/blob/master/examples/mayavi/mayavi_jupyter.ipynb

他にも2つのバックエンドがあり,最も単純なものは,ノートブックに埋め込むことができるイメージを生成する 'png' バックエンドです.これらは静的でインタラクティブではなく,これもサーバーサイドレンダリングを使用しています.

また,ノートブック上に X3D 要素を表示する 'x3d' バックエンドも用意されています.X3D出力では完全にインタラクティブな3次元シーンが生成されますが,VTKのインタラクティブウィジェットはサポートされません.透明度やその他の高度な視覚化もサポートしていません.X3Dシーンの操作方法については, http://www.x3dom.org/documentation/interaction/ を参照してください.

X3Dバックエンドのために,Mayaviはいくつかのjavascriptファイルを同梱しており,以下のようにインストールすることができます:

$ jupyter nbextension install --py mayavi --user

これにより,x3dom JavascriptおよびCSSファイルがローカルにインストールされます.上記のコマンドを実行した後は,拡張機能などを "enable" にする必要はありません.詳細な手順とオプションについては, Installation of Jupyter Extensions を参照してください.これにより,ネットワーク接続なしでX3Dファイルを表示できます.

ノートブックでMayaviの視覚化を表示するには,まず次の操作を行います.

from mayavi import mlab
mlab.init_notebook()

当然のことながら,次のようにします.

s = mlab.test_plot3d()
s

init_notebook メソッドを呼び出すと,MayaviオブジェクトがJupyterノートブック上でレンダリングできるように設定されます.

注釈

何らかの理由で ipyitkpngx3d の間のバックエンドを変更したい場合, init_notebook を複数回呼び出すことができます.

init_notebook にはオプションの引数がいくつかあります.

  • 1つはバックエンドで,デフォルトは 'ipy' で, 'itk''x3d' または 'png' に設定することもできます.

  • 図形のピクセル幅と高さを設定して,(整数として)(例 mlab.init_notebook('x3d', 800, 800))を作成できます.これは x3d バックエンドにのみ適用されます. ipy バックエンドでは, size キーワード引数を使用して新しい figure を作成するときに設定できます.

  • 最後のキーワード引数 local のデフォルトは True です. local=True がJavascriptファイルを使用している場合は,Mayaviとともに配布されます.それ以外の場合は,x3domファイルをオンラインで使用するためにインターネット接続が必要になります.何らかの理由でjupyter nbextensionのインストールが動作しない場合,インターネット接続で local=False を使うことは,WebGLをサポートしている最近のブラウザで動作するはずです.

X3Dデータはノートブックに埋め込まれており,共有することができますが,シーンに多数のポリゴンがある場合は,これらのファイルのサイズが大きくなることがあります.PNGバックエンドでは,PNGも埋め込まれており,これらはより小さなファイルです.PNGバックエンドは,ご使用のプラットフォームで正しく動作するオフスクリーンレンダリングに依存します.

オフスクリーンレンダリング

レンダリングウィンドウを使用しない

多くの場合,Mayaviスクリプトを記述してバッチ全体のイメージをレンダーし,アニメーションなどを作成すると,イメージを保存するたびに,Mayaviがウィンドウを "raises" してアクティブウィンドウにし,作業を中断させることがわかります.これは,VTKが内部的にウィンドウをつかんで画像を作成するために必要です.ウィンドウを非表示にすると,空白または不正なイメージが生成されます.

すでにPythonスクリプトを持っている場合は, script.py と言って,実行するビジュアル化を設定します.

$ mayavi2 -x script.py

そうすれば,このスクリプトを画面外で実行することが非常に簡単になります.次のように実行します.

$ mayavi2 -x script.py -o

スクリプトは,オフスクリーンのスタンドアロンウィンドウで実行されます.Linuxでは,VTK-5.2以上で最適に動作します. mayavi2 アプリケーションがサポートするコマンドライン引数の詳細については, コマンドライン引数 セクションを参照してください.

mlab を使用する場合は,次のようにします.

mlab.options.offscreen = True

をクリックすると,レンダリングにオフスクリーンウィンドウが使用されます.

オフスクリーンレンダリングの別のオプションは,シーンをクリックして "Off screen rendering" オプションをオンに設定することです.または,スクリプトから

mayavi.engine.current_scene.scene.off_screen_rendering = True

これにより,ウィンドウの上昇が停止します.しかし,これでは十分ではないかもしれません.各プラットホームの状況は下記参照.

プラットフォームの概要

  • Windows: win32を使用している場合,初期状態ではオフスクリーンレンダリングが適切に機能します.必要な作業は,上記の内容のみです.

  • Linux と Mac: これを正しく動作させるにはいくつかのオプションがあり,考慮すべき重要な問題がいくつかあります.

    VTK-5.2を使用している場合は,オフスクリーンレンダリングオプションを使用すれば,ウィンドウを隠すことなく画像を生成できます.ただし,これを正しく動作させるには,VTK-5.2が必要です.また,これが常に動作するとは限らない場合もあります.これを試してみて,空白のウィンドウが表示された場合は,問題が発生します.次に例を示します.

    from mayavi import mlab
    mlab.options.offscreen = True
    mlab.test_contour3d()
    mlab.savefig('example.png')
    

    クリーンなイメージ(デスクトップを切り替えたり,作成されたウィンドウをカバーしたりしても)が生成される場合は,金色になります.そうでない場合は,仮想フレームバッファを使用するか,Mesa+OSMesaを使ってVTKを構築し,純粋なソフトウェアレンダリング手法を提供することを検討してください.

仮想フレームバッファを使用したレンダリング

VTKでは,すべてのレンダリングにopenGLが使用されます.従来のUnix(Linuxを含む)では,GLコンテキストを開くためにXserverを実行する必要があります(特にハードウェアアクセラレーションが必要な場合).これは,ヘッドレスサーバでレンダリングする場合に問題になる可能性があります.前の段落で述べたように,デスクトップでは,既定のサーバーを使用すると進行中の作業の妨げになるため,問題になることがあります.

回避策としては,次のようにX11用の仮想フレームバッファXサーバを使用します.

  • Xvfb パッケージがインストールされていることを確認します.例えばDebianとその派生版では,これは xvfb パッケージと呼ばれます.

  • 次のように仮想フレームバッファXサーバを作成します.

    Xvfb :1 -screen 0 1280x1024x24 -auth localhost
    

    これにより,ディスプレイ ":1" が作成され,1280x1024,24bppの画面が作成されます(24bppは重要です.).その他のオプションについては, Xvfb のマニュアルページを参照してください.

  • 次のように表示を(bashでの)1のようにエクスポートします

    $ export DISPLAY=:1
    
  • Mayaviスクリプトを実行します.このXサーバ上で中断なく実行され,保存されたイメージが生成されます.

これはおそらく,あなたの好みに合わせて微調整する必要があります.

Pythonでこれを行いたい場合は, pyvirtualdisplay が使えます.

from pyvirtualdisplay import Display
import os
display = Display(visible=0, size=(1280, 1024))
display.start()

多くのLinuxシステム(UbuntuおよびDebianを含む)には,ヘッドレスで動作するためのヘルパースクリプト xvfb-run が付属しています.次のコマンドは,PythonスクリプトをMayavi2ビジュアライゼーションでヘッドレスで実行できます.

xvfb-run --server-args="-screen 0 1024x768x24" python my_script.py

mlab.show を呼び出したり,スクリプトの中でメインループを起動したりしないように注意してください.そうしないと,スクリプトは無限に実行され,隠れたウィンドウでの対話を待ちます.

注釈

envisage UIまたはtrait UIさえも持たないMayavi(すなわち純粋なTVTKウィンドウで)を使用し,Pythonスクリプトを使用して画面外のレンダリングを実行する場合, オフスクリーンの例 に興味を持つかもしれません.この単純な例では,EnvisageまたはMayavi envisageアプリケーションを使用せずにMayaviを使用し,画面外のレンダリングを実行する方法を示します.

Maya2アプリケーション以外でmlabを使用している場合は,次のように設定します.

mlab.options.offscreen = True

MesaでVTKを使用して純粋なソフトウェアレンダリングを行う

場合によっては,XサーバがまったくないマシンでMayavi/VTKを完全にヘッドレスで実行し,純粋なオフスクリーンレンダリング( Sage ノートブックインターフェイスでの使用例)に関心があることもあります.このような場合,MesaのOSMesaライブラリを使ってオフスクリーンでレンダリングすることができる.欠点は,この場合はハードウェアアクセラレーションを使用できないことです.ここでは,これを行うためのVTKのビルド方法を簡単に説明します.

  • 最近のバージョンのmesaを作成します. 7.0.4 (現時点で)は7.2と同じように動作するはずです. MesaLib-7.0.4.tar.bz2をダウンロードしていると仮定します.

  • Untarを実行し,作成した新しいディレクトリに移動します.以降,このディレクトリを $MESA と呼びます.

  • make configs/linux-x86 を実行し,設定に従ってファイルを変更します. make を実行してオプションのリストを表示します.注: 7.2には,実行可能な ./configure スクリプトがあります.

  • VTK-5.2以降を入手してください(CVSも動作します).

  • ccmake path/to/VTK を実行します.

    • 次に,詳細オプション 't' を選択します.

    • VTK_OPENGL_HAS_OSMESA ON を設定します.

    • 設定: 'c' を押します.

    • OSMESA_INCLUDE_DIR$MESA/include dir に設定します.

    • OSMESA_LIBRARY$MESA/lib/libOSMesa.so に設定します.

    • 同様に OPENGL_INCLUDE_DIROPENGL_gl_LIBRARY=$MESA/lib/libGL.soOPENGL_glu_LIBRARYOPENGL_xmesa_INCLUDE_DIR を設定します.

    • 常にオフスクリーンにする場合は VTK_USE_OFFSCREENON に設定してください.この場合,レンダーウィンドウのオフスクリーンレンダリングのivarのデフォルト値がTrueに設定されるため,実際にマッピングされたVTKウィンドウが生成されることはありません.

    • VTK_USE_GL2PS, USE_RPATH などのその他の設定.

    • 再度( 'c' を押す)を設定し, 'g' を生成してください.

    • ccmake を使いたくなくて,コマンドラインからこれを行いたいなら,以下のようにしても良いことに注意してください(例えば)

      cmake \
      -DVTK_OPENGL_HAS_OSMESA=ON \
      -DVTK_USE_OFFSCREEN=ON \
      -DCMAKE_INSTALL_PREFIX=/path/to/vtk-offscreen \
      -DVTK_WRAP_PYTHON=ON \
      -DPYTHON_EXECUTABLE=/usr/bin/python2.5 \
      -DPYTHON_LIBRARY=/usr/lib/libpython2.5.so \
      -DBUILD_SHARED_LIBS=ON \
      -DVTK_USE_GL2PS=ON \
      -DOSMESA_INCLUDE_DIR=/path/to/Mesa-7.2/include/ \
      -DOSMESA_LIBRARY=/home/path/to/Mesa-7.2/lib64/libOSMesa.so \
      -DOPENGL_INCLUDE_DIR=/path/to/Mesa-7.2/include \
      -DOPENGL_gl_LIBRARY=/path/to/Mesa-7.2/lib64/libGL.so \
      -DOPENGL_glu_LIBRARY=/path/to/Mesa-7.2/lib64/libGLU.so \
      path/to/VTK/
      
  • make を実行し,VTKがビルドされるまで待ちます.ビルドが ``$VTK_BUILD``にあるとします.

  • ここでVTKをインストールするか, PYTHONPATHLD_LIBRARY_PATH を適切に設定します.また, LD_LIBRARY_PATH$MESA/lib (システムにmesaライブラリがインストールされていない場合)を指していることを確認します.これにより,VTKが正しいGLライブラリにリンクされていることが保証されます.次に例を示します.

    $ export PYTHONPATH=$VTK_BUILD/bin:$VTK_BUILD/Wrapping/Python``
    $ export LD_LIBRARY_PATH=$VTK_BUILD/bin:$MESA/lib
    

    これで準備は完了です.

これが完了すると,mlabの例を画面外で実行できるようになります.これはX表示なしでも動作します.

このようなVTKをビルドして実行すれば,簡単にmayavi2をビルドしてインストールすることができます.たとえばSageノートで使用するには, ETS_TOOLKIT='null'mlab.options.offscreen = True を設定します.これで,すべてが画面外で機能するようになります.

VTK_USE_OFFSCREENON に設定した場合,デフォルトではオフスクリーンコンテキストのみを取得することに注意してください.UIが必要な場合は,マッピングされたウィンドウを強制的に表示するために,レンダウィンドウの``off_screen_rendering`` のivarを明示的に False に設定します.このため,完全なUIをポップアップ表示する必要がある場合は, VTK_USE_OFFSCREEN=ON を設定しない方がよい場合があります.

カスタマイズによるMayaviの拡張

開発者は,新しいソース,フィルタ,またはモジュールを追加してMayaviをカスタマイズできます.これらは, Customizing Mayavi2 で記述されているように,それぞれのフィルタを書いて user_mayavi.pysite_mayavi.py 経由で公開することで実現できます.これを行うためのより柔軟で再利用可能なメカニズムは,以下の方法で本格的なMayavi contribパッケージを作ることです.

  1. Pythonパッケージを作成します.これを mv_iitb (IIT Bombay固有の拡張/カスタマイズ用)とします.このパッケージのディレクトリ構造は次のようになります.

    mv_iitb/
            __init__.py
            user_mayavi.py
            sources/
                    ...
            filters/
                    ...
            modules/
                    ...
            docs/
                ...
    

    上記で注目すべき2つのポイントは, mv_iitb が適切なPythonパッケージ( __init__.py に注目してください)であり, user_mayavi.py がMayaviに新しいソース/フィルタ/モジュールなどを追加するファイルであるという事実です.構造の他の部分は開発者次第です.現時点では,これらのパッケージは新しいソース,フィルタ,モジュールを追加でき, mayavi2 アプリケーションがロードするEnvisageプラグインを提供できます.

  2. このパッケージは sys.path のどこかにインストールされるべきです.これが終わったら,ユーザはこれらのパッケージを見つけて, Tools->Preferences (UIがパッケージを自動的に検出します.)からそれらを有効にすることができます.選択した各パッケージの user_mayavi.py は,Mayaviの次回起動時にインポートされます.これは mlab からでも使用できます.

このようなパッケージは,いくつでも作成して配布できます.これらがインストールされている場合,ユーザーはこれらを有効にすることができます.内部的には,選択されたパッケージの一覧は mayavi.contrib_packages 設定オプションとして格納されます.次のコードは,Pythonスクリプトからこれにアクセスする方法を示しています.

>>> from mayavi.preferences.api import preference_manager
>>> print(preference_manager.root.contrib_packages)
[]
>>> preference_manager.configure_traits() # Pop up a UI.

user_mayavi.py ファイルを書く最善の方法とそれらで何ができるかの詳細については, examples/mayavi/user_mayavi.py の例を参照してください.そのファイルの警告には特に注意してください. user_mayavi.py がソース/モジュール/フィルタを実装せず,メタデータのみを登録することを保証することは非常に良い考えです.これにより,循環インポートの問題を回避できます.

Mayavi2のカスタマイズ

Mayaviをカスタマイズするには,次の3つの方法があります.

  1. システムにインストールされているMayaviコントリビューションにより.これを行うには,Mayaviコンポーネントの Tools->Preferences "contribution settings" メニューから検索結果を有効にします.選択したコントリビューションは,Mayaviの次回起動時にインポートされます.詳細については, Extending Mayavi with customizations セクションを参照してください.

  2. site_mayavi.py を経由したグローバルなシステムレベルで,このファイルは sys.path のどこにでも置くことができます.

  3. ローカルのユーザーレベル.これは user_mayavi.py をusers ~/.mayavi2/ ディレクトリに置くことで達成されます. ~/.mayavi2/user_mayavi.py が見つかった場合,ディレクトリは sys.path に配置されます.

ファイルの内容は似ています.このファイルでは,次の2つのことを行うことができます.

  1. 新しいソース,モジュール,またはフィルタをMayaviレジストリに登録します( mayavi.core.registry.registry ).これを行うには,新しいクラスのメタデータをレジストリに登録します.例については, examples/mayavi/user_mayavi.py を参照してください.

  2. mayavi2アプリケーションにenvenageプラグインを追加します.これは,mayavi2アプリケーションに追加するプラグインのリストを返す get_plugins() という関数を定義することによって行います.

examples/mayavi/user_mayavi.py の例はこれがどのように行われるかを記述し,示します.このファイルを表示するには,ファイルを ~/.mayavi2 ディレクトリにコピーします.ご使用のプラットフォームで ~ がどこにあるかわからない場合は,サンプルを実行するとディレクトリが出力されます.

警告

user_mayavi.pysite_mayavi.py では, from mayavi.modules.outline import Outline などのMayaviインポートを避けてください.これは, user_mayavi がインポートの多くが完了していない時期にインポートされるため,デバッグが困難な循環インポートの問題が発生するためです. registry には,ほとんどが文字列形式のメタデータのみが与えられますが,これは問題になりません.したがって,新しいモジュールを定義するには,別のモジュールで定義するか,提供されているサンプル user_mayavi.py のようにファクトリ関数で定義することを強くお勧めします.

Envisageを使用しないMayaviのスクリプティング

スタンドアロンの例 はEnvisageを使わずにMayaviのコアAPIを使う方法を示しています.これは,依存関係を最小化する場合に便利です. オフスクリーンの例 は,想定されるUIや特性UI(すなわち純粋なTVTKウィンドウで)を使用せずにMayaviを使用する方法と,画面に表示されないレンダリングを実行する方法を示します.

スレッドでの計算

スレッドで計算する例 は2D numpy配列を可視化する方法と,いくつかのモジュールを使って画像データとして可視化する方法をデモしています.また,別のスレッドで計算を実行し,計算が完了したらMayaviパイプラインを更新する方法も示します.これにより,計算が別のスレッドで実行されるときに,ユーザーがユーザーインタフェースと対話できるようになります.

ファイルをポーリングしてMayaviを自動更新する

視覚化に適したデータを生成する別の計算プロセスがある場合もあります.Mayaviにデータを視覚化させたいが,計算によってデータファイルが更新されたときに自動的にデータを更新したい.これは,データファイルをポーリングし,変更されているかどうかを確認することで簡単に実現できます. Pollファイルの例 はこれを実証しています.動作を確認するには, examples/data/heart.vtk データファイルのスカラーデータを編集する必要があります.

ネットワーク上でのMayaviの提供

小さなビジュアル化スクリプトがあり,TCP/UDP接続から実行中のMayavi UIをスクリプト化できるサーバを実行したいとします. Twisted がインストールされていれば,これを行う簡単な方法があることがわかります.簡単な例を次に示します.

from mayavi import mlab
from mayavi.tools import server
mlab.test_plot3d()
server.serve_tcp()

上記で mlab.show() を呼ぶ必要はありません.上記の例では,TCPサーバはデフォルトでポート8007で受信します(これは, serve_tcp() に適切な引数を指定して変更できます.).サーバーに送信されるデータはどれも単純にexecされるため,ほとんど何でもできるのです. enginescenecamera ,および mlab という名前はすべて使用可能で,Pythonコードでスクリプト化できます.たとえば,上記のコマンドを実行した後,次のように実行できます.

$ telnet localhost 8007
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
scene.camera.azimuth(45)
mlab.clf()
mlab.test_contour3d()
scene.camera.zoom(1.5)

これの良いところは,アプリケーションの対話性を失うことなく,以前と同じようにUIを使い続けることができ,ネットワーク・コマンドはこの上で単純に実行されることです.UDPポートでサービスするには serve_udp() 機能を使います. server モジュールの詳細については,ソースコードを参照してください.

警告

これは非常に強力ですが,リモートユーザはサーバに接続すればほとんど何でもできるので,大きなセキュリティホールにもなります.

TCPサーバ: serve_tcp 関数

UDPサーバ: serve_udp 関数

時系列のアニメーション

mayaviがロードできるファイルの形式が some_name[0-9]*.ext である場合,それはタイムスライスの一部として扱われます.たとえば,次のファイルがあるとします.

$ ls
data_01.vti data_02.vti ... data_10.vti

Mayaviを使用してファイルをロードすると,ファイルリーダオブジェクトにスライダが表示され,これを使用して適切なタイムステップを選択できます.タイムステップを自動的に変更するボタンもあります.これを行うには,再生チェックボックスをオンにします.これは,次のようにプログラムで実行することもできます.

from mayavi import mlab
src = mlab.pipeline.open('data_01.vti')
src.play = True

"loop" チェックボックスを選択すると,ファイルが連続的にループします.タイムスケールの一部である複数のファイルがある場合は, "sync timestep" オプションを選択できます.これにより,現在のリーダーと同じタイムステップ数を持つ他のファイルのすべてのタイムステップが同期されます. "Rescan files" ボタンをクリックすると,ディスク上のファイルが再スキャンされ,タイムスケールに含まれる新しいファイルが検索されます.

ビジュアル化のアニメーション化

多くの場合,ユーザはビューのインタラクティブ機能に影響を与えずにビジュアル化をアニメートします.たとえば,カメラを連続的に回転させながら,Mayavi UIとの対話を続けながらスナップショットを撮るとします.これを行うには,Mayaviに用意されている非常に便利な animate() デコレータを使用できます.簡単な例を次に示します.

from mayavi import mlab
@mlab.animate
def anim():
    f = mlab.gcf()
    while 1:
        f.scene.camera.azimuth(10)
        f.scene.render()
        yield

a = anim() # Starts the animation.

上記の yield の使用に注意してください,これはこの動作に とても 重要です.この例では,UIのインタラクティブ性に影響を与えずに,カメラを連続的に回転させます.また,アニメーションの開始と停止,および関数の呼び出し間隔の変更を行うための小さなUIも表示されます.より専門的に使用するために,引数をデコレータに渡すことができます.

from mayavi import mlab
@mlab.animate(delay=500, ui=False)
def anim():
    # ...

a = anim() # Starts the animation without a UI.

すべての mlab をインポートしたくない場合は,animateデコレータを次の場所から利用できます.

from mayavi.tools.animator import animate

イベントループを開始する, つまり アニメーションを実行するには,GUI環境をまだ実行していない場合に show() を呼び出す必要があることに注意してください.

次にデコレータの使用例を示します.

import numpy as np
from mayavi import mlab

@mlab.animate(delay = 100)
def updateAnimation():
    t = 0.0
    while True:
        ball.mlab_source.set(x = np.cos(t), y = np.sin(t), z = 0)
        t += 0.1
        yield

ball = mlab.points3d(np.array(1.), np.array(0.), np.array(0.))

updateAnimation()
mlab.show()

詳細については, MLabリファレンス にある animate() デコレータのドキュメントを参照してください.このデコレータをオブジェクト移動アニメーションに便利な visual とともに使用する例については, Mlabの視覚的な例 を参照してください.

注釈

アニメーション内のオブジェクトのデータを変更する場合は, データのアニメート を参照してください.

アニメーションからのムービーの作成

ムービーは,アニメーションまたはタイムスケールを再生して簡単に作成できます.UI上でこれを行うには,Mayavi Sceneを選択し,Movieタブに移動してrecordチェックボックスを選択します.この後, 時系列のアニメーション で参照されている "play" チェックボックスを使用してタイムステップをアニメートすると,ムービーUIで指定されているディレクトリにイメージのスタックが作成されます.これは, ビジュアル化のアニメーション化 で説明されているようにアニメーションを実行する場合にも発生します.

たとえば,次のようにmlabを使用してスクリプトを作成することもできます.

from mayavi import mlab
f = mlab.figure()
f.scene.movie_maker.record = True
mlab.test_mesh_sphere_anim()

これにより,アニメーションの各ステップに1つずつ,イメージのセットが作成されます. movie_maker インスタンスは,作成した各シーンで使用できます.

一連のイメージをアニメートする

Mayaviシーンでアニメートする一連の番号付きPNGまたはJPEGファイルがあるとします.簡単なスクリプトを次に示します( img_movie.py と呼ばれています).

# img_movie.py
from pyface.timer.api import Timer

def animate(src, N=10):
    for j in range(N):
        for i in range(len(src.file_list)):
            src.timestep = i
            yield

if __name__ == '__main__':
    src = mayavi.engine.scenes[0].children[0]
    animator = animate(src)
    t = Timer(250, animator.next)

Timer クラスを使用すると,実行中のユーザインターフェイスをブロックせずに関数を呼び出すことができます.最初の引数は,関数がミリ秒単位で再度呼び出される時間です. animate 関数はジェネレータであり,ソースのタイムステップを変更します.このスクリプトは,イメージのスタックを10回アニメートします.スクリプトでは,デフォルトで最初のデータ・ソースがアニメーション化されます.これは簡単に変更できます.

このスクリプトを使用するには,次の操作を行います.

$ mayavi2 -d your_image000.png -m ImageActor -x img_movie.py

画像のスタックからムービーを作成します

これは実際にはMayaviとは関係ありませんが,便利なトリックです.たとえば, anim%03d.png ( anim000.pnganim001.png など)という形式のMayaviコマンドを使用してイメージのスタックを生成すると,これをムービーにすることができます. mencoder がインストールされている場合は,次の操作を試してください.

$ mencoder "mf://anim%03d.png" -mf fps=10 -o anim.avi \
  -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=500

ffmpegがインストールされている場合は,以下を試してみてください.

$ ffmpeg -f image2 -r 10 -i anim%03d.png -sameq anim.mov -pass 2

コマンドラインからのスクリプティング

Mayaviアプリケーションでは,シェルから複雑なビジュアライゼーションを構築できる非常に強力な コマンドライン引数 が可能です.以下に,これらを説明する簡単な例を示します.

次の例では, ParametricSurface ソースを作成し,サーフェス上の赤のグリフを表示します.

$ mayavi2 -d ParametricSurface -m Glyph \
-s"glyph.glyph.scale_factor=0.1" \
-s"glyph.color_mode='no_coloring'" \
-s"actor.property.color = (1,0,0)"

-s"string" はグリフである最後のオブジェクト( last_obj としても利用可能)に文字列を適用することに注意してください.

次の例では,Glyphのカラーリングをオフにし,表示するGlyphを変更します

$ mayavi2 -d ParametricSurface -m Glyph\
-s"glyph.glyph.scale_factor=0.1" \
-s"glyph.color_mode='no_coloring'" \
-s"glyph.glyph_source.glyph_source = last_obj.glyph.glyph_source.glyph_list[-1]"

上記の last_obj の使い方に注意してください.

テクスチャマッピングアクター

以下は,Mayaviソースに付属するデータ(データファイルはexamplesディレクトリにあります)を使用してアイソサーフェスをテクスチャマッピングする方法を示す簡単な例です.

$ mayavi2 -d examples/tvtk/images/masonry.jpg \
 -d examples/mayavi/data/heart.vti \
 -m IsoSurface \
 -s"actor.mapper.scalar_visibility=False" \
 -s"actor.enable_texture=True"\
 -s"actor.tcoord_generator_mode='cylinder'"\
 -s"actor.texture_source_object=script.engine.current_scene.children[0]"

代わりに ParametricSurface とあなたが選んだ他の画像を使うようにこの例を変えるのは比較的簡単であるべきです.上の最後の行で,テクスチャイメージ( masonry.jpg )がどのように設定されているかに注目してください.イメージリーダは現在のシーンの最初の子であり,これをisosurfaceアクターの texture_source_object として設定します.

データのシフトとプロット

入力データを空間でシフト/変換し,元のデータに加えて視覚化する必要がある場合があります.これは,同じデータに対して異なる操作を行い,同じプロットで表示する場合に便利です.これは, StructuredGridPolyData および UnstructuredGrid データセットに対して TransformData フィルタを使用してMayaviで実行できます.ParametricSurface データソースを使用した例を次に示します.

$ mayavi2 -d ParametricSurface \
  -m Outline -m Surface \
  -f TransformData -s "transform.translate(1,1,1)" \
  -s "widget.set_transform(last_obj.transform)" \
  -m Outline -m Surface

ImageData データセットがある場合は, ImageChangeInformation フィルタを使用して,原点,間隔,範囲だけを変更できます.次に,標準のMayaviイメージデータを使用した簡単な例を示します.

$ mayavi2 -d examples/mayavi/data/heart.vti -m Outline \
-m ImagePlaneWidget \
-f ImageChangeInformation \
-s "filter.origin_translation=(20,20,20)" \
-m Outline -m ImagePlaneWidget

UserDefined フィルタの使用

Mayaviの``UserDefined`` フィルタを使用すると,既存のVTKフィルタを簡単にラップできます.次に例を示します.

$ mayavi2 -d ParametricSurface -s "function='dini'" \
-f UserDefined:GeometryFilter \
-s "filter.extent_clipping=True" \
-s "filter.extent = [-1,1,-1,1,0,5]" \
-f UserDefined:CleanPolyData \
-m Surface \
-s "actor.property.representation = 'p'" \
-s "actor.property.point_size=2"

この例では, tvtk.GeometryFilter を使用して,生成されたパラメトリックサーフェイスの範囲ベースのクリッピングを実行します. -f UserDefined:GeometryFilter の仕様に注意してください.このデータは tvtk.CleanPolyData フィルタを使用して消去されます.

mlab の下で Userdefined を使用すると,例えば GeometryFilter VTKフィルタを次のようにラップすることができます.

filtered_obj = mlab.pipeline.user_defined(obj, filter='GeometryFilter')

mlab の場合, user_defined 関数は,使用されるVTKフィルタの名前をフィルタ引数として取ることも,すでにインスタンス化されているフィルタのインスタンスを取ることもできます.

注釈

UserDefined フィルタを使用すると,ほとんどのMayaviフィルタと同様に,生のTVTKオブジェクトにMayaviフィルタオブジェクトの filter アトリビュートとしてアクセスできます.

イメージカーソルフィルタの例 は,UserDefinedフィルタを使用する完全な例を提供します. Tvtkセグメンテーションの例 は,UserDefinedフィルタを多用して複雑なVTKパイプラインを構築する完全な例です.

シーン間での同じデータの共有

同じデータを異なるビューに表示する場合は,データソースが1つのシーンに属することができるため,異なるMayaviデータソースを作成する必要があります.ただし,データをコピーしたり,ソースを最初から再作成したりする必要はありません.コツは,同じ基本VTKデータセットを指す別のMayaviデータソースを作成し,それを別のシーン(MayaviソースとVTKデータセットの違いについては Mayaviでのデータ表現 を参照してください.)にアタッチすることです.

mlabの使用

mlab から返される全ての可視化オブジェクトは mlab_source 属性を持ち,これは dataset としてVTKデータセットを公開します.加えて,モジュールを追加する mlab pipeline 関数は生のVTKデータセットの使い方を知っています.したがって,新しい図でデータセットを公開するには,mlabによって作成された視覚化オブジェクトの mlab_source.dataset 属性を mlab.pipeline 関数に渡すだけで済みます.

from mayavi import mlab
ctr = mlab.test_contour3d()
mlab.figure()
ipw = mlab.pipeline.image_plane_widget(ctr.mlab_source.dataset)
mlab.show()

上の例では,同じデータを表示する2つのフィギュアを作成します.1つはアイソサーフェスを使用し,もう1つはイメージプレーンウィジェットを使用します.

あるいは, mlab の現在の図を使用するよりも,新しいモジュールが追加された図について明示することが有用である可能性があります.これは,現在の数字が明確でないスクリプトではなく対話型アプリケーションなどの状況でコードを読みやすくするために重要です.

new_fig = mlab.figure()
ipw = mlab.pipeline.image_plane_widget(ctr.mlab_source.dataset, figure=new_fig)

ボリュームスライサの例 は, mlab.pipeline を介して異なるビューを通して同じデータを公開する複雑なダイアログを示します.

コアMayavi APIの使用

また,ファクトリを使用する代わりに,MayaviコアAPIを使用してオブジェクトを自分で作成し,パイプラインに追加することで,これを完全に明示的に行うこともできます.

import numpy as np
a = np.random.random((3, 3, 3))
from mayavi.sources.api import ArraySource, VTKDataSource
src1 = ArraySource(scalar_data=a)
engine.add_source(src1)
engine.new_scene()
scene2 = engine.current_scene

# Now create a second data source viewing the same data:
src2 = VTKDataSource(data=src1.image_data)
scene2.add_child(src2)

シーンとのインタラクションの変更

シーンとの既定の3Dインタラクション(背景を左クリックするとシーンが回転し,右クリックするとスケールが回転し,中クリックするとパンが回転します)は,すべての表示に適しているわけではありません.たとえば,inは,オブジェクトを 'x' 方向に見ているときなどに,移動を2Dに制限することができます.これを行うには,シーンの interactor_style を変更します.Mayaviを2Dイメージビューアとして使用する例を次に示します.

from mayavi import mlab
mlab.test_imshow()
mlab.view(0, 0)
fig = mlab.gcf()
from tvtk.api import tvtk
fig.scene.interactor.interactor_style = tvtk.InteractorStyleImage()
mlab.show()

もう1つの便利な相互作用子は 'terrain' 相互作用子で, 'up' ベクトルを常に 'z' 方向に向けたいシーンで自然な動きをするのに便利です.

from mayavi import mlab
mlab.test_surf()
fig = mlab.gcf()
from tvtk.api import tvtk
fig.scene.interactor.interactor_style = tvtk.InteractorStyleTerrain()
mlab.show()

VTKには多くの異なるインターアクターがあります.これらを一覧表示する簡単な方法は,VTKクラスブラウザを表示し(ヘルプメニューの mayavi2 アプリケーション), "Interactor" を検索することです.もう1つのオプションは, tvtk.InteractorStyle でIpythonをタブ補完することです.

Mayaviスクリプトの高速化

これでMayavi/mlabスクリプトが完成し,アニメーションまたは一連のイメージを生成することができました.イメージのレンダリングに時間がかかりすぎて,完了までに時間がかかることに気付くでしょう.レンダリングを高速化する簡単な方法は2つあります. objscene 属性を持つMayaviパイプラインオブジェクトであると仮定します.

obj.scene.disable_render = True
# Do all your scripting that takes ages.
# ...
# Once done, do the following:
obj.scene.disable_render = False

これにより,複雑な視覚化の処理速度が1桁向上することがあります.

ビジュアライゼーションをイメージに保存するときに,次の操作を行うと,アンチエイリアシングを犠牲にしてイメージ生成を高速化できます.

obj.scene.anti_aliasing_frames = 0

既定値は通常8で,レンダリングイメージには適切なアンチエイリアシングが適用されます.0に設定すると,レンダーしたイメージに大きな違いは生じませんが,スムースなラインは少しギザギザに表示されます.ただし,レンダリングははるかに高速になります.したがって,これが許容される場合(試してみてください),これはイメージの生成を高速化するメカニズムです.