scipy 不均匀采样的Angular 值的二维插值/平滑

xnifntxz  于 2022-11-10  发布在  Angular
关注(0)|答案(2)|浏览(166)

我有一些由不均匀采样的2D空间位置组成的数据,其中每个 x,y 坐标都有一个在0和2 pi之间的相关相位值 theta。我希望能够将 theta 值插值到规则的 x,y 网格上。(或非常接近的)x,y 位置可以与多个相位值相关联,并且对于 * θ * 的值反之亦然,因此严格地说,这是平滑问题而不是直接插值。
我已经简单地用scipy的径向基函数做了实验,但是由于从2 pi--〉0开始的 theta 值的不连续性,这些径向基函数给予令人讨厌的边缘效应。
下面是一个玩具示例(相位的真实的空间分布要混乱得多):

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colorbar
from matplotlib.colors import Normalize
from scipy import interpolate

# randomly sampled spatial locations

x, y = np.random.uniform(-1, 1, size=(2, 1000))

# theta varies smoothly with location apart from the singularity at 0, 0

z = np.arctan2(x, y) % (2 * np.pi)

# smooth with a simple linear RBF

rbf = interpolate.Rbf(x, y, z, function='linear', smooth=0.1)

# resample on a finer grid

xi, yi = np.mgrid[-1:1:100j, -1:1:100j].reshape(2, -1)
zi = rbf(xi, yi) % (2 * np.pi)

# plotting

fig, ax = plt.subplots(1, 1, subplot_kw={'aspect': 'equal'})
ax.hold(True)
norm = Normalize(0, 2 * np.pi)
im = ax.imshow(zi.reshape(100, 100).T, extent=(-1, 1, -1, 1),
               origin='lower', cmap=plt.cm.hsv, norm=norm)
sc = ax.scatter(x, y, s=30, c=z, cmap=im.cmap, norm=norm)
cax, kw = colorbar.make_axes_gridspec(ax)
cb = plt.colorbar(im, cax=cax,**kw)
ax.set_xlabel(r'$X_0$', fontsize='x-large')
ax.set_ylabel(r'$Y_0$', fontsize='x-large')
cb.set_ticks(np.arange(0, 2.1*np.pi, np.pi/2.))
cb.set_ticklabels([r'$0$', r'$\frac{\pi}{2}$', r'$\pi$',
                   r'$\frac{3\pi}{2}$', r'$2\pi$'])
cb.set_label(r'$\theta$', fontsize='x-large')
cb.ax.tick_params(labelsize='x-large')
plt.show()

什么是一个很好的方法来插值像这样的Angular 量?scipy有任何内置的插值方法,将处理Angular 很好,还是我必须写我自己的?

wb1gzix0

wb1gzix01#

我现在觉得自己很蠢!
答案很简单--this answer on MathOverflow告诉了我。如果我将极坐标空间转换为笛卡尔坐标空间,然后独立地对矢量的x和y分量进行插值,则不连续性没有问题:

x, y = np.random.uniform(-1, 1, size=(2, 1000))
z = np.arctan2(y, x) % (2*np.pi)

# convert from polar --> cartesian

u, v = np.cos(z), np.sin(z)

# interpolate x and y components separately

rbf_u = interpolate.Rbf(x, y, u, function='linear', smooth=0.1)
rbf_v = interpolate.Rbf(x, y, v, function='linear', smooth=0.1)
xi, yi = np.mgrid[-1:1:100j, -1:1:100j].reshape(2, -1)
ui = rbf_u(xi, yi)
vi = rbf_v(xi, yi)

# convert from cartesian --> polar

zi = np.arctan2(ui, vi) % (2*np.pi)

如果有一种方法可以避免在x和y分量上执行两个单独的插值,那将是一个很好的性能方面的问题,但我真的没有看到解决这个问题的方法。

8fsztsew

8fsztsew2#

扩展可接受的答案,这可以通过使用复数来存储坐标而在单次传递中完成:

x, y = np.random.uniform(-1, 1, size=(2, 1000))
z = np.arctan2(y, x) % (2*np.pi)

# convert to cartesian coordinates on the complex plane

u = np.sin(z) + np.cos(z) * 1j

# interpolate x and y components separately

rbf_u = sp.interpolate.Rbf(x, y, u, function='linear', smooth=0.1)
xi, yi = np.mgrid[-1:1:100j, -1:1:100j].reshape(2, -1)
ui = rbf_u(xi, yi)

# convert from cartesian --> polar

zi = np.angle(ui) % (2*np.pi)

相关问题