- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
下面的代码生成了我测量强度的点的 3D 图。我希望将强度值附加到每个点,然后在这些点之间进行插值,以生成显示高强度和低强度点的彩色图/曲面图。
我相信这样做需要 scipy.interpolate.RectBivariateSpline
,但我不确定它是如何工作的——因为我看过的示例中没有一个包含 3D 图。
编辑:我想将球体显示为曲面图,但我不确定是否可以使用 Axes3D
来完成此操作,因为我的点不均匀分布式(即赤道周围的点靠得更近)
如有任何帮助,我们将不胜感激。
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
# Radius of the sphere
r = 0.1648
# Our theta vals
theta = np.array([0.503352956, 1.006705913, 1.510058869,
1.631533785, 2.134886741, 2.638239697])
# Our phi values
phi = np.array([ np.pi/4, np.pi/2, 3*np.pi/4, np.pi,
5*np.pi/4, 3*np.pi/2, 7*np.pi/4, 2*np.pi])
# Loops over each angle to generate the points on the surface of sphere
def gen_coord():
x = np.zeros((len(theta), len(phi)), dtype=np.float32)
y = np.zeros((len(theta), len(phi)), dtype=np.float32)
z = np.zeros((len(theta), len(phi)), dtype=np.float32)
# runs over each angle, creating the x y z values
for i in range(len(theta)):
for j in range(len(phi)):
x[i,j] = r * np.sin(theta[i]) * np.cos(phi[j])
y[i,j] = r * np.sin(theta[i]) * np.sin(phi[j])
z[i,j] = r * np.cos(theta[i])
x_vals = np.reshape(x, 48)
y_vals = np.reshape(y, 48)
z_vals = np.reshape(z, 48)
return x_vals, y_vals, z_vals
# Plots the points on a 3d graph
def plot():
fig = plt.figure()
ax = fig.gca(projection='3d')
x, y, z = gen_coord()
ax.scatter(x, y, z)
plt.show()
编辑:更新:我已经格式化了我的数据数组(这里命名为 v),使得前 8 个值对应于 theta 的第一个值,依此类推。出于某种原因,与图表对应的颜色条表示我有负电压值,这在原始代码中没有显示。此外,输入的值似乎并不总是对应于应该是它们位置的点。我不确定是否存在某种偏移量,或者我是否错误地解释了您的代码。
from scipy.interpolate import RectSphereBivariateSpline
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.colorbar import ColorbarBase, make_axes_gridspec
r = 0.1648
theta = np.array([0.503352956, 1.006705913, 1.510058869, 1.631533785, 2.134886741, 2.638239697]) #Our theta vals
phi = np.array([np.pi/4, np.pi/2, 3*np.pi/4, np.pi, 5*np.pi/4, 3*np.pi/2, 7*np.pi/4, 2*np.pi]) #Our phi values
v = np.array([0.002284444388889,0.003155555477778,0.002968888844444,0.002035555555556,0.001884444411111,0.002177777733333,0.001279999988889,0.002666666577778,0.015777777366667,0.006053333155556,0.002755555533333,0.001431111088889,0.002231111077778,0.001893333311111,0.001288888877778,0.005404444355556,0,0.005546666566667,0.002231111077778,0.0032533332,0.003404444355556,0.000888888866667,0.001653333311111,0.006435555455556,0.015311110644444,0.002453333311111,0.000773333333333,0.003164444366667,0.035111109822222,0.005164444355556,0.003671111011111,0.002337777755556,0.004204444288889,0.001706666666667,0.001297777755556,0.0026577777,0.0032444444,0.001697777733333,0.001244444411111,0.001511111088889,0.001457777766667,0.002159999944444,0.000844444433333,0.000595555555556,0,0,0,0]) #Lists 1A-H, 2A-H,...,6A-H
volt = np.reshape(v, (6, 8))
spl = RectSphereBivariateSpline(theta, phi, volt)
# evaluate spline fit on a denser 50 x 50 grid of thetas and phis
theta_itp = np.linspace(0, np.pi, 100)
phi_itp = np.linspace(0, 2 * np.pi, 100)
d_itp = spl(theta_itp, phi_itp)
x_itp = r * np.outer(np.sin(theta_itp), np.cos(phi_itp)) #Cartesian coordinates of sphere
y_itp = r * np.outer(np.sin(theta_itp), np.sin(phi_itp))
z_itp = r * np.outer(np.cos(theta_itp), np.ones_like(phi_itp))
norm = plt.Normalize()
facecolors = plt.cm.jet(norm(d_itp))
# surface plot
fig, ax = plt.subplots(1, 1, subplot_kw={'projection':'3d', 'aspect':'equal'})
ax.hold(True)
ax.plot_surface(x_itp, y_itp, z_itp, rstride=1, cstride=1, facecolors=facecolors)
#Colourbar
cax, kw = make_axes_gridspec(ax, shrink=0.6, aspect=15)
cb = ColorbarBase(cax, cmap=plt.cm.jet, norm=norm)
cb.set_label('Voltage', fontsize='x-large')
plt.show()
最佳答案
您可以在球坐标空间中进行插值,例如使用 RectSphereBivariateSpline
:
from scipy.interpolate import RectSphereBivariateSpline
# a 2D array of intensity values
d = np.outer(np.sin(2 * theta), np.cos(2 * phi))
# instantiate the interpolator with the original angles and intensity values.
spl = RectSphereBivariateSpline(theta, phi, d)
# evaluate spline fit on a denser 50 x 50 grid of thetas and phis
theta_itp = np.linspace(0, np.pi, 50)
phi_itp = np.linspace(0, 2 * np.pi, 50)
d_itp = spl(theta_itp, phi_itp)
# in order to plot the result we need to convert from spherical to Cartesian
# coordinates. we can avoid those nasty `for` loops using broadcasting:
x_itp = r * np.outer(np.sin(theta_itp), np.cos(phi_itp))
y_itp = r * np.outer(np.sin(theta_itp), np.sin(phi_itp))
z_itp = r * np.outer(np.cos(theta_itp), np.ones_like(phi_itp))
# currently the only way to achieve a 'heatmap' effect is to set the colors
# of each grid square separately. to do this, we normalize the `d_itp` values
# between 0 and 1 and pass them to one of the colormap functions:
norm = plt.Normalize(d_itp.min(), d_itp.max())
facecolors = plt.cm.coolwarm(norm(d_itp))
# surface plot
fig, ax = plt.subplots(1, 1, subplot_kw={'projection':'3d', 'aspect':'equal'})
ax.hold(True)
ax.plot_surface(x_itp, y_itp, z_itp, rstride=1, cstride=1, facecolors=facecolors)
这是一个完美的解决方案。特别是,会出现一些难看的边缘效应,其中 ϕ 从 2π 到 0“环绕”(请参阅下面的更新)。
要解决关于颜色条的第二个问题:因为我必须单独设置每个补丁的颜色以获得“热图”效果,而不是仅仅指定一个数组和颜色图,所以创建颜色条的常规方法不会不工作。但是,可以使用 ColorbarBase
来“伪造”颜色条。类:
from matplotlib.colorbar import ColorbarBase, make_axes_gridspec
# create a new set of axes to put the colorbar in
cax, kw = make_axes_gridspec(ax, shrink=0.6, aspect=15)
# create a new colorbar, using the colormap and norm for the real data
cb = ColorbarBase(cax, cmap=plt.cm.coolwarm, norm=norm)
cb.set_label('Voltage', fontsize='x-large')
要“拉平球体”,您可以在二维热图中将插值强度值绘制为 ϕ 和 ϴ 的函数,例如使用 pcolormesh
:
fig, ax = plt.subplots(1, 1)
ax.hold(True)
# plot the interpolated values as a heatmap
im = ax.pcolormesh(phi_itp, theta_itp, d_itp, cmap=plt.cm.coolwarm)
# plot the original data on top as a colormapped scatter plot
p, t = np.meshgrid(phi, theta)
ax.scatter(p.ravel(), t.ravel(), s=60, c=d.ravel(), cmap=plt.cm.coolwarm,
norm=norm, clip_on=False)
ax.set_xlabel('$\Phi$', fontsize='xx-large')
ax.set_ylabel('$\Theta$', fontsize='xx-large')
ax.set_yticks(np.linspace(0, np.pi, 3))
ax.set_yticklabels([r'$0$', r'$\frac{\pi}{2}$', r'$\pi$'], fontsize='x-large')
ax.set_xticks(np.linspace(0, 2*np.pi, 5))
ax.set_xticklabels([r'$0$', r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{4}$',
r'$2\pi$'], fontsize='x-large')
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(0, np.pi)
cb = plt.colorbar(im)
cb.set_label('Voltage', fontsize='x-large')
fig.tight_layout()
您可以看到为什么这里存在奇怪的边界问题 - 没有足够接近 ϕ = 0 的输入点采样以捕获沿 ϕ 轴的振荡的第一阶段,并且插值没有“包裹”强度值从 2π 到 0。在这种情况下,一个简单的解决方法是在进行插值之前复制 φ = 2π 处的输入点,使 φ = 0。
我不太确定“实时旋转球体”是什么意思 - 您应该已经可以通过在 3D 轴上单击并拖动来完成此操作。
虽然您的输入数据不包含任何负电压,但这并不能保证插值数据不会。样条拟合不限于非负,您可以预期插值在某些地方“低于”真实数据:
print(volt.min())
# 0.0
print(d_itp.min())
# -0.0172434740677
我不太确定我理解你的意思
Also, the values input do not always seem to correspond to the points which should be their positions.
这是您的数据作为 2D 热图的样子:
散点的颜色(代表您的原始电压值)与热图中的插值完全匹配。也许您指的是插值中“过冲”/“下冲”的程度?鉴于数据集中的输入点很少,这很难避免。您可以尝试的一件事是尝试使用 RectSphereBivariateSpline
的 s
参数。通过将其设置为正值,您可以进行平滑而不是插值,即您可以放宽插值必须准确通过输入点的约束。但是,我快速尝试了一下,但无法获得漂亮的输出,可能是因为输入点太少了。
关于python - 将强度附加到 3D 图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33569225/
我正在开发一个录音机应用程序。我想知道在录制音频时有什么方法可以找到音频的强度。我不想将录音保存在任何地方。我只想向用户展示麦克风捕捉到的声音是否大于预定义的阈值。 假设如果声音低于 2 分贝,它应该
我正在尝试让一个基本服务器(从 Beginning Python 复制)来发送一个 str。 错误: c.send( "XXX" ) TypeError: must be bytes or buffe
我陷入了一个问题,不知道去哪里看。我需要增加图像中特定颜色的强度,例如 R、G 或蓝色。当我这样做时,某些颜色无法正确呈现。 下面是我为测试拍摄的图像: 现在当我像绿色一样增加时: A = Color
我不希望我的背景图片太模糊。没有调整模糊强度的属性吗? let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light) blurEffect
我使用 OpenCV 2.4.11+Qt 并尝试制作视频并更改红色/蓝色或绿色 channel 的强度,但没有找到任何功能或设置来执行此操作。有谁知道如何做到这一点? 最佳答案 如果您只想更改一个特定
当我有 x、y、强度时,我不知道如何创建热图(或等高线图)。我有一个看起来像这样的文件: 0,1,6 0,2,10 .... 到目前为止: with open('eye_.txt', 'r') as
有谁有一些可以在 iPhone 应用程序中使用的代码,让我可以看到 wifi 的强度吗?我有一个连接密集型操作,并且希望它们不在不稳定区域 最佳答案 这可能会帮助您走上正确的道路...... http
当从 RGB 转换为灰度时,据说应该对 R、G 和 B channel 应用特定的权重。这些权重是:0.2989、0.5870、0.1140。 据说这是因为人类对这三种颜色的感知/感受不同。有时也有人
Eclipse SSH key 生成屏幕(常规 -> 网络连接 -> SSH2)生成 1024 位 RSA key ,该 key 太弱而无法使用 ( http://news.netcraft.com/
当从 RGB 转换为灰度时,据说应该对 R、G 和 B channel 应用特定的权重。这些权重是:0.2989、0.5870、0.1140。 据说这是因为人类对这三种颜色的感知/感受不同。有时也有人
我们的网络应用程序使用 the Vibrate API对于微妙的按钮按下效果: window.navigator.vibrate(5); 但在我的新手机上,感觉不那么微妙,更像是我的手机正试图从我手中
我的应用程序应扫描周围的 Wifi 信号并列出网络名称及其 RSSI。 我在谷歌上找不到任何关于如何做的线索。有人可以举个例子或者至少指出其他地方我可以找到答案吗? 最佳答案 我认为这不可能!不管是
所以我的图像有一些黑点,它们看起来很简单,所以我想我可以创建一个亮度图,将其反转,然后将其应用到我的图像以消除黑点。然而,我所能找到的只有两种均衡方法:均衡整个图像(使用直方图)或将图像分割成深色和浅
我是一名优秀的程序员,十分优秀!