【问题标题】:Python 3D plotting of measurement data测量数据的 Python 3D 绘图
【发布时间】:2017-06-29 17:09:58
【问题描述】:

我在一个球体上捕获了 3D 测量数据(这是一个天线辐射模式,因此测量天线捕获了每个 phi,theta 方向的辐射强度,并将该值记录为 phi,theta 的函数)。

我很难获得代表的数据。 我尝试了多种选择。这是我现在尝试的最后一个:

import numpy as np
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

nElevationPoints = 16
nAzimuthPoints = 40
stepSizeRad = 0.05 * np.pi
def r(phi,theta):
    radius = 1
    return radius

phi = np.arange(0,nAzimuthPoints*stepSizeRad,stepSizeRad)
theta = np.arange(0,nElevationPoints*stepSizeRad,stepSizeRad)

x = (r(phi,theta)*np.outer(r(phi,theta)*np.cos(phi), np.sin(theta)))
y = (-r(phi,theta)*np.outer(np.sin(phi), np.sin(theta)))
z = (r(phi,theta)*np.outer(np.ones(np.size(phi)), np.cos(theta)))

fig = plt.figure(1)
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='b')

plt.ioff()
plt.show()

这段代码本身就可以工作,它绘制了一个球体。现在的问题是,根据测量数据,我实际上需要的半径不是常数“1”,而是与测量的辐射强度相对应。所以它需要是 phi,theta 的函数。

但是,一旦我将“r”函数更改为包含 phi 或 theta 参数的任何内容,我就会收到有关无法广播的操作数的错误。

如果有任何解决方法可以通过 phi 循环,theta 也可以。

但我现在卡住了,所以我很感激任何帮助:-)

顺便说一句,我采用上述方法的原因是因为我无法理解应该如何定义 x,y,z 才能被 plot_surface 函数接受。 我确实设法通过从 phi、theta、强度数据计算实际位置(x、y、z)来生成散点图,但这只是单个点的表示,并不会生成任何可见的天线辐射模式阴谋。为此,我假设等值线图会更好,但是我又一次陷入了“r”函数调用或通过了解 x,y,z 应该如何格式化(文档指 x,y,z 需要是二维数组,但这超出了我的理解范围,因为 x,y,z 通常本身就是一维数组。

无论如何,期待任何人愿意提供的任何帮助。

-- 编辑--

根据@M4rtini 的建议更改,我得出以下结论:

import numpy as np
from mayavi import mlab

def r(phi,theta):
    r = np.sin(phi)**2
    return r


phi, theta = np.mgrid[0:2*np.pi:201j, 0:np.pi:101j]

x = r(phi,theta)*np.sin(phi)*np.cos(theta)
y = r(phi,theta)*np.sin(phi)*np.sin(theta)
z = r(phi,theta)*np.cos(phi)

intensity = phi * theta

obj = mlab.mesh(x, y, z, scalars=intensity, colormap='jet')
obj.enable_contours = True
obj.contour.filled_contours = True
obj.contour.number_of_contours = 20
mlab.show()

这很有效,谢谢@M4rtini,我现在可以拥有一个依赖于 phi、theta 的“r”函数。 但是,请注意,该示例现在确保 phi 和 theta 具有相同的长度(由于 mgrid 函数)。在我的测量中不是这种情况。当分别声明不同维度的 phi 和 theta 时,它仍然不起作用。所以我现在将研究一下测量插值。

【问题讨论】:

  • 你可以看看numpy.fromfunc,它可以将函数转换为支持广播的函数。
  • 感谢您的建议(我不知道此功能),但似乎没有帮助。它似乎只有在 nElevationPoints 等于 nAzimuthPOints 时才有效(在我的测量中并非如此)。

标签: python 3d plot


【解决方案1】:

这可能不是您要寻找的确切答案,但如果您可以接受使用强度值作为颜色的映射,这应该可以工作。
实际上,您也可以在这里计算一个特定的 r。但我没有对此进行测试。
使用 mayavi,因为在我看来,它在 3D 方面远优于 matplotlib。

import numpy as np
from mayavi import mlab
r = 1.0
phi, theta = np.mgrid[0:np.pi:200j, 0:2*np.pi:101j]

x = r*np.sin(phi)*np.cos(theta)
y = r*np.sin(phi)*np.sin(theta)
z = r*np.cos(phi)

intensity = phi * theta

obj = mlab.mesh(x, y, z, scalars=intensity, colormap='jet')
obj.enable_contours = True
obj.contour.filled_contours = True
obj.contour.number_of_contours = 20
mlab.show()

示例脚本的输出,现在这是一个交互式 gui。因此您可以随意旋转、平移、缩放。甚至可以交互式地操作数据和表示选项。

【讨论】:

  • 谢谢@M4rtini !不过,我无法为我的 windows python 2.6 安装找到 Mayavi 库。我确实看到了一个巨大的 200MB+ 可执行文件,包括 python 2.7。
  • 您是否受到项目限制而无法使用python 2.6?
  • 是的,实际上我是(有些库在 2.6 之后不可用)。但是,由于您的建议和我不断碰壁,我只选择了 Canopy 包(我自己无法将它安装在 2.6 下......)现在有了 Mayavi 和 Python2.7,看看我如何解决 2.6 lib依赖关系稍后;-)顺便说一句,我刚刚取得了一些不错的进展,现在能够有一个“适当的”辐射图。我只需要在绘图时查看“标量”选项以影响绘图中的颜色,因为现在它只依赖于 z 轴,它不应该依赖于 z 轴。感谢您迄今为止的帮助!
  • 如果 r 代表测量值,您可能只需将标量设置为 r。 docs.scipy.org/doc/scipy/reference/interpolate.html 这是 scipy 必须提供的一长串插值函数。 interp2d 或 scipy.ndimage.map_coordinates 看起来不错。
  • 谢谢,完美!如果没有你的帮助,我可能无法做到,非常感谢。我现在一切都按照我的喜好运行了:-)
猜你喜欢
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
相关资源
最近更新 更多