在形状内保持 2D 插值
Keeping 2D interpolation within shape
我有一组测量点,我想在它们之间进行插值,为此我使用 SciPy 的 griddata():
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
data = pd.DataFrame({
'time': [0, 1, 2, 3, 4, 0.1, 0.9, 2, 3.05, 4, 0, 1, 2.2, 3, 3.95],
'force': [1, 2, 4, 9, 16, 0, 0, 0, 0, 0, -1, -2, -4, -9, -16]
})
Times, Forces = np.meshgrid(
np.linspace(0, 4, 100),
np.linspace(-16, 16, 100)
)
data['work'] = data['time'] * data['force']
interpolation = griddata(
(data['time'], data['force']),
data['work'],
(Times, Forces),
method= 'linear'
)
fig, ax = plt.subplots()
contour = ax.contourf(
Times, Forces, interpolation
)
ax.scatter(data['time'], data['force'])
fig.show()
我的问题是,我的测量点已经沿着物理可能性的边界,但是插值仍然会为每个可跨越的区域进行插值,包括那些无法测量的区域。
如何限制插值或至少将插值图限制为 'within' 外点的形状?不幸的是 'time' 测量值有小偏差。
如有任何建议,我们将不胜感激!
首先,你需要得到所有点的凹多边形。其次,使用多边形裁剪轮廓填充。虽然,这可能有点复杂,但一些有用的包可以帮助完成这些任务。
下面是代码。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
import matplotlib.path as mpath
import alphashape
from descartes import PolygonPatch
Path = mpath.Path
data = pd.DataFrame({
'time': [0, 1, 2, 3, 4, 0.1, 0.9, 2, 3.05, 4, 0, 1, 2.2, 3, 3.95],
'force': [1, 2, 4, 9, 16, 0, 0, 0, 0, 0, -1, -2, -4, -9, -16]
})
Times, Forces = np.meshgrid(
np.linspace(0, 4, 100),
np.linspace(-16, 16, 100)
)
data['work'] = data['time'] * data['force']
interpolation = griddata(
(data['time'], data['force']),
data['work'],
(Times, Forces),
method= 'linear')
fig, ax = plt.subplots()
plt.xlim(-.3,4.3)
plt.ylim(-18,18)
#contour = ax.contourf( Times, Forces, interpolation)
contour = ax.tricontourf( data['time'], data['force'], data['work'])
ax.scatter(data['time'], data['force'])
x = data['time']
y = data['force']
points = np.vstack([x, y]).T
alpha = 0.95 * alphashape.optimizealpha(points)
hull = alphashape.alphashape(points, alpha)
hull_pts = hull.exterior.coords.xy
ax.scatter(hull_pts[0], hull_pts[1], color='red')
ax.add_patch(PolygonPatch(hull, fill=False, color='red'))
plt.savefig("clip_before.png")
#make clip path
vertices = []
codes = []
xpts,ypts = hull_pts
## convert polygon to path for cliping contour fill
for ix,iy in zip(xpts,ypts):
vertices.append((ix,iy))
codes += [Path.MOVETO]
codes += [Path.LINETO] * (len(xpts) -2)
codes += [Path.CLOSEPOLY]
clip = Path(vertices, codes)
for collection in contour.collections:
collection.set_clip_path(clip,transform=ax.transData)
plt.savefig("clip_after.png")
plt.show()
这是输出数字。
裁剪前。
剪辑后。
我有一组测量点,我想在它们之间进行插值,为此我使用 SciPy 的 griddata():
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
data = pd.DataFrame({
'time': [0, 1, 2, 3, 4, 0.1, 0.9, 2, 3.05, 4, 0, 1, 2.2, 3, 3.95],
'force': [1, 2, 4, 9, 16, 0, 0, 0, 0, 0, -1, -2, -4, -9, -16]
})
Times, Forces = np.meshgrid(
np.linspace(0, 4, 100),
np.linspace(-16, 16, 100)
)
data['work'] = data['time'] * data['force']
interpolation = griddata(
(data['time'], data['force']),
data['work'],
(Times, Forces),
method= 'linear'
)
fig, ax = plt.subplots()
contour = ax.contourf(
Times, Forces, interpolation
)
ax.scatter(data['time'], data['force'])
fig.show()
我的问题是,我的测量点已经沿着物理可能性的边界,但是插值仍然会为每个可跨越的区域进行插值,包括那些无法测量的区域。
如何限制插值或至少将插值图限制为 'within' 外点的形状?不幸的是 'time' 测量值有小偏差。
如有任何建议,我们将不胜感激!
首先,你需要得到所有点的凹多边形。其次,使用多边形裁剪轮廓填充。虽然,这可能有点复杂,但一些有用的包可以帮助完成这些任务。
下面是代码。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.interpolate import griddata
import matplotlib.path as mpath
import alphashape
from descartes import PolygonPatch
Path = mpath.Path
data = pd.DataFrame({
'time': [0, 1, 2, 3, 4, 0.1, 0.9, 2, 3.05, 4, 0, 1, 2.2, 3, 3.95],
'force': [1, 2, 4, 9, 16, 0, 0, 0, 0, 0, -1, -2, -4, -9, -16]
})
Times, Forces = np.meshgrid(
np.linspace(0, 4, 100),
np.linspace(-16, 16, 100)
)
data['work'] = data['time'] * data['force']
interpolation = griddata(
(data['time'], data['force']),
data['work'],
(Times, Forces),
method= 'linear')
fig, ax = plt.subplots()
plt.xlim(-.3,4.3)
plt.ylim(-18,18)
#contour = ax.contourf( Times, Forces, interpolation)
contour = ax.tricontourf( data['time'], data['force'], data['work'])
ax.scatter(data['time'], data['force'])
x = data['time']
y = data['force']
points = np.vstack([x, y]).T
alpha = 0.95 * alphashape.optimizealpha(points)
hull = alphashape.alphashape(points, alpha)
hull_pts = hull.exterior.coords.xy
ax.scatter(hull_pts[0], hull_pts[1], color='red')
ax.add_patch(PolygonPatch(hull, fill=False, color='red'))
plt.savefig("clip_before.png")
#make clip path
vertices = []
codes = []
xpts,ypts = hull_pts
## convert polygon to path for cliping contour fill
for ix,iy in zip(xpts,ypts):
vertices.append((ix,iy))
codes += [Path.MOVETO]
codes += [Path.LINETO] * (len(xpts) -2)
codes += [Path.CLOSEPOLY]
clip = Path(vertices, codes)
for collection in contour.collections:
collection.set_clip_path(clip,transform=ax.transData)
plt.savefig("clip_after.png")
plt.show()
这是输出数字。
裁剪前。
剪辑后。