なぜPyVistaなのか?#

VTKは優れた可視化ツールキットであり,Pythonバインディングを使えば,C++のスピードとPythonのラピッドプロトタイピングを組み合わせることができるはずです.ただし,PythonでプログラムされたこのVTKコードは,一般的には対応するC++と同じように見えます.このモジュールは,機能を損なうことなくメッシュの作成とプロットを簡略化することを目的としています.

ファイルから表面メッシュをロードおよびプロットする2つの方法を比較します:

PythonのVTKを使用したメッシュのプロット#

この example を基準にすると,STLファイルの読み込みとプロットは, vtk ライブラリだけを使った場合,多くのコードを必要とします. 一方,PyVistaでは数行のコードしか必要ありません.

vtk を用いたSTLファイルの読み込みと描画

PyVistaによるSTLファイルの読み込み

import vtk
reader = vtk.vtkSTLReader()
reader.SetFileName("bunny.stl")
mapper = vtk.vtkDataSetMapper()
output_port = reader.GetOutputPort()
mapper.SetInputConnection(output_port)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
style = vtk.vtkInteractorStyleTrackballCamera()
iren.SetRenderWindow(renWin)
iren.SetInteractorStyle(style)
ren.AddActor(actor)
iren.Initialize()
renWin.Render()
iren.Start()
del iren, renWin
import pyvista
mesh = pyvista.read('bunny.stl')
mesh.plot()
../_images/why-2_00_00.png

PyVistaのデータモデルとAPIは,メッシュを素早く読み込むことができ,プロットの設定,クラスとパイプラインの接続,プロットウィンドウのクリーンアップなどの "面倒な作業" の多くを処理します. これは,VTKのクラスへの簡素化された,しかし機能的なインターフェイスを公開することで実現しています.

pyvista.read() では,ファイルの拡張子に基づいて,PyVistaが自動的に正しいファイルリーダーを決定し,データセットオブジェクトを取得します.このデータセットオブジェクトには, plot メソッドを含む, pyvista.PolyData クラスで利用可能なすべてのメソッドが含まれており,メッシュのプロットを即座に生成することができます. ガベージコレクションは自動的に処理され,ユーザーがプロットウィンドウを閉じた後,レンダラーはクリーンアップされます.

2つのAPIを比較した詳細については, PyVistaデータモデルVTKからPyVistaへの移行 を参照してください.

PyVista API#

たとえば,VTKの3角形のサーフェイスメッシュは分割できますが,VTKの他のすべてのオブジェクトは分割できません.この場合,既存の3角形表面メッシュに細分化された方法を追加することは理にかなっています.このように, pyvista.PolyDataFilters.subdivide() メソッドは次のように実行できます:

import pyvista
mesh = pyvista.Plane().triangulate()
submesh = mesh.subdivide(2, 'linear')
submesh.plot(show_edges=True)
../_images/why_1_0.png

また,PyVistaのすべてのメソッドのdocstringは,インタラクティブなコーディングセッションで使用することを意図しています.これにより,高度な処理ルーチンをその場で使用し,メソッドの使用方法の説明にすぐにアクセスできます.

../_images/documentation.gif

他のライブラリとの連携#

PyVistaは numpy に大きく依存しており,VTKメッシュからのポイント,セル,フィールド,その他のデータを表現するために使用しています. このデータは, pyvista.DataSet.points のようなデータセット属性から簡単にアクセスできます. 例えば,pyvistaの円の最初の10点には次のようにアクセスできます.

circle = pyvista.Circle()
circle.points[:10]
pyvista_ndarray([[0.5       , 0.        , 0.        ],
                 [0.49901336, 0.03139526, 0.        ],
                 [0.49605735, 0.06266662, 0.        ],
                 [0.49114363, 0.09369066, 0.        ],
                 [0.48429158, 0.12434494, 0.        ],
                 [0.47552826, 0.1545085 , 0.        ],
                 [0.46488824, 0.18406228, 0.        ],
                 [0.45241353, 0.21288965, 0.        ],
                 [0.43815334, 0.24087684, 0.        ],
                 [0.42216396, 0.2679134 , 0.        ]])

また,これらのポイントは,あたかもNumPyの配列のように操作することができますが,その際,基礎となるVTKデータ配列との接続は失われません.

同時に,様々なPyVistaオブジェクトをnumpy配列から直接生成することができます. 例えば,以下では numpy.meshgrid() を使って,矢印のベクトルフィールドを生成しています.

import pyvista
import numpy as np

# Make a grid
x, y, z = np.meshgrid(np.linspace(-5, 5, 20),
                      np.linspace(-5, 5, 20),
                      np.linspace(-5, 5, 5),
                      indexing='ij')

points = np.empty((x.size, 3))
points[:, 0] = x.ravel('F')
points[:, 1] = y.ravel('F')
points[:, 2] = z.ravel('F')

# Compute a direction for the vector field
direction = np.sin(points)**3

# plot using the plotting class
pl = pyvista.Plotter()
pl.add_arrows(points, direction, 0.5)
pl.show()
../_images/why_3_0.png

PyVistaは, meshiomatplotlib など,いくつかの他のライブラリに接続しており,PyVistaはVTKをPythonエコシステムの機能で拡張することができます.