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

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


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)

http://img4.mukewang.com/630728eb0001d5dc07970434.jpg

这里明确给出了坐标,并相应地调整了绘图。我希望在数据数组本身中重新排列数据。它应该包含所有值,可以选择用零填充以适合形状(类似于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')

http://img.mukewang.com/630728fd0001285007830435.jpg

有没有办法在实现转换的同时避免结果数据数组中的空白区域?


智慧大石
浏览 122回答 3
3回答

胡说叔叔

tl;dr:不,不是没有改变你的问题的一些条件。你所看到的人工制品是转变的一个属性。这并不是由于所有半径的角度具有固定的分辨率。因此,这不是由于转换的错误或不良实现。笛卡尔格网只是意味着这些区域具有更高的特殊分辨率,因为极地图中存在已解析的点。处理这个问题的唯一“干净”方法(我现在能想到的)是在极坐标中具有可调节的分辨率,以考虑1 / r缩放。(如果输入数据允许)一种有点作弊的可视化方式是没有间隙,将它们随机分布在间隙上。这里的论点是,你没有决心决定他们从哪个箱子开始。因此,您可以随机将它们放入一个可能是可能的起源中,而不是将它们全部扔在同一个中(就像您现在所做的那样)。但是,我想劝阻这种诡计。它只是给你一个更漂亮的情节。请注意,这在某种程度上等同于问题中右上角绘图的行为。

温温酱

这并没有真正给出预期的结果,但也许会帮助你在一些需要的纠正后实现解决方案......import numpy as npradius = 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&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ (a_grid/angle.max())**2)def polar_to_cartesian(data):&nbsp; &nbsp; new = np.zeros_like(data) * np.nan&nbsp; &nbsp; x = np.linspace(-1, 1, new.shape[1])&nbsp; &nbsp; y = np.linspace(-1, 1, new.shape[0])&nbsp; &nbsp; for i in range(new.shape[0]):&nbsp; &nbsp; &nbsp; &nbsp; for j in range(new.shape[1]):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x0, y0 = x[j], y[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r, a = np.sqrt(x0**2 + y0**2), np.arctan2(y0, x0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_i = np.argmin(np.abs(a_grid[:, 0] - a))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_j = np.argmin(np.abs(r_grid[0, :] - r))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; val = data[data_i, data_j]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if r <= 1:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new[i, j] = val&nbsp; &nbsp; return newnew = polar_to_cartesian(data)fig, ax = plt.subplots()ax.imshow(new, origin='lower')

慕斯王

您可以遍历笛卡尔数组,将每个网格点转换为极坐标,并通过从极坐标数据中插值来近似函数值。不过,您可能仍希望将角落区域留空,因为缺少足够接近的数据。我不认为有更好的方法,除非你当然可以访问原始功能。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python