Python: Как развернуть циклические данные, чтобы удалить разрывы? - PullRequest
5 голосов
/ 01 мая 2019

У меня есть сетка круговых данных, например, данные задаются углом от 0 до π.В этих данных у меня есть еще одна меньшая сетка.

Это может выглядеть так:

enter image description here

Что я хочу сделать, этоинтерполировать черные данные на красных точках.Поэтому я использую scipy.interpolate.griddata.Это даст мне следующий результат:

enter image description here

Как видите, при изменении угла с «почти 0» на «происходит разрыв»почти π '.

Чтобы удалить это, я попытался развернуть данные перед интерполяцией.Согласно этому ответу (здесь) .И я получаю этот (лучший) результат, но удивительно, что справа есть новое несоответствие, которого я не понимаю.

enter image description here

Так что мойвопрос: как использовать np.unwrap для непрерывной интерполяции?Или есть лучший способ сделать это?

Вот код для воспроизведения:

import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import griddata

ax = plt.subplot()
ax.set_aspect(1)

# Simulate some given data.
x, y = np.meshgrid(np.linspace(-10, 10, 20), np.linspace(-10, 10, 20))
phi = np.arctan2(y, x) % (2 * np.pi)
data = np.arctan2(np.cos(phi), np.sin(phi)) % np.pi

# Plot data.
u = np.cos(data)
v = np.sin(data)
ax.quiver(x, y, u, v, headlength=0.01, headaxislength=0, pivot='middle', units='xy')

# Create a smaller grid within.
x1, y1 = np.meshgrid(np.linspace(-6, 5, 20), np.linspace(-4, 8, 25))
# ax.plot(x1, y1, '.', color='red', markersize=2)

# Prepare data.
data = np.unwrap(2 * data) / 2

# Interpolate data on grid.
interpolation = griddata((x.flatten(), y.flatten()), data.flatten(), (x1.flatten(), y1.flatten()))

# Plot interpolated data.
u1 = np.cos(interpolation)
v1 = np.sin(interpolation)
ax.quiver(x1, y1, u1, v1, headlength=0.01, headaxislength=0, pivot='middle', units='xy',
          scale=3, width=0.03, color='red')

plt.show()

1 Ответ

1 голос
/ 03 мая 2019

Чтобы правильно работать с круговыми величинами , преобразуйте углы в комплексные числа перед вызовом griddata и обратно в углы впоследствии:

c=np.exp(2j*data)  # 0,pi -> 1
# …
a=np.angle(interpolation)/2

Коэффициенты 2 распространяют ваш [0, π) на весь круг и обратно. Обратите внимание, что нормализация, подразумеваемая при вызове angle, будет очень чувствительной к вводу, который слишком сильно изменяется в пределах одной «ячейки сетки» входных данных.

...