3D quiver plotΒΆ

This is a comparison to the 3D quiver plot Matplotlib example.

../../_images/mp_quiver.png
import numpy as np
from matplotlib import pyplot as plt
import s3dlib.surface as s3d

#.. Matplotlib Examples: 3D quiver plot

# 1. Define function to examine ....................................
# +----------------------------------------------------------------------------
# |  The following code between the ========= comments was copied DIRECTLY from
# |  https://matplotlib.org/stable/gallery/mplot3d/quiver3d.html#sphx-glr-gallery-mplot3d-quiver3d-py
# |
# +----------------------------------------------------------------------------
# ===================================================== start of copy.
# Make the grid
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.8))

# Make the direction data for the arrows
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
     np.sin(np.pi * z))
# ===================================================== end of copy.
# ..... reshape data to N x 3 ......................
location = np.reshape(np.array( [x,y,z] ).T,(-1,3))
vector = np.reshape(np.array( [u,v,w] ).T,(-1,3))
vector *= 0.15

# 2. Setup and map vectors ........................................

vf = s3d.Vector3DCollection(location,vector)

# 3. Construct figure, add surface, and plot ......................

fig = plt.figure(figsize=plt.figaspect(0.92))
fig.text(0.975,0.975,str(vf),
    ha='right', va='top', fontsize='smaller', multialignment='right')
ax = plt.axes(projection='3d', aspect='equal')
minmax = (-0.85,0.85)
ax.set(xlim=minmax, ylim=minmax, zlim=minmax )

ax.add_collection3d(vf)
plt.show()

Colormapping vector fields may enhance the visual interpretation in 3D. Considering a denser distribution of the above data, i.e:

x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2))

Producing the plot

../../_images/mp_quiver_dense.png

This is similar to the above data set but is visually noisy. Color mapping can reveal patterns when color is based on just the vector magnitude, direction or a color mapping function. See the Magnitude and Direction Visualization example.

../../_images/quiver_mdo.png
import numpy as np
from matplotlib import pyplot as plt
import s3dlib.surface as s3d
import s3dlib.cmap_utilities as cmu

# 1. Define function to examine ....................................
# Make the grid
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2))
#                      np.arange(-0.8, 1, 0.8))

# Make the direction data for the arrows
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
     np.sin(np.pi * z))

# ..... reshape data to N x 3 ......................
location = np.reshape(np.array( [x,y,z] ).T,(-1,3))
vector = np.reshape(np.array( [u,v,w] ).T,(-1,3))
vector *= 0.4

def from_origin(xyz,uvw) :
    x,y,z = xyz
    return np.sqrt(x*x + y*y + z*z)

# 2. Setup and map vectors ........................................

fields = []

vf = s3d.Vector3DCollection(location,vector,alr=0.4)
vf.map_cmap_from_magnitude()
fields.append(vf)

vf = s3d.Vector3DCollection(location,vector,alr=0.4)
vf.map_cmap_from_direction()
fields.append(vf)

vf = s3d.Vector3DCollection(location,vector,alr=0.4)
vf.map_cmap_from_op(from_origin)
fields.append(vf)

# 3. Construct figure, add surface, and plot ......................

fig = plt.figure(figsize=(12,4),facecolor='w')
axPos = 131
minmax = (-1,1)
for vf in fields :
    ax = fig.add_subplot(axPos, projection='3d', facecolor='k', aspect='equal')
    ax.set_axis_off()
    ax.set(xlim=minmax, ylim=minmax, zlim=minmax )
    ax.set_title(vf.cname, color='w')
    ax.add_collection3d(vf)
    axPos += 1

fig.tight_layout(pad=2)

plt.show()