~ubuntu-branches/ubuntu/hardy/mayavi2/hardy-backports

« back to all changes in this revision

Viewing changes to enthought.mayavi/enthought/mayavi/html/_sources/advanced_scripting.txt

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2008-07-25 09:03:34 UTC
  • mfrom: (2.2.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080725090334-1hbb9fn8b3as5qy0
Tags: 2.2.0-1~hardy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
.. _advanced-scripting-with-mayavi:
 
2
 
 
3
Advanced Scripting with Mayavi
 
4
===============================
 
5
 
 
6
As elaborated in the :ref:`an-overview-of-mayavi` section, mayavi can be
 
7
scripted from Python in order to visualize data.  Mayavi2 was designed
 
8
from the ground up to be highly scriptable.  Everything that can be done
 
9
from the user interface can be achieved using Python scripts. 
 
10
 
 
11
If you are not looking to script mayavi itself but looking for quick
 
12
ways to get your visualization done with simple code you may want to
 
13
check out mayavi's mlab module.  This is described in more detail in
 
14
the :ref:`simple-scripting-with-mlab` section.
 
15
 
 
16
To best understand how to script mayavi, a reasonable understanding of
 
17
the mayavi internals is necessary.  The following sections provides an
 
18
overview of the basic design and objects in the mayavi pipeline.
 
19
Subsequent sections consider specific example scripts that are
 
20
included with the mayavi sources that illustrate the ideas.
 
21
 
 
22
Mayavi2 uses Traits_ and TVTK_ internally.  Traits_ in many ways
 
23
changes the way we program.  So it is important to have a good idea of
 
24
Traits in order to understand mayavi's internals.  If you are unsure
 
25
of traits it is a good idea to get a general idea about traits now.
 
26
Trust me, your efforts learning Traits will not be wasted!
 
27
 
 
28
.. _Traits: https://svn.enthought.com/enthought/wiki/Traits
 
29
.. _TVTK: https://svn.enthought.com/enthought/wiki/TVTK
 
30
 
 
31
Design Overview
 
32
---------------
 
33
 
 
34
This section provides a brief introduction to mayavi's internal
 
35
architecture.
 
36
 
 
37
The "big picture" of a visualization in mayavi is that an ``Engine``
 
38
(``enthought.mayavi.engine.Engine``) object manages the entire
 
39
visualization.  The ``Engine`` manages a collection of ``Scene``
 
40
(``enthought.mayavi.core.scene.Scene``) objects.  In each ``Scene``, a
 
41
user may have created any number of ``Source``
 
42
(``enthought.mayavi.core.source.Source``) objects.  A ``Source``
 
43
object can further contain any number of ``Filters``
 
44
(``enthought.mayavi.core.filter.Filter``) or ``ModuleManager``
 
45
(``enthought.mayavi.core.module_manager.ModuleManager``) objects.  A
 
46
``Filter`` may contain either other filters or ``ModuleManagers``.  A
 
47
``ModuleManager`` manages any number of ``Modules``.  The figure below
 
48
shows this hierarchy in a graphical form.
 
49
 
 
50
.. image:: images/m2_big_picture.png
 
51
   :alt: Illustration of the various objects in the mayavi pipeline.
 
52
 
 
53
*Illustration of the various objects in the mayavi pipeline.*
 
54
 
 
55
This hierarchy is precisely what is seen in the Mayavi tree view on
 
56
the UI.  The UI is therefore merely a graphical representation of this
 
57
internal world-view.  A little more detail on these objects is given
 
58
below.  For even more details please refer to the sources.
 
59
 
 
60
All objects in the mayavi pipeline feature ``start`` and ``stop``
 
61
methods.  The reasoning for this is that any object in mayavi is not
 
62
usable (i.e. it may not provide any outputs) unless it has been
 
63
started.  Similarly the ``stop`` method "deactivates" the object.
 
64
This is done because mayavi is essentially driving VTK objects
 
65
underneath.  These objects require inputs in order to do anything
 
66
useful.  Thus, an object that is not connected to the pipeline cannot
 
67
be used.  For example, consider an ``IsoSurface`` module.  It requires
 
68
some data in order to contour anything.  Thus, the module in isolation
 
69
is completely useless.  It is usable only when it is added to the
 
70
mayavi pipeline.  When an object is added to the pipeline, its inputs
 
71
are setup and its ``start`` method is called automatically.  When the
 
72
object is removed from the pipeline its ``stop`` method is called
 
73
automatically.
 
74
 
 
75
Apart from the ``Engine`` object, all other objects in the mayavi
 
76
pipeline feature a ``scene`` trait which refers to the current
 
77
``enthought.pyface.tvtk.tvtk_scene.TVTKScene`` instance that the
 
78
object is associated with.  The objects also feature an ``add_child``
 
79
method that lets one build up the pipeline by adding "children"
 
80
objects.  The ``add_child`` method is "intelligent" and will try to
 
81
appropriately add the child in the right place.
 
82
 
 
83
Here is a brief description of the key objects in the mayavi pipeline.
 
84
 
 
85
 ``Engine``
 
86
    The Mayavi engine is defined in the ``enthought.mayavi.engine``
 
87
    module.
 
88
 
 
89
     * It possesses a ``scenes`` trait which is a Trait ``List`` of
 
90
       ``Scene`` objects.
 
91
 
 
92
     * Features several methods that let one add a
 
93
       ``Filter/Source/Module`` instance to it.  It allows one to
 
94
       create new scenes and delete them.  Also has methods to load
 
95
       and save the entire visualization.
 
96
 
 
97
     * The ``EnvisageEngine`` defined in the
 
98
       ``enthought.mayavi.envisage_engine`` module is a subclass of
 
99
       ``Engine`` and is the one used in the ``mayavi2`` application.
 
100
       The ``Engine`` object is not abstract and itself perfectly
 
101
       usable.  It is useful when users do not want to use Envisage_
 
102
       but still desire to use mayavi for visualization.
 
103
 
 
104
 ``Scene``
 
105
    Defined in the ``enthought.mayavi.core.scene`` module.
 
106
 
 
107
     * ``scene`` attribute: manages a ``TVTKScene``
 
108
       (``enthought.pyface.tvtk.tvtk_scene``) object which is where
 
109
       all the rendering occurs.
 
110
 
 
111
     * The ``children`` attribute is a ``List`` trait that manages a
 
112
       list of ``Source`` objects.
 
113
 
 
114
 ``PipelineBase``   
 
115
    Defined in the ``enthought.mayavi.core.pipeline_base`` module.
 
116
    Derives from ``Base`` which merely abstracts out common
 
117
    functionality.  The ``PipelineBase`` is the base class for all
 
118
    objects in the mayavi pipeline except the ``Scene`` and ``Engine``
 
119
    (which really isn't *in* the pipeline but contains the pipeline).
 
120
 
 
121
     * This class is characterized by two events, ``pipeline_changed``
 
122
       and ``data_changed``.  These are ``Event`` traits.  They
 
123
       determine when the pipeline has been changed and when the data
 
124
       has changed.  Therefore, if one does::
 
125
 
 
126
             object.pipeline_changed = True 
 
127
 
 
128
       then the ``pipeline_changed`` event is fired.  Objects
 
129
       downstream of ``object`` in the pipeline are automatically
 
130
       setup to listen to events from an upstream object and will call
 
131
       their ``update_pipeline`` method.  Similarly, if the
 
132
       ``data_changed`` event is fired then downstream objects will
 
133
       automatically call their ``update_data`` methods.
 
134
 
 
135
     * The ``outputs`` attribute is a trait ``List`` of outputs
 
136
       produced by the object.
 
137
 
 
138
 
 
139
 ``Source``
 
140
    Defined in the ``enthought.mayavi.core.source`` module.  All the
 
141
    file readers, Parametric surface etc. are subclasses of the
 
142
    ``Source`` class.
 
143
 
 
144
     * Contains the rest of the pipeline via its ``children`` trait.
 
145
       This is a ``List`` of either ``Modules`` or other ``Filters``.
 
146
    
 
147
     * The ``outputs`` attribute is a trait ``List`` of outputs
 
148
       produced by the source.
 
149
 
 
150
 ``Filter``
 
151
    Defined in the ``enthought.mayavi.core.filter`` module.  All the
 
152
    ``Filters`` described in the :ref:`filters` section are subclasses of
 
153
    this.
 
154
 
 
155
     * Contains the rest of the pipeline via its ``children`` trait.
 
156
       This is a ``List`` of either ``Modules`` or other ``Filters``.
 
157
    
 
158
     * The ``inputs`` attribute is a trait ``List`` of input data
 
159
       objects that feed into the filter.
 
160
 
 
161
     * The ``outputs`` attribute is a trait ``List`` of outputs
 
162
       produced by the filter.
 
163
       
 
164
     * Also features the three methods:
 
165
 
 
166
       - ``setup_pipeline``: used to create the underlying
 
167
          TVTK pipeline objects if needed.
 
168
 
 
169
       - ``update_pipeline``: a method that is called when the
 
170
         upstream pipeline has been changed, i.e. an upstream object
 
171
         fires a ``pipeline_changed`` event.
 
172
 
 
173
       - ``update_data``: a method that is called when the upstream
 
174
         pipeline has **not** been changed but the data in the
 
175
         pipeline has been changed.  This happens when the upstream
 
176
         object fires a ``data_changed`` event.
 
177
 
 
178
 ``ModuleManager``
 
179
    Defined in the ``enthought.mayavi.core.module_manager`` module.
 
180
    This object is the one called *Modules* in the tree view on the
 
181
    UI.  The main purpose of this object is to manage ``Modules`` and
 
182
    share common data between them.  All modules typically will use
 
183
    the same lookup table (LUT) in order to produce a meaningful
 
184
    visualization.  This lookup table is managed by the module
 
185
    manager.
 
186
 
 
187
     * The ``source`` attribute is the ``Source`` or ``Filter`` object
 
188
       that is the input of this object.
 
189
 
 
190
     * Contains a list of ``Modules`` in its ``children`` trait.
 
191
    
 
192
     * The ``scalar_lut_manager`` attribute is an instance of a
 
193
       ``LUTManager`` which basically manages the color mapping from
 
194
       scalar values to colors on the visualizations.  This is
 
195
       basically a mapping from scalars to colors.
 
196
 
 
197
     * The ``vector_lut_manager`` attribute is an instance of a
 
198
       ``LUTManager`` which basically manages the color mapping from
 
199
       vector values to colors on the visualizations.
 
200
 
 
201
     * The class also features a ``lut_data_mode`` attribute that
 
202
       specifies the data type to use for the LUTs.  This can be
 
203
       changed between 'auto', 'point data' and 'cell data'.  Changing
 
204
       this setting will change the data range and name of the lookup
 
205
       table/legend bar.  If set to 'auto' (the default), it
 
206
       automatically looks for cell and point data with point data
 
207
       being preferred over cell data and chooses the one available.
 
208
       If set to 'point data' it uses the input point data for the LUT
 
209
       and if set to 'cell data' it uses the input cell data.
 
210
 
 
211
 ``Module`` 
 
212
    Defined in the ``enthought.mayavi.core.module`` module.
 
213
    These objects are the ones that typically produce a visualization
 
214
    on the TVTK scene.  All the modules defined in the :ref:`modules`
 
215
    section are subclasses of this.
 
216
 
 
217
     * The ``components`` attribute is a trait ``List`` of various
 
218
       reusable components that are used by the module.  These usually
 
219
       are never used directly by the user.  However, they are
 
220
       extremely useful when creating new modules.  A ``Component`` is
 
221
       basically a reusable piece of code that is used by various
 
222
       other objects.  For example, almost every ``Module`` uses a
 
223
       TVTK actor, mapper and property.  These are all "componentized"
 
224
       into a reusable `Actor` component that the modules use.  Thus,
 
225
       components are a means to promote reuse between mayavi pipeline
 
226
       objects.
 
227
 
 
228
     * The ``module_manager`` attribute specifies the
 
229
       ``ModuleManager`` instance that it is attached to.
 
230
 
 
231
     * Like the ``Filter`` modules also feature the three methods:
 
232
 
 
233
       - ``setup_pipeline``: used to create the underlying
 
234
          TVTK pipeline objects if needed.
 
235
 
 
236
       - ``update_pipeline``: a method that is called when the
 
237
         upstream pipeline has been changed, i.e. an upstream object
 
238
         fires a ``pipeline_changed`` event.
 
239
 
 
240
       - ``update_data``: a method that is called when the upstream
 
241
         pipeline has **not** been changed but the data in the
 
242
         pipeline has been changed.  This happens when the upstream
 
243
         object fires a ``data_changed`` event.
 
244
 
 
245
The following figures show the class hierarchy of the various objects
 
246
involved.
 
247
 
 
248
 
 
249
.. image:: images/design2c.png
 
250
   :alt: The ``Engine`` object.
 
251
 
 
252
*The ``Engine`` object and its important attributes and methods.*
 
253
 
 
254
.. image:: images/design2a.png
 
255
   :alt: Basic object hierarchy
 
256
 
 
257
*This hierarchy depicts the ``Base`` object, the ``Scene``,
 
258
``PipelineBase`` and the ``ModuleManager``.*
 
259
 
 
260
.. image:: images/design2b.png
 
261
   :alt: More object hierarchy
 
262
 
 
263
*This hierarchy depicts the ``PipelineBase`` object, the ``Source``,
 
264
``Filter``, ``Module`` and the ``Component``.*
 
265
 
 
266
 
 
267
Scripting the ``mayavi2`` application
 
268
-------------------------------------
 
269
 
 
270
The ``mayavi2`` application is implemented in the
 
271
``enthought.mayavi.scripts.mayavi2`` module (look at the
 
272
``mayavi2.py`` file and not the ``mayavi2`` script).  This code
 
273
handles the command line argument parsing and runs the application.
 
274
 
 
275
``mayavi2`` is an Envisage_ application.  It starts the Envisage
 
276
application in its ``main`` method.  The code for this is in the
 
277
``enthought.mayavi.app`` module.  Mayavi uses several envisage plugins
 
278
to build up its functionality.  These plugins are defined in the
 
279
``enthought.mayavi.plugin_definitions`` module.  In this module there
 
280
are two lists of plugins defined, ``PLUGIN_DEFINITIONS`` and the
 
281
``NONGUI_PLUGIN_DEFINITIONS``.  The default application uses the
 
282
former which produces a GUI that the user can use.  If one uses the
 
283
latter (``NONGUI_PLUGIN_DEFINITIONS``) then the mayavi tree view,
 
284
object editor and menu items will not be available when the
 
285
application is run.  This allows a developer to create an application
 
286
that uses mayavi but does not show its user interface.  An example of
 
287
how this may be done is provided in ``examples/nongui.py``.
 
288
 
 
289
.. _envisage: https://svn.enthought.com/enthought/wiki/Envisage
 
290
 
 
291
 
 
292
Scripting from the UI
 
293
~~~~~~~~~~~~~~~~~~~~~
 
294
 
 
295
When using the ``mayavi2`` application, it is possible to script from
 
296
the embedded Python interpreter on the UI.  On the interpreter the
 
297
name ``mayavi`` is automatically bound to an
 
298
``enthought.mayavi.script.Script`` instance that may be used to easily
 
299
script mayavi.  This instance is a simple wrapper object that merely
 
300
provides some nice conveniences while scripting from the UI.  It has
 
301
an ``engine`` trait that is a reference to the running mayavi engine.
 
302
 
 
303
As described in :ref:`the-embedded-python-interpreter` section, one can
 
304
always drag a mayavi object from the tree and drop it on the
 
305
interpreter to script it directly.
 
306
 
 
307
One may select the `File->Open File...` menu to open an existing
 
308
Python file in the text editor, or choose the `File->New File` menu to
 
309
create a new file.  The text editor is Python-aware and one may write
 
310
a script assuming that the ``mayavi`` name is bound to the ``Script``
 
311
instance as it is on the shell.  To execute this script one can press
 
312
``Control-r`` as described earlier.  ``Control-s`` will save the
 
313
script.
 
314
 
 
315
The nice thing about this kind of scripting is that if one scripts
 
316
something on the interpreter or on the editor, one may save the
 
317
contents to a file, say ``script.py`` and then the next time mayavi
 
318
run it like so::
 
319
 
 
320
  $ mayavi2 -x script.py
 
321
 
 
322
This will execute the script for automatically.  The name ``mayavi``
 
323
is available to the script and is bound to the ``Script`` instance.
 
324
This is very convenient.  It is possible to have mayavi execute
 
325
multiple scripts.  For example::
 
326
 
 
327
 $ mayavi2 -d foo.vtk -m IsoSurface -x setup_iso.py -x script2.py
 
328
 
 
329
will load the ``foo.vtk`` file, create an ``IsoSurface`` module, then
 
330
run ``setup_iso.py`` and then run ``script2.py``.
 
331
 
 
332
There are several scripts in the mayavi ``examples`` directory that
 
333
should show how this can be done.  The ``examples/README.txt``
 
334
contains some information on the recommended ways to script.
 
335
 
 
336
 
 
337
Scripting from IPython
 
338
~~~~~~~~~~~~~~~~~~~~~~
 
339
 
 
340
It is possible to script Mayavi using IPython_.  IPython will have to
 
341
be invoked with the ``-wthread`` command line option in order to allow
 
342
one to interactively script the mayavi application::
 
343
 
 
344
 $ ipython -wthread
 
345
 
 
346
To start a visualization do the following::
 
347
 
 
348
 from enthought.mayavi.app import main
 
349
 # Note, this does not process any command line arguments.
 
350
 mayavi = main()
 
351
 # 'mayavi' is the mayavi Script instance.
 
352
 
 
353
It is also possible to use mlab (see :ref:`simple-scripting-with-mlab`) for
 
354
this purpose::
 
355
 
 
356
 from enthought.mayavi.tools import mlab
 
357
 f = mlab.figure() # Returns the current scene.
 
358
 mayavi = mlab.get_mayavi() # Returns the Script instance.
 
359
 
 
360
With this it should be possible to script mayavi just the way it is
 
361
done on the embedded interpreter or on the text editor.
 
362
 
 
363
.. _IPython: http://ipython.scipy.org
 
364
 
 
365
An example
 
366
~~~~~~~~~~
 
367
 
 
368
Here is an example script that illustrates various features of
 
369
scripting mayavi::
 
370
 
 
371
  # Create a new mayavi scene.
 
372
  mayavi.new_scene()
 
373
 
 
374
  # Get the current active scene.
 
375
  s = mayavi.engine.current_scene
 
376
 
 
377
  # Read a data file.
 
378
  from enthought.mayavi.sources.api import VTKXMLFileReader
 
379
  d = VTKXMLFileReader()
 
380
  # You must specify the full path to the data here.
 
381
  d.initialize('fire_ug.vtu')
 
382
  mayavi.add_source(d)
 
383
 
 
384
  # Import a few modules.
 
385
  from enthought.mayavi.modules.api import Outline, IsoSurface, Streamline
 
386
 
 
387
  # Show an outline.
 
388
  o = Outline()
 
389
  mayavi.add_module(o)
 
390
  o.actor.property.color = 1, 0, 0 # red color.
 
391
 
 
392
  # Make a few contours.
 
393
  iso = IsoSurface()
 
394
  mayavi.add_module(iso)
 
395
  iso.contour.contours = [450, 570]
 
396
  # Make them translucent.
 
397
  iso.actor.property.opacity = 0.4
 
398
  # Show the colormapping.
 
399
  iso.module_manager.scalar_lut_manager.show_scalar_bar = True
 
400
 
 
401
  # A streamline.
 
402
  st = Streamline()
 
403
  mayavi.add_module(st)
 
404
  # Position the seed center.
 
405
  st.seed.widget.center = 3.5, 0.625, 1.25
 
406
  st.streamline_type = 'tube'
 
407
 
 
408
  # Save the resulting image.
 
409
  s.scene.save('test.png')
 
410
 
 
411
  # Make an animation:
 
412
  for i in range(36):
 
413
      # Rotate the camera by 10 degrees.
 
414
      s.scene.camera.azimuth(10)
 
415
 
 
416
      # Resets the camera clipping plane so everything fits and then
 
417
      # renders.
 
418
      s.scene.reset_zoom()
 
419
 
 
420
      # Save the scene.
 
421
      s.scene.save_png('anim%d.png'%i)
 
422
 
 
423
Sometimes, given a mayavi ``Script`` instance or ``Engine``, it is
 
424
handy to be able to navigate to a particular module/object.  In the
 
425
above this could be achieved as follows::
 
426
 
 
427
  x = mayavi.engine.scenes[0].children[0].children[0].children[-1]
 
428
  print x
 
429
 
 
430
In this case ``x`` will be set to the ``Streamline`` instance that we
 
431
just created.
 
432
 
 
433
There are plenty of examples illustrating various things in the
 
434
``examples`` directory.  These are all fairly well documented.  
 
435
 
 
436
In particular, the ``standalone.py`` example illustrates how one can
 
437
script mayavi without using the envisage application at all.  The
 
438
``offscreen.py`` example illustrates how this may be done using off
 
439
screen rendering (if supported by your particular build of VTK).
 
440
 
 
441
``examples/README.txt`` contains some information on the recommended
 
442
ways to script and some additional information.
 
443
 
 
444
 
 
445
 
 
446
Using the mayavi envisage plugins
 
447
---------------------------------
 
448
 
 
449
The mayavi related plugin definitions to use are:
 
450
 
 
451
  * ``mayavi_plugin_definition.py``
 
452
  * ``mayavi_ui_plugin_definition.py``
 
453
 
 
454
These are in the ``enthought.mayavi`` package.  To see an example of
 
455
how to use this see the ``enthought.mayavi.plugin_definitions``
 
456
module and the ``enthought.mayavi.app`` module.
 
457
 
 
458
If you are writing Envisage plugins for an application and desire to
 
459
use the mayavi plugins from your plugins/applications then it is
 
460
important to note that mayavi creates three application objects for
 
461
your convenience.  These are:
 
462
 
 
463
  * ``enthought.mayavi.services.IMAYAVI``: This is an
 
464
    ``enthought.mayavi.script.Script`` instance that may be used to
 
465
    easily script mayavi.  It is a simple wrapper object that merely
 
466
    provides some nice conveniences while scripting from the UI.  It
 
467
    has an ``engine`` trait that is a reference to the running mayavi
 
468
    engine.
 
469
 
 
470
  * ``enthought.mayavi.services.IMAYAVI_ENGINE``: This is the running
 
471
    mayavi engine instance.
 
472
 
 
473
  * ``enthought.mayavi.services.IMAYAVI_ENGINE_VIEW``:  This is the
 
474
    view of the engine and is only exposed if the
 
475
    ``mayavi_ui_plugin_definition.py`` is used.
 
476
 
 
477
A simple example that demonstrates the use of the mayavi plugin in an
 
478
envisage application is included in the ``examples/explorer``
 
479
directory.  This may be studied to understand how you may do the same
 
480
in your envisage applications.
 
481
 
 
482
 
 
483
 
 
484
..
 
485
   Local Variables:
 
486
   mode: rst
 
487
   indent-tabs-mode: nil
 
488
   sentence-end-double-space: t
 
489
   fill-column: 70
 
490
   End:
 
491