pyqtgraph中的球坐标图
Posted
技术标签:
【中文标题】pyqtgraph中的球坐标图【英文标题】:Spherical coordinates plot in pyqtgraph 【发布时间】:2018-02-25 17:16:19 【问题描述】:我刚开始使用 pyqtgraph,我想在球坐标中制作 3d 曲面图。我查看了文档中的示例 GLSurfacePlot.py,但只有笛卡尔坐标中的图。
这是我要绘制的图(它是半波偶极子辐射图):
如何用 pyqtgraph 绘制 r(theta, phi)?
编辑:我可以用 matplotlib mplot3d 来做,这是脚本:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
k = 2*np.pi
long = 0.5
theta = np.linspace(0, np.pi, 361)
phi = np.linspace(0, 2*np.pi, 361)
PHI, THETA = np.meshgrid(phi, theta)
R = np.absolute((np.cos(k*long/2*np.cos(THETA))-np.cos(k*long/2))/np.sin(THETA))
R = np.nan_to_num(R)
X = R * np.sin(THETA) * np.cos(PHI)
Y = R * np.sin(THETA) * np.sin(PHI)
Z = R * np.cos(THETA)
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
cmap = plt.get_cmap('jet')
plot = ax.plot_surface(X, Y, Z, rstride=10, cstride=10, facecolors=cmap(R),linewidth=0, antialiased=False, alpha=1)
plt.show()
问题是它在旋转和缩放时太慢了,我的应用程序肯定需要这个功能,这就是我尝试用 pyqtgraph 来做的原因。
【问题讨论】:
你可以放置数学方程 什么意思? 我的意思是什么等式r(theta, phi)
不使用代码。
完成,我想插入一个包含数学表达式的图像,但我不能,因为我没有 10 个重复。
将其上传到保管箱、驱动器或类似设备并在此处分享链接,我会将其放在您的帖子中。 :P
【参考方案1】:
通过GLSurfacePlotItem
无法绘制此类方程,在这种情况下您必须使用GLMeshItem
,但为此您必须创建一个适当的MeshData
,因此以sphere
为参考获得以下功能:
def DipoleData(rows, cols, func, args=None):
verts = np.empty((rows+1, cols, 3), dtype=float)
phi = (np.arange(rows+1) * 2*np.pi *(1+2/rows)/ rows).reshape(rows+1, 1)
th = ((np.arange(cols) * np.pi / cols).reshape(1, cols))
if args is not None:
r = func(th, phi, *args)
else:
r = func(th, phi)
s = r* np.sin(th)
verts[...,2] = r * np.cos(th)
verts[...,0] = s * np.cos(phi)
verts[...,1] = s * np.sin(phi)
verts = verts.reshape((rows+1)*cols, 3)[cols-1:-(cols-1)] ## remove redundant vertexes from top and bottom
faces = np.empty((rows*cols*2, 3), dtype=np.uint)
rowtemplate1 = ((np.arange(cols).reshape(cols, 1) + np.array([[0, 1, 0]])) % cols) + np.array([[0, 0, cols]])
rowtemplate2 = ((np.arange(cols).reshape(cols, 1) + np.array([[0, 1, 1]])) % cols) + np.array([[cols, 0, cols]])
for row in range(rows):
start = row * cols * 2
faces[start:start+cols] = rowtemplate1 + row * cols
faces[start+cols:start+(cols*2)] = rowtemplate2 + row * cols
faces = faces[cols:-cols] ## cut off zero-area triangles at top and bottom
## adjust for redundant vertexes that were removed from top and bottom
vmin = cols-1
faces[faces<vmin] = vmin
faces -= vmin
vmax = verts.shape[0]-1
faces[faces>vmax] = vmax
return gl.MeshData(vertexes=verts, faces=faces)
然后用在下面的例子中:
app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.opts['distance'] = 3
w.show()
w.setWindowTitle('Half Wave Dipole Radiation Pattern')
def r_theta_phi(theta, phi, k, l):
return np.absolute((np.cos((k*l/2)*np.cos(theta)) -np.cos(k*l/2))/np.sin(theta))
p = 2*np.pi
q = 0.5
md = DipoleData(100, 100, r_theta_phi, args=(p, q))
colors = np.ones((md.faceCount(), 4), dtype=float)
colors[:,0] = np.linspace(0.1, 0.2, colors.shape[0])
colors[:,1] = np.linspace(0.2, 0.9, colors.shape[0])
colors[:,2] = np.linspace(0.0, 0.1, colors.shape[0])
md.setFaceColors(colors)
m = gl.GLMeshItem(meshdata=md, smooth=False)
w.addItem(m)
ax = gl.GLAxisItem()
ax.setSize(100,100,100)
w.addItem(ax)
g = gl.GLGridItem()
g.scale(0.2, 0.2, 0.2)
w.addItem(g)
## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
获取如下图所示:
【讨论】:
嗯,这和它应该的样子完全不同。 antenna-theory.com/antennas/norm3D1lam.jpg 你可以告诉我这本书,也许你传给我的方程式是另一个,我是一名电子学学生,我在其他程序中模拟过它,我得到了类似的东西。 :P 天线理论:分析与设计。康斯坦丁A.巴拉尼斯。 (第 182-183 页)。在这里,您可以查看我对其进行的捕获:gyazo.com/467868b5353b8eb1d8fb7b35f6d4833b。我只关心归一化的幅度,所以我在括号内表示。这是一个比我传递给您的表达式更简单的表达式,因为它已经替换了 k 和 l 值。我用 matplotlib mplot3d 绘制它并得到了预期的图形,但它太慢了,这就是我想使用 pyqtgraph 的原因。 @Jorge 问题是通过使用坐标系,使用你的定义我和你一样。 现在看起来不错,但是生成的曲面并没有完全封闭,它在 phi = 0 处有一个小开口。没什么太严重的,也许你可以轻松解决。作为一个初学者,这种操作对我来说看起来有点太复杂了,我的意思是,与此相比,matplotlib 代码是如此简单。我正在考虑尝试 mayavi,因为它看起来更容易。以上是关于pyqtgraph中的球坐标图的主要内容,如果未能解决你的问题,请参考以下文章
试图在 PyQt5 中的 pyqtgraph plotwidget 中获取坐标显示的光标
怎么在matlab中鼠标在坐标图上单击,记录下这一点的坐标啊