I have a grid with some given data. This data is given by its angle (from 0
to π
). Within this grid I have another smaller grid.
This might look like this:
Now I want to interpolate the angles on that grid.
I tried this by using scipy.interpolate.griddata
what gives a good result. But there is a problem when the angles change from almost 0
to almost π
(because the middle is π/2
...)
Here is the result and it is easy to see what's going wrong.
How can I deal with that problem? Thank you! :)
Here is the code to reproduce:
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))
data = np.arctan(y / 10) % np.pi
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(-1, 5, 15), np.linspace(-6, 2, 20))
# ax.plot(x1, y1, '.', color='red', markersize=2)
# Interpolate data on grid.
interpolation = griddata((x.flatten(), y.flatten()), data.flatten(), (x1.flatten(), y1.flatten()))
u1 = np.cos(interpolation)
v1 = np.sin(interpolation)
ax.quiver(x1, y1, u1, v1, headlength=0.01, headaxislength=0, pivot='middle', units='xy',
color='red', scale=3, width=0.03)
plt.show()
Edit:
Thanks to @bubble, there is a way to adjust the given angles before interpolation such that the result will be as desired. Therefore:
Define a rectifying function:
def RectifyData(data): for j in range(len(data)): step = data[j] - data[j - 1] if abs(step) > np.pi / 2: data[j] += np.pi * (2 * (step < 0) - 1) return data
Interpolate as follows:
interpolation = griddata((x.flatten(), y.flatten()), RectifyData(data.flatten()), (x1.flatten(), y1.flatten())) u1 = np.cos(interpolation) v1 = np.sin(interpolation)
I tried direct interpolation of cos(angle)
and sin(angle)
values, but this still yielded to discontinues, that cause wrong line directions. The main idea consist in reducing discontinues, eg [2.99,3.01, 0.05,0.06]
should be transformed to something like this: [2.99, 3.01, pi+0.05, pi+0.06]
. This is needed to apply 2D interpolation algorithm correctly. Almost the same problem raises in the following post .
def get_rectified_angles(u, v):
angles = np.arcsin(v)
inds = u < 0
angles[inds] *= -1
# Direct approach of removing discontinues
# for j in range(len(angles[1:])):
# if abs(angles[j] - angles[j - 1]) > np.pi / 2:
# sel = [abs(angles[j] + np.pi - angles[j - 1]), abs(angles[j] - np.pi - angles[j-1])]
# if np.argmin(sel) == 0:
# angles[j] += np.pi
# else:
# angles[j] -= np.pi
return angles
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(-1, 5, 15), np.linspace(-6, 2, 20))
angles = get_rectified_angles(u.flatten(), v.flatten())
interpolation = griddata((x.flatten(), y.flatten()), angles, (x1.flatten(), y1.flatten()))
u1 = np.cos(interpolation)
v1 = np.sin(interpolation)
ax.quiver(x1, y1, u1, v1, headlength=0.01, headaxislength=0, pivot='middle', units='xy',
color='red', scale=3, width=0.03)
Probably, numpy.unwrap
function could be used to fix discontinues. In case of 1d data, numpy.interp
has keyword period
to handle periodic data.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.