極座標からデカルト座標への変換に従って2次元配列のデータを再配置します


8

極座標系の位置の関数値を表す2次元配列があります。例えば:

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)

例

ここでは座標が明示的に与えられ、それに応じてプロットが調整されます。代わりに、データをデータ配列自体に再配置したいのですが。これにはすべての値が含まれている必要があり、形状に合わせてゼロで埋めることもできます(と同様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')

試行例

結果のデータ配列の空の領域を回避しながら変換を実現する方法はありますか?

回答:


2

tl; dr:いいえ、問題のいくつかの条件を変更することなしではありません。

あなたが見ているアーティファクトは変換の特性です。これは、すべての半径の角度の固定解像度によるものではありません。したがって、それは変換の間違ったまたは悪い実装によるものではありません。デカルトグリッドは、極座標マップから解決されたポイントがあるため、これらの領域ではより高い特別な解像度を意味します。

  • これを処理する唯一の「クリーン」な方法(私が今考えることができる)は、1 / rスケーリングを考慮するために極座標で調整可能な解像度を持つことです。(あなたがデータを入力する場合はそれを許可します)

  • ギャップなしでこれを視覚化するやや浮気方法は、それらをギャップにランダムに分散することです。ここでの議論は、どのビンで開始するかを決定する決議がないということです。したがって、可能性のある起源である可能性のある1つにランダムにそれらをランダムにスローし、それらをすべて同じものにスローすることはできません(現在行っているように)。しかし、私はこの問題を思いとどまらせたいと思います。それはあなたにもっときれいなプロットを与えるだけです。これは、質問の右上のプロットの動作と多少同じです。


実際、角度分解能は固定されているため、問題は半径の増加に伴って空間分解能が低下することです。1/r直交座標への変換が計算される前に、比例する密度で各半径の角度データが補間されるアプローチを試しました。結果は有望に見え、周りにいくつかのアーティファクトがy = 0残っているだけなので、まだ調査中です。
a_guest

1

これは実際に期待される結果を与えるわけではありませんが、必要な修正を行った後で解決策を達成するのに役立つでしょう...


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')

ここに画像の説明を入力してください

編集:np.arctan2OPの提案に従って使用して変更されました。


正しい角度依存関係を取得するためにnp.arctan2使用する必要がありますが、いずれの場合も、デカルト座標系のエッジに向かって大きな差異が生じます。実際にはデータポイントはありませんが、このアプローチでは、最も近い利用可能なデータポイントのみを考慮しているため、満たすべきではないが満たされています。
a_guest

@a_guestは実際、最も近い値を考慮するだけです。基本的に最近傍内挿を行っています。より高度な補間が必要な場合、補間は放射状空間で行う必要があるため、はるかに複雑になります。たぶんskimage.transform.resize、与えられた係数によって極画像をアップサンプリングし、双一次または双三次補間を使用して、このアプローチを使用して変換を行う可能性があります。最終的には、より正確な変換になります。
dzang

@a_guest半径を1に制限すると、境界の問題を解決できますか?
dzang

0

デカルト配列をループして、各グリッドポイントを極座標に変換し、極グリッドデータからの補間によって関数値を近似することができます。ただし、十分に近いデータがないため、コーナー領域を空白のままにすることもできます。

もちろん、元の機能にアクセスできない限り、もっと良い方法はないと思います。


私があなたを正しく理解している場合、これらの補間されたグリッドポイントは、現在のグリッドポイントの「間に」位置します。したがって、グリッドポイントがどこから来たかは決定できません。それとも私はあなたを誤解しましたか?
465b

はい、デカルトグリッドポイントの1つを極座標に変換すると、通常、4つの極グリッドポイント間のどこかになります。したがって、距離に応じて重み付けされた、これらの4つのグリッドポイントの関数値の平均をとることによって、関数値を割り当てます。それが私が補間によって意味したことです。
Arne

これが役立つ場合があります:en.wikipedia.org/wiki/Multivariate_interpolation
Arne

ああ、よし。しかし、これは個々のポイントを「より大きく」するだけです。これは、rの値が低い場合に役立つ4つのポイントに分布するためです。これでも、rの値が大きくなると星型のパターンになります
465b

いいえ、そうは思いません。上記の方法を使用すると、すべてのデカルトグリッドポイントの関数値の明確な推定値を計算できます。
アルネ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.