Skip to content
Advertisement

making a 3D quiver plot using matplotlib by reading in data

I am trying to make a 3D quiver plot using matplotlib 2.2.5. I provide a simple sample code below to show my attempt. I want to make a quiver plot using fx(x,y,z), fy(x,y,z) and fz(x,y,z). These correspond to the vector field f = (fx,fy,fz). I input the data for fx,fy,fz as 3 .dat files where each .dat file is 1 column of numbers.

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt #I'm using matplotlib 2.2.5
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

fx = np.genfromtxt('fx.dat')
fy = np.genfromtxt('fy.dat')
fz = np.genfromtxt('fz.dat')

N = 10
Fx = fx[::N,::N]
Fy = fy[::N,::N]
Fz = fz[::N,::N]

nrows, ncols = Fx.shape
nx = 1
ny = 1
nz = 1

x = np.linspace(-nx, nx, ncols)
y = np.linspace(-ny, ny, ncols)
z = np.linspace(-nz, nz, ncols)
xi, yi, zi = np.meshgrid(x, y, z, indexing='ij')

plt.quiver(xi, yi, zi, Fx, Fy, Fz, edgecolor='k', facecolor='black', linewidth=.5)

plt.axis('scaled')
plt.show()

The data is generated and stored as follows (using fortran):

!generate data
DO i = -nx,nx !nx = 1
  DO j = -ny,ny !ny = 1
     DO k = -nz,nz !nz = 1
       fx(i,j,k) = i + 2.*j  + 3.*k  !this is a function fx that depends on x,y,z; fx(x,y,z)
       fy(i,j,k) = i - 4.*j  + k !this is a function fy that depends on x,y,z; fy(x,y,z)
       fz(i,j,k) = i + 2*j + k !this is a function fz that depends on x,y,z; fz(x,y,z)
     END DO
  END DO
END DO

!store data
DO i = -nx,nx
   DO j = -ny,ny
      DO k = -nz,nz
        WRITE(1,*) fx(i,j,k) !stores fx(x,y,z)
        WRITE(2,*) fy(i,j,k) !stores fy(x,y,z)
        WRITE(3,*) fz(i,j,k) !stores fz(x,y,z)
      END DO
   END DO
END DO

Advertisement

Answer

I’m assuming here you are trying to plot the quivers starting from the (origin (0,0,0)).

Using a random sample with coordinates between -1 and 1 (hoping it will match your data sample), this would go this way:

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')

fx = np.genfromtxt('fx.dat')
fy = np.genfromtxt('fy.dat')
fz = np.genfromtxt('fz.dat')

N = 10
Fx = fx[:N]
Fy = fy[:N]
Fz = fz[:N]

Note that I used a simple “:”: based on your explanation, your .dat files have only one dimension. You use multiples colon only if you have at least 2 dimensions.

plt.quiver(0, 0, 0, Fx, Fy, Fz, edgecolor='k', facecolor='black', linewidth=.5) #To plot starting from the origin

ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
ax.set_zlim(-1,1)

plt.show()

If you want to plot starting from your mesh (ie np.linspace), you can alter the code as follow (though I’m not sure this is what you are trying to achieve):

nx = 1
ny = 1
nz = 1
x = np.linspace(-nx, nx, N)
y = np.linspace(-ny, ny, N)
z = np.linspace(-nz, nz, N)
plt.quiver(x, y, z, Fx, Fy, Fz, edgecolor='k', facecolor='black', linewidth=.5)
ax.set_xlim(-2,2) #I altered the bounds to match the new coordinates 
ax.set_ylim(-2,2)
ax.set_zlim(-2,2)

Note: this code has been tested on matplotlib 3.0.1 only

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement