根据从极坐标到笛卡尔坐标的转换在二维数组中重新排列数据

问题描述 投票:7回答:3

我有一个二维数组,表示极坐标系中各个位置的函数值。例如:

import numpy as np

radius = np.linspace(0, 1, 50)
angle = np.linspace(0, 2*np.pi, radius.size)
r_grid, a_grid = np.meshgrid(radius, angle)
data = np.sqrt((r_grid/radius.max())**2
               + (a_grid/angle.max())**2)

此处data排列在一个与极坐标相对应的矩形网格中。我想重新排列数组中的数据,以使轴代表相应的笛卡尔坐标系。新旧布局可以如下显示:

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=plt.figaspect(0.5))
ax1.set(title='Polar coordinates', xlabel='Radius', ylabel='Angle')
ax1.pcolormesh(r_grid, a_grid, data)
ax2.set(title='Cartesian coordinates', xlabel='X', ylabel='Y')
x_grid = r_grid * np.cos(a_grid)
y_grid = r_grid * np.sin(a_grid)
ax2.pcolormesh(x_grid, y_grid, data)

Example

这里明确给出了坐标,并相应地调整了图。我希望将数据重新排列在数据数组本身中。它应该包含所有值,可以选择填充零以适合形状(类似于scipy.ndimage.rotate(..., reshape=True))。

如果我手动遍历极坐标数组以计算笛卡尔坐标,则结果包含理想情况下也应填充的空白区域:

scipy.ndimage.rotate(..., reshape=True)

new = np.zeros_like(data) visits = np.zeros_like(new) for r, a, d in np.nditer((r_grid, a_grid, data)): i = 0.5 * (1 + r * np.sin(a)) * new.shape[0] j = 0.5 * (1 + r * np.cos(a)) * new.shape[1] i = min(int(i), new.shape[0] - 1) j = min(int(j), new.shape[1] - 1) new[i, j] += d visits[i, j] += 1 new /= np.maximum(visits, 1) ax2.imshow(new, origin='lower')

是否有一种方法来实现转换,同时避免在结果数据数组中出现空白区域?

python numpy scipy coordinate-transformation polar-coordinates
3个回答
0
投票

您可以遍历笛卡尔数组,将每个网格点转换为极坐标,并通过从极坐标数据中进行插值来逼近函数值。但是,由于缺少足够接近的数据,您可能仍然希望将角落区域留空。

我认为没有更好的方法,除非您当然可以使用原始功能。


0
投票

tl; dr:不,并非不更改您的问题的某些条件。

您看到的文物是转换的属性。这不是由于所有半径的角度分辨率都是固定的。因此,这不是由于转换的错误或错误实现造成的。笛卡尔网格仅表示在这些区域具有更高的特殊分辨率,因为极坐标图中有解析点。

  • 处理该问题的唯一“干净”方法(我现在可以想到)是在极坐标中具有可调分辨率,以解决1 / r缩放问题。 (如果您输入数据允许的话)

  • 一种在没有间隙的情况下可视化它的作弊方式,是将它们随机分布在间隙上。这里的论据是,您没有解决方案来决定他们从哪个bin开始。因此,您可以将它们随机地放入一个可能是起源的容器中,而不是将它们全部放入一个容器中(就像您现在所做的那样)。但是,我谨此劝阻。它只是给您一个漂亮的情节。请注意,这在某种程度上等同于您问题中右上图的行为。


0
投票

这并没有真正给出预期的结果,但是可能会在某些需要的更正之后帮助您实现解决方案...

Example attempt

def polar_to_cartesian(data): new = np.zeros_like(data) x = np.linspace(-1, 1, new.shape[1]) y = np.linspace(-1, 1, new.shape[0]) for i in range(new.shape[0]): for j in range(new.shape[1]): x0, y0 = x[j], y[i] r, a = np.sqrt(x0**2 + y0**2), np.arctan(y0 / x0) data_i = np.argmin(np.abs(a_grid[:, 0] - a)) data_j = np.argmin(np.abs(r_grid[0, :] - r)) val = data[data_i, data_j] new[i, j] = val return new new = polar_to_cartesian(data) fig, ax = plt.subplots() ax.imshow(new, origin='lower')

© www.soinside.com 2019 - 2024. All rights reserved.