Reputation: 509
I want to plot a 3d velocity vector field using a 3d quiver plot in python, from 3 data files (.npy) that give u, v and w components of velocity in the x, y and z directions. This what I have done so far, showing the error message as well. How do I create a 3d quiver plot from three 3d .npy data files? I have also looked at other examples here and here. The code below was adapted from the 2d quiver plot example from here.
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.pyplot import figure
from mpl_toolkits.mplot3d import proj3d
c1 = 1
nx, ny, nz = 284, 160, 160
x1 = range(nx)
y1 = range(ny)
z1 = range(nz)
U = np.load("u.npy") # 3d array file
V = np.load("v.npy") # 3d array file
W = np.load("w.npy") # 3d array file
X1, Y1, Z1 = np.meshgrid(x1, y1, z1)
fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')
ax.set_title("pivot='mid'; every 10th arrow; units='velocity vector' time=" + str(c1))
Q = ax.quiver(X1[::10, ::10], Y1[::10, ::10], Z1[::10, ::10], U[::10, ::10],
V[::10, ::10], W[::10, ::10], pivot='mid', units='inches')
#Not sure if it should be formatted as below:
#Q = ax.quiver(X1[::10, ::10, ::10], Y1[::10, ::10, ::10], Z1[::10, ::10, ::10], U[::10, ::10, ::10],
#V[::10, ::10, ::10], W[::10, ::10, ::10], pivot='mid', units='inches')
qk = ax.quiverkey(Q, 0.9, 0.9, 5, r'$1 \frac{m}{s}$', labelpos='E', coordinates='figure') #possibly for 2D (X, Y) only.
ax.scatter(X1[::10, ::10], Y1[::10, ::10], Z1[::10, ::10], color='c', s=0)
plt.tight_layout()
plt.savefig('3D_video_velocity_' + str(c1) + '.png')
Error message:
$ python3 test_3d_quiver_plot_1a.py
Traceback (most recent call last):
File "test_3d_quiver_plot_1a.py", line 69, in <module>
Q = ax.quiver(X1[::10, ::10], Y1[::10, ::10], Z1[::10, ::10], U[::10, ::10],
File "/home/brendan/.local/lib/python3.8/site-packages/mpl_toolkits/mplot3d/axes3d.py", line 2628, in quiver
bcast = np.broadcast_arrays(*input_args, *masks)
File "<__array_function__ internals>", line 5, in broadcast_arrays
File "/home/brendan/.local/lib/python3.8/site-packages/numpy/lib/stride_tricks.py", line 264, in broadcast_arrays
shape = _broadcast_shape(*args)
File "/home/brendan/.local/lib/python3.8/site-packages/numpy/lib/stride_tricks.py", line 191, in _broadcast_shape
b = np.broadcast(*args[:32])
ValueError: shape mismatch: objects cannot be broadcast to a single shape
The result should look something like this:
Upvotes: 0
Views: 642
Reputation: 509
I found the following code produced a 3d quiver plot from 3 data files (3d arrrays in .npy files). The code was adapted from @tacaswell.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
nx, ny, nz = 160, 284, 160
x1 = range(nx)
y1 = range(ny)
z1 = range(nz)
u = np.load("u.npy")
v = np.load("v.npy")
w = np.load("w.npy")
fig = plt.figure(figsize=(10,10))
ax = fig.gca(projection='3d')
x, y, z = np.meshgrid(x1, y1, z1)
# 3d quiver plot for every 5th data point
ax.quiver(x[::5, ::5], y[::5, ::5], z[::5, ::5], u[::5, ::5],
v[::5, ::5], w[::5, ::5], length=0.1, color = 'red', lw=2)
plt.show()
The resultant 3d quiver plot is shown here (I haven't worked out how make the arrows larger yet):
Upvotes: 0
Reputation: 13150
Based on the above comment, to create a 3D quiver plot X1, Y1, Z1, U, V, W
must have the same shape.
Try to modify the following lines of code:
import numpy as np
nx, ny, nz = 160, 284, 160
x1 = range(nx)
y1 = range(ny)
z1 = range(nz)
X1, Y1, Z1 = np.meshgrid(x1, y1, z1)
Note that I changed nx, ny, nz = 284, 160, 160
to nx, ny, nz = 160, 284, 160
. This should give X1, Y1, Z1
the correct shape.
Upvotes: 1