通过读取数据使用 matplotlib 制作 3D 箭袋图

问题描述

我正在尝试使用 matplotlib 2.2.5 制作 3D 箭袋图。我在下面提供了一个简单的示例代码来展示我的尝试。我想使用 fx(x,y,z)、fy(x,z) 和 fz(x,z) 制作一个箭袋图。这些对应于向量场 f = (fx,fy,fz)。我将 fx,fz 的数据输入为 3 个 .dat 文件,其中每个 .dat 文件是 1 列数字。

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,z,indexing='ij')

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

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

数据生成和存储如下(使用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,z; fx(x,z)
       fy(i,k) = i - 4.*j  + k !this is a function fy that depends on x,z; fy(x,z)
       fz(i,k) = i + 2*j + k !this is a function fz that depends on x,z; fz(x,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,k) !stores fx(x,z)
        WRITE(2,*) fy(i,k) !stores fy(x,z)
        WRITE(3,*) fz(i,k) !stores fz(x,z)
      END DO
   END DO
END DO

解决方法

我在这里假设您正在尝试从 (origin (0,0) 开始绘制箭袋。

使用坐标介于 -1 和 1 之间的随机样本(希望它与您的数据样本匹配),这将是这样的:

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]

请注意,我使用了一个简单的“:”:根据您的解释,您的 .dat 文件只有一个维度。仅当您至少有 2 个维度时才使用倍数冒号。

plt.quiver(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()

如果你想从你的网格(即 np.linspace)开始绘图,你可以改变代码如下(虽然我不确定这是你想要实现的):

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,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)

注意:此代码仅在 matplotlib 3.0.1 上测试过

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...