为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

智慧大石 2022-08-25 15:43:53
我有一个二维数组,它表示极坐标系中位置的函数值。例如: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               + (a_grid/angle.max())**2)这里排列在对应于极坐标的矩形网格中。我想重新排列数组中的数据,以便轴表示相应的笛卡尔坐标系。新旧布局可以按如下方式可视化:dataimport matplotlib.pyplot as pltfig, (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)这里明确给出了坐标,并相应地调整了绘图。我希望在数据数组本身中重新排列数据。它应该包含所有值,可以选择用零填充以适合形状(类似于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] += 1new /= np.maximum(visits, 1)ax2.imshow(new, origin='lower')有没有办法在实现转换的同时避免结果数据数组中的空白区域?
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

tl;dr:不,不是没有改变你的问题的一些条件。

你所看到的人工制品是转变的一个属性。这并不是由于所有半径的角度具有固定的分辨率。因此,这不是由于转换的错误或不良实现。笛卡尔格网只是意味着这些区域具有更高的特殊分辨率,因为极地图中存在已解析的点。

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

  • 一种有点作弊的可视化方式是没有间隙,将它们随机分布在间隙上。这里的论点是,你没有决心决定他们从哪个箱子开始。因此,您可以随机将它们放入一个可能是可能的起源中,而不是将它们全部扔在同一个中(就像您现在所做的那样)。但是,我想劝阻这种诡计。它只是给你一个更漂亮的情节。请注意,这在某种程度上等同于问题中右上角绘图的行为。


查看完整回答
反对 回复 2022-08-25
?
温温酱

TA贡献1752条经验 获得超4个赞

这并没有真正给出预期的结果,但也许会帮助你在一些需要的纠正后实现解决方案......



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)



def polar_to_cartesian(data):

    new = np.zeros_like(data) * np.nan

    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.arctan2(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]


            if r <= 1:

                new[i, j] = val


    return new


new = polar_to_cartesian(data)

fig, ax = plt.subplots()

ax.imshow(new, origin='lower')

查看完整回答
反对 回复 2022-08-25
?
慕斯王

TA贡献1864条经验 获得超2个赞

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

我不认为有更好的方法,除非你当然可以访问原始功能。


查看完整回答
反对 回复 2022-08-25
  • 3 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信