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中鼠标在坐标图上单击,记录下这一点的坐标啊

PyQtGraph & OpenGL:如何在两个坐标之间创建一个球体?

PyQtGraph横坐标刷新时间

如何用EXCEL坐标图计算两点间折线距离

pyqtgraph动态刷新数据(横坐标为时间)