http://www.sam.math.ethz.ch/~raoulb/teaching/PythonTutorial/tips_mayavi2.html
Mayavi2
Mayavi2 seeks to provide easy and interactive visualization of 3-D data. It offers:
- An (optional) rich user interface with dialogs to interact with all data and objects in the visualization.
- A simple and clean scripting interface in Python, including one-liners, or an object-oriented programming interface.
- The power of the VTK toolkit, harnessed through these interfaces, without forcing you to learn it.
Additionally Mayavi2 is a reusable tool that can be embedded in your applications in different ways or combined with the Envisage application-building framework to assemble domain-specific tools.
TVTK
TVTK wraps VTK objects to provide a convenient, Pythonic API, while supporting Traits attributes and NumPy/SciPy arrays. TVTK is implemented mostly in pure Python, except for a small extension module.
Developers typically use TVTK to write Mayavi modules, and then use Mayavi to interact with visualizations or create applications.
Prerequisites
You must have the following libraries installed before installing the Mayavi project:
Mayavi2 tips
The enthought.mayavi.mlab module, that we call mlab, provides an easy way to visualize data in a script or from an interactive prompt with one-liners as done in the matplotlib pylab interface but with an emphasis on 3D visualization using Mayavi2. This allows users to perform quick 3D visualization while being able to use Mayavi’s powerful features.
Warning
When using IPython with mlab, as in the following examples, IPython must be invoked with the -wthread command line option like so:
$ ipython -wthread
If you are using the Enthought Python Distribution, the Pylab menu entry will start ipython with the right switch.
Try:
In [1]: from enthought.mayavi import mlab
In [2]: mlab.test_[TAB]
In [3]: mlab.test_contour3d??
In [4]: mlab.test_contour3d()
Out[4]: <enthought.mayavi.modules.iso_surface.IsoSurface object at 0x7fb8e8646b30>
In [5]: import numpy as np
In [6]: t = np.linspace(0, 2*np.pi, 50)
In [7]: u = np.cos(t)*np.pi
In [8]: x, y, z = np.sin(u), np.cos(u), np.sin(t)
In [9]: mlab.clf()
In [10]: mlab.points3d(x,y,z)
In [11]: mlab.clf()
In [12]: mlab.points3d(x,y,z,t, scale_mode='none')
In [13]: mlab.points3d?
In [23]: x, y = np.mgrid[-3:3:100j, -3:3:100j ]
In [24]: z = np.sin(x*x + y*y)
In [25]: mlab.clf()
In [26]: mlab.surf(x,y,z)
In [28]: mlab.mesh(x,y,z)
A simple example showing a 3D plot done with the help of mayavi2. The following code shows what it takes to produce such an image. The plotting is essentially only two lines of code!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from numpy import mgrid, real, conj, ones, zeros
from numpy.fft.fftpack import fft2
from numpy.fft.helper import fftshift
from enthought.mayavi import mlab
# A mesh grid
X,Y = mgrid[-100:100, -100:100]
# The initial function: a 2D unit step
Z = zeros((200,200))
Z[0:6,0:6] = 0.3*ones((6,6))
# The fourier transform: a 2D sinc(x,y)
W = fftshift(fft2(Z))
W = real(conj(W)*W)
# Display the data with mayavi
# Plot the original function
#mlab.mesh(X, Y, Z)
# Plot the fourier transformed function
mlab.mesh(X, Y, W)
mlab.savefig("mayavi_fft_plot.png")
|
And now an animated example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
'''Progam menat to test funcyionality of scipy, mayavi2 and matplotlib
to be run either with
mayavi2 -x testy.py
or
ipython -pylab -wthread
run testy.py
'''
from enthought.mayavi import mlab
from scipy import sin, ogrid, array
from pylab import plot, show
# prepare data, hence test scipy elements
x , y = ogrid[-3:3:100j , -3:3:100j]
z = sin(x**2 + y**2)
# test matplotlib
plot(x, sin(x**2)); show()
#now mayavi2
#mlab.options.offscreen = True
obj=mlab.surf(x,y,z)
P = mlab.pipeline
scalar_cut_plane = P.scalar_cut_plane(obj,
plane_orientation='y_axes',
)
scalar_cut_plane.enable_contours = True
scalar_cut_plane.contour.filled_contours = True
scalar_cut_plane.implicit_plane.widget.origin = array([ 0.00000000e+00, 1.46059210e+00, -2.02655792e-06])
scalar_cut_plane.warp_scalar.filter.normal = array([ 0., 1., 0.])
scalar_cut_plane.implicit_plane.widget.normal = array([ 0., 1., 0.])
## mlab.draw()
f = mlab.gcf()
f.scene.camera.azimuth(10)
f.scene.show_axes = True
f.scene.magnification = 4 # or 4
mlab.axes()
#engine=mlab.getengine()
## mlab.draw()
# Now animate the data.
dt = 0.01; N = 40
ms = obj.mlab_source
for k in xrange(N):
x = x + k*dt
scalars = sin(x**2 + y**2)
ms.set(x=x, scalars=scalars)
|
The next example demonstrates how to use scalar cut planes in order to evidence subtle characteristics of a plot. Here, we would like to show the Gibbs oscillations in the Fourier series approximation of jumps.
-
The workflow for such a problem is:
-
- write a simple program (let us call it pl.py) that plots your object
- run mayavi2 -x pl.py (python pl.py works too for just executing the script)
- use the ‘spion’ of mayavi2: click on the red point in the menu: the protocol of everything you do visually with the mouse is python-scripted in the opened window
- play with the possibilities and variables that mayavi2 offers, till the image that you see satisfies your exigences
- copy from the ‘spion’-window the relevant information for your result into your pl.py file
- save the picture, if you wish; CAUTION: the pictures that mayavi2 produces became huge, if saved in vector graphics ... so eps is not recommeded here!
- re-run mayavi2 -x pl.py to see if this is really what you wanted
- iterate the above process, if wished
- improve speed and quality of the plot by avoiding rendering and increasing size
In the following code (that was developped following this receipt) you find hints for your formulations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
from numpy import mgrid, zeros, sin, pi, array
from enthought.mayavi import mlab
Lx = 4
Ly = 4
S = 10
dx = 0.05
dy = 0.05
# A mesh grid
X,Y = mgrid[-S:S:dx, -S:S:dy]
# The initial function:
#Z = zeros(X.shape)
#Z = sin(pi*X/Lx)*sin(pi*Y/Ly)
#Z[Z>0] = 1
#Z[Z<0] = -1
# The Fourier series:
W = zeros(X.shape)
m = 10
for i in xrange(1,m,2):
for j in xrange(1,m,2):
W += 1.0 / (i*j) * sin(i * pi * X / Lx) * sin(j * pi * Y / Ly)
W *= pi / 4.0
# prepare scene
scene = mlab.gcf()
# next two lines came at the very end of the design
scene.scene.off_screen_rendering = True # quicker execution because no redenring
scene.scene.magnification = 4
# plot the object !
obj = mlab.mesh(X, Y, W)
P = mlab.pipeline
# first scalar_cut_plane
scalar_cut_plane = P.scalar_cut_plane(obj,
plane_orientation='z_axes',
)
scalar_cut_plane.enable_contours = True
scalar_cut_plane.contour.filled_contours = True
# where ?
scalar_cut_plane.implicit_plane.widget.origin = array([-0.025, -0.025, 0.48])
scalar_cut_plane.warp_scalar.filter.normal = array([ 0., 0., 1.])
scalar_cut_plane.implicit_plane.widget.normal = array([ 0., 0., 1.])
scalar_cut_plane.implicit_plane.widget.enabled = False # do not show the widget
# second scalar_cut-plane
scalar_cut_plane_2 = P.scalar_cut_plane(obj,
plane_orientation='z_axes',
)
scalar_cut_plane_2.enable_contours = True
scalar_cut_plane_2.contour.filled_contours = True
# where ?
scalar_cut_plane_2.implicit_plane.widget.origin = array([-0.025, -0.025, -0.48])
scalar_cut_plane_2.warp_scalar.filter.normal = array([ 0., 0., 1.])
scalar_cut_plane_2.implicit_plane.widget.normal = array([ 0., 0., 1.])
scalar_cut_plane_2.implicit_plane.widget.enabled = False # do not show the widget
# see it from a closer view point
scene.scene.camera.position = [-31.339891336951567, 14.405281950904936, -27.156389988308661]
scene.scene.camera.focal_point = [-0.025000095367431641, -0.025000095367431641, 0.0]
scene.scene.camera.view_angle = 30.0
scene.scene.camera.view_up = [0.63072643330371414, -0.083217283169475589, -0.77153033000256477]
scene.scene.camera.clipping_range = [4.7116394000124906, 93.313165745624019]
scene.scene.camera.compute_view_plane_normal()
#scene.scene.render() # commented out at the end, we do not want to render anything
mlab.savefig("mayavi_fourier_series_plot.png")
#mlab.show()
|