~ubuntu-branches/debian/sid/mayavi2/sid

« back to all changes in this revision

Viewing changes to docs/source/mayavi/building_applications.rst

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2009-03-27 04:34:55 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090327043455-vs6ox32daj6ndw33
Tags: 3.2.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
Building applications using Mayavi
 
3
===================================
 
4
 
 
5
.. topic:: Section summary
 
6
 
 
7
    This section describes how Mayavi can be used as a scientific data
 
8
    visualization and 3D plotting tool in interactive application.
 
9
 
 
10
Mayavi can be used as a fully integrated and interactive 3D plotting tool 
 
11
in a GUI application. Using the event model behind Traits and TVTK, all
 
12
the different properties of a visualization can be changed dynamically,
 
13
including the data visualized itself.
 
14
 
 
15
In this section, we first show how an interactive dialog embedding a
 
16
Mayavi scene can be built, using `Traits`. Then we show how to integrate
 
17
this dialog in a WxPython or a PyQt application.
 
18
 
 
19
Custom interactive dialogs
 
20
--------------------------
 
21
 
 
22
Mayavi and TVTK are entirely built using the Traits library which provide
 
23
easy callbacks and visualization for objects attribute. All the different
 
24
properties of the pipeline and pipeline objects are expressed as Traits,
 
25
ie special attributes that can be visualized in dialogs, and that fire
 
26
callbacks when they are modified. In particuler this means that when a
 
27
visualization object is modified, the scene can update automatically.
 
28
 
 
29
We strongly suggest that you refer to the `Traits` 
 
30
`documentation <http://code.enthought.com/projects/traits.documentation.php>`_
 
31
for more details, and to the 
 
32
`tutorial <http://code.enthought.com/projects/traits/docs/html/tutorials/traits_ui_scientific_app.html>`_
 
33
for a quick introduction.
 
34
 
 
35
Embedding a Mayavi scene in a Traits dialog
 
36
............................................
 
37
 
 
38
To build a custom dialog with a Mayavi scene, the best option is to
 
39
create a class deriving from the base `Traits` class. A special
 
40
attribute, called SceneModel can be used as an attribute to represent a
 
41
Mayavi scene that can accept objects. This defines the `model`, ie the
 
42
main `HasTraits` object in which the application logics is contained.
 
43
 
 
44
A view of this object, as a dialog, can be created using the
 
45
`.configure_traits` method of this object. If a view is explicitely
 
46
specified the embedded Mayavi scene can be represented with the usual
 
47
widget for scene by specifying for it the `SceneEditor`::
 
48
 
 
49
    from enthought.traits.api import HasTraits, Instance
 
50
    from enthought.traits.ui.api import View, Item
 
51
    from enthought.tvtk.pyface.scene_model import SceneModel
 
52
    from enthought.tvtk.pyface.scene_editor import SceneEditor
 
53
 
 
54
    class MyModel(HasTraits):
 
55
        scene = Instance(SceneModel, ())
 
56
 
 
57
        view = View(Item('scene', height=400, show_label=False,
 
58
                        editor=SceneEditor()))
 
59
 
 
60
    MyModel().configure_traits()
 
61
    
 
62
A `Mayavi` button to pop up the pipeline dialog can be added on the
 
63
toolbar by specifying a different scene view to the `SceneEditor`::
 
64
 
 
65
    from enthought.mayavi.core.ui.mayavi_scene import MayaviScene
 
66
 
 
67
    #...
 
68
    editor=SceneEditor(scene_class=MayaviScene)
 
69
    #...
 
70
 
 
71
The ``mayavi_traits_ui.py`` example is a fairly comprehensive example that
 
72
demonstrates how you can embed almost the entire mayavi UI into your traits
 
73
based UI. mlab based visualization.
 
74
 
 
75
A scene, with `mlab` embedded
 
76
..............................
 
77
 
 
78
An object representing a scene is interesting only if you can visualize
 
79
data with the scene. For this we can instanciate an `Engine` and assign
 
80
it to the scene. Having an `Engine` only for one scene allows us to
 
81
confine action and visualization objects only to this scene. 
 
82
 
 
83
We can also use an `MlabSceneModel` instance, rather than a `SceneModel`,
 
84
imported from `enthought.mayavi.tools.mlab_scene_model`. This scene model
 
85
has an embedded `mlab` attribute, that exposes all the mlab commands (see
 
86
:ref:`mlab_plotting_functions`) as attributes, applying on the scene. For
 
87
instance plotting 3D points can be achieved with
 
88
`self.scene.mlab.points3d(x, y, z, s)`.
 
89
 
 
90
Making the visualization live
 
91
..............................
 
92
 
 
93
Having an interactive application is interesting only if you can do
 
94
custom, domain-specific, interaction with the visualization. 
 
95
 
 
96
An important use case is modifying the data visualized as a parameter is
 
97
changed interactively. For this we can use the inplace modification of
 
98
the data of an mlab object, as for animation of an mlab plot (see
 
99
:ref:`mlab-animating-data`). Suppose we are plotting a line curve defined
 
100
by a function of two parameters::
 
101
    
 
102
    from numpy import linspace, pi, cos, sin
 
103
 
 
104
    def curve(n_mer, n_long):
 
105
        phi = linspace(0, 2*pi, 2000)
 
106
        return [ cos(phi*n_mer) * (1 + 0.5*cos(n_long*phi)),
 
107
                sin(phi*n_mer) * (1 + 0.5*cos(n_long*phi)),
 
108
                0.5*sin(n_long*phi),
 
109
                sin(phi*n_mer)]
 
110
 
 
111
Using `mlab`, we could plot the curve with `plot3d`::
 
112
 
 
113
    x, y, z, s = curve(4, 6)
 
114
    from enthought.mayavi import mlab
 
115
    plot = mlab.plot3d(x, y, z, s)
 
116
 
 
117
Modifying the plot for new parameters could be written::
 
118
 
 
119
    x, y, z, t = curve(4, 8)
 
120
    plot.mlab_source.set(x=x, y=y, z=z, scalars=t)
 
121
 
 
122
In a dialog, this would be::
 
123
 
 
124
    from enthought.traits.api import HasTraits, Range, Instance, \
 
125
                        on_trait_change
 
126
    from enthought.traits.ui.api import View, Item, HGroup
 
127
    from enthought.tvtk.pyface.scene_editor import SceneEditor
 
128
    from enthought.mayavi.tools.mlab_scene_model import \
 
129
                        MlabSceneModel
 
130
    from enthought.mayavi.core.ui.mayavi_scene import MayaviScene
 
131
 
 
132
 
 
133
    class Visualization(HasTraits):
 
134
        meridional = Range(1, 30,  6)
 
135
        transverse = Range(0, 30, 11)
 
136
        scene      = Instance(MlabSceneModel, ())
 
137
 
 
138
        def __init__(self):
 
139
            # Do not forget to call the parent's __init__
 
140
            HasTraits.__init__(self)
 
141
            x, y, z, t = curve(self.meridional, self.transverse)
 
142
            self.plot = self.scene.mlab.plot3d(x, y, z, t, 
 
143
                                            colormap='Spectral')
 
144
 
 
145
        @on_trait_change('meridional,transverse')
 
146
        def update_plot(self):
 
147
            x, y, z, t = curve(self.meridional, self.transverse)
 
148
            self.plot.mlab_source.set(x=x, y=y, z=z, scalars=t)
 
149
 
 
150
        view = View(Item('scene', height=400, show_label=False,
 
151
                    editor=SceneEditor(scene_class=MayaviScene)),
 
152
                    HGroup('meridional', 'transverse'))
 
153
 
 
154
    visualization = Visualization()
 
155
    visualization.configure_traits()
 
156
 
 
157
A complete, runnable, code based on the above comments is given by the 
 
158
``mlab_traits_ui.py`` example.
 
159
 
 
160
 
 
161
Integrating in a WxPython application
 
162
--------------------------------------
 
163
 
 
164
Using the `Visualization` class defined above::
 
165
 
 
166
    import wx
 
167
 
 
168
    class MainWindow(wx.Frame):
 
169
        def __init__(self, parent, id):
 
170
            wx.Frame.__init__(self, parent, id, 'Mayavi in Wx')
 
171
            self.visualization = Visualization()
 
172
            self.control = self.visualization.edit_traits(parent=self,
 
173
                                    kind='subpanel').control
 
174
            self.Show()
 
175
 
 
176
    app = wx.PySimpleApp()
 
177
    frame = MainWindow(None, wx.ID_ANY)
 
178
    app.MainLoop()
 
179
 
 
180
 
 
181
Integrating in a PyQt application
 
182
----------------------------------
 
183
 
 
184
Before defining the `Visualization` class::
 
185
 
 
186
    import os
 
187
    os.environ['ETS_TOOLKIT'] = 'qt4'
 
188
 
 
189
And using this class::
 
190
 
 
191
    from PyQt4 import QtGui
 
192
 
 
193
    class MainWindow(QtGui.QMainWindow):
 
194
        def __init__(self, parent=None):
 
195
            QtGui.QWidget.__init__(self, parent)
 
196
            self.visualization = Visualization()
 
197
            self.ui = self.visualization.edit_traits().control
 
198
            self.setCentralWidget(self.ui)
 
199
 
 
200
    window = MainWindow() 
 
201
    window.show()
 
202
    QtGui.qApp.exec_()
 
203
 
 
204
 
 
205
 
 
206