Using python and mayavi to create a 3D stream

It is now quite simple to create a 2D stream using python and matplotlib because streamplot was recently included in matplotlib by Tom Flannagan and Tony U.

Although you can create certain types of 3D plots with matplotlib, 3D streams are not currently supported. However, the python plotting mayavi program (which provides the vtk-based python interface) is able to create 3D streams using the flow () function .

I created a simple python module for streaming data in 2D and 3D without a Z-slope (all dZ = 0) in a 3D data set to demonstrate the graphing problem that I faced with Mayavi versus matplotlib by effectively matching data in the xy plane . The commented code and the resulting graphs are shown below:

import numpy, matplotlib, mayavi, matplotlib.pyplot, mayavi.mlab
#for now, let produce artificial streamline data sets for 2D & 3D cases where x and y change by +1 at each point, while Z changes by 0 at each point:

#2D data first:
x = numpy.ones((10,10))
y = numpy.ones((10,10))
#and a corresponding meshgrid:
Y,X = numpy.mgrid[-10:10:10j,-10:10:10j]

#now 3D data with Z = 0 (i.e., I want to be able to produce a matching streamplot plane in mayavi, which is normally used for 3D):
xx = numpy.ones((10,10,10))
yy = numpy.ones((10,10,10))
zz = numpy.zeros((10,10,10))
#and a corresponding meshgrid:
ZZ,YY,XX = numpy.mgrid[-10:10:10j,-10:10:10j,-10:10:10j]

#plot the 2D streamplot data with matplotlib:
fig = matplotlib.pyplot.figure()
ax = fig.add_subplot(111,aspect='equal')
speed = numpy.sqrt(x*x + y*y)
ax.streamplot(X, Y, x, y, color=x, linewidth=2, cmap=matplotlib.pyplot.cm.autumn,arrowsize=3)
fig.savefig('test_streamplot_2D.png',dpi=300)

#there no streamplot 3D available in matplotlib, so try to see how mayavi behaves with a similar 3D data set:
fig = mayavi.mlab.figure(bgcolor=(1.0,1.0,1.0),size=(800,800),fgcolor=(0, 0, 0))
st = mayavi.mlab.flow(XX,YY,ZZ,xx,yy,zz,line_width=4,seedtype='sphere',integration_direction='forward') #sphere is the default seed type
mayavi.mlab.axes(extent = [-10.0,10.0,-10.0,10.0,-1.0,1.0]) #set plot bounds
fig.scene.z_plus_view() #adjust the view for a perspective along z (xy plane flat)
mayavi.mlab.savefig('test_streamplot_3D_attempt_1.png')

#now start to modify the mayavi code to see if I can 'seed in' more streamlines (default only produces a single short streamline, albeit of the correct slope)
#attempt 2 uses a line seed / widget over the specified bounds (points 1 and 2):
fig = mayavi.mlab.figure(bgcolor=(1.0,1.0,1.0),size=(800,800),fgcolor=(0, 0, 0))
st = mayavi.mlab.flow(XX,YY,ZZ,xx,yy,zz,line_width=4,seedtype='line',integration_direction='forward') #line instead of sphere
st.seed.widget.point1 = [0,-10,0]
st.seed.widget.point2 = [0,10,0] #so seed line should go up along y axis
st.seed.widget.resolution = 25 #seems to be the number of seeds points along the seed line
mayavi.mlab.axes(extent = [-10.0,10.0,-10.0,10.0,-1.0,1.0]) #set plot bounds
fig.scene.z_plus_view() #adjust the view for a perspective along z (xy plane flat)
mayavi.mlab.savefig('test_streamplot_3D_attempt_2.png')

#attempt 3 will try to seed a diagonal line across the plot to produce streamlines that cover the full plot:
#would need to use 'both' for integration_direction if I could get the diagonal seed line to work
fig = mayavi.mlab.figure(bgcolor=(1.0,1.0,1.0),size=(800,800),fgcolor=(0, 0, 0)) 
st = mayavi.mlab.flow(XX,YY,ZZ,xx,yy,zz,line_width=4,seedtype='line',integration_direction='forward') 
st.seed.widget.point1 = [-10,10,0] #start seed line at top left corner of plot
st.seed.widget.point2 = [10,-10,0] #end seed line at bottom right corner of plot 
#this fails to produce a diagonal seed line though
st.seed.widget.resolution = 25 #seems to be the number of seeds points along the seed line
mayavi.mlab.axes(extent = [-10.0,10.0,-10.0,10.0,-1.0,1.0]) #set plot bounds
fig.scene.z_plus_view() #adjust the view for a perspective along z (xy plane flat)
mayavi.mlab.savefig('test_streamplot_3D_attempt_3.png')

2D matplotlib ( , 1 dx dy, ): 2D matplotlib streamplot 3D mayavi ( 1; ) , , , , , , 2D matplotlib): enter image description here 3D mayavi ( 2; ) , , , - , ) enter image description here , β„–3 () , # 2, /. , , , ? , 3D- (), .

, , :

  • matplotlib streamplot Tom Flannaghan
  • , Mayavi Streamline (, , ( )), , , .
  • , , 2D- .
  • 3D, :
  • flow() , Mayavi ( , ).
+4
1

, , - linux clamp_to_bounds True. False, .

st.seed.widget.clamp_to_bounds = False

, :

Final result

, , , :

Mayavi, IPython pylab. Ubuntu :

ipython --pylab=qt

IPython script % run magic:

%run streamlines.py

, , Mayavi Mayavi, Mayavi:

enter image description here

Streamline, , "Seed", "Clamp to bounds". ( - Mayavi - ...)

enter image description here

, , enter image description here, , , :

enter image description here

clamp_to_bounds script.

!

+5

All Articles