Vector SurfacesΒΆ

../../_images/vmag_surface.png

Using the vector field shown in the Magnitude and Direction Visualization example, surfaces of constant vector magnitude are shown on the left. On the right, surfaces are shown for contant component of the vector field in the [1,1,1] direction (dot product values).

The magnitude surface plot is similar to that found at Mayavi vector field .

import numpy as np
import matplotlib.pyplot as plt
import s3dlib.surface as s3d
import matplotlib.patches as mpatches

#.. Vector magnitude and direction surfaces

# 1. Define functions to examine ....................................

def getVect(xyz) :
    x,y,z = xyz
    u =    np.sin(np.pi*x) * np.cos(np.pi*z)
    v = -2*np.sin(np.pi*y) * np.cos(2*np.pi*z)
    w = np.cos(np.pi*x)*np.sin(np.pi*z) + np.cos(np.pi*y)*np.sin(2*np.pi*z)
    return np.array([u,v,w]).T

def vector_mag(xyz) :
    return np.linalg.norm(getVect(xyz),axis=3).T

def vector_dot(xyz) :
    direction = [1,1,1]
    incidentDir = np.divide( direction, np.linalg.norm(direction) )
    return np.dot(getVect(xyz),incidentDir).T

# 3. Construct figure, add surface, and plot ......................
rez,dmn,col = 2, [0, 1], ['gold', 'greenyellow' ,'cyan']
params = [ [ 'Magnitude',          vector_mag, [1.9,1.2,0.5] ] ,
           [ 'Direction, [1,1,1]', vector_dot, [ 1, 0,  -1 ] ]   ]

fig = plt.figure(figsize=(8,4),facecolor='w')
minmax = (0,1)
for i,pms  in enumerate(params) :
    title, vectFunc, mVal =  pms   # set parmeters to the specific visualization.     
    ax = fig.add_subplot(121+i, projection='3d', aspect='equal', focal_length=0.25)
    ax.view_init(0,-120)
    ax.set(xlim=minmax, ylim=minmax, zlim=minmax, title=title,
           xlabel='X',  ylabel='Y',  zlabel='Z' )
    patch_0 = mpatches.Patch(label=str(mVal[0]), color=col[0] )
    patch_1 = mpatches.Patch(label=str(mVal[1]), color=col[1] )
    patch_2 = mpatches.Patch(label=str(mVal[2]), color=col[2] )
    ax.legend(handles=[patch_0,patch_1,patch_2])

    # 2. Setup and map surfaces .................
    surf0 = s3d.Surface3DCollection.implsurf( vectFunc,rez,dmn,mVal[0],color=col[0] )
    surf1 = s3d.Surface3DCollection.implsurf( vectFunc,rez,dmn,mVal[1],color=col[1] )
    surf2 = s3d.Surface3DCollection.implsurf( vectFunc,rez,dmn,mVal[2],color=col[2] )
    surface = surf0+surf1+surf2
    surface.evert().triangulate(3)

    ax.add_collection3d(surface.shade(.4,flat=False))

    #  front edge lines, coordinates/indices
    vE,iE = [ [1,0,1], [0,0,1], [0,1,1], [0,0,0] ], [ [0,1,2],[1,3]]
    ax.add_collection3d( s3d.ColorLine3DCollection(vE,iE,color='0.5',lw=1) )

fig.tight_layout(pad=2)
plt.show()