首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不添加不必要极值的插值方法

不添加不必要极值的插值方法
EN

Stack Overflow用户
提问于 2014-01-04 09:07:37
回答 3查看 877关注 0票数 2

这个问题既是编程的一半,也是数学的一半。我想用曲线插值一组点,而不增加不必要的极值,“接近线性插值”,同时保持曲线光滑,我知道这个公式很模糊,但我希望它能以一个例子开始更清楚。让我们看看下面的代码及其结果:

代码语言:javascript
复制
#! /usr/bin/python

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

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

list_points=[(-3,0.1),(-2,0.15),(0,4),(2,-6),(4,-2),(7,-0.15),(8,-0.1)]
(xp,yp)=zip(*list_points)
fun=interp1d(xp,yp,kind='cubic')

xc=np.linspace(min(xp),max(xp),300)

plt.plot(xp,yp,'o',color='black',ms=5)
plt.plot(xc,fun(xc))
fun2=interp1d(xp,yp,kind='linear')
plt.plot(xc,fun2(xc))

plt.show()

我本以为只有两个极值( x~0和x~2左右)的插值,而这里我们有5个极值。如果我们要求他们用一条平滑的曲线加入这些点,这就是大多数人所画的。有没有办法达到这个目的(在python中)。

更新:请注意,xfig有一些相近的东西(称为“近似样条图”),其不便之处在于曲线没有经过指定的点。我更喜欢精确地通过指定点的曲线,但如果没有人知道更好的解决方案,我会欢迎使用xfig方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-04 15:13:47

虽然不完全相同(?),但您的问题类似于这一个,因此,也许相同的答案将是有用的。你可以试试单调内插器。可以在PchipInterpolator中使用scipy.interpolate类(您可以使用其较短的别名pchip)。下面是一个使用pchip创建曲线的脚本版本:

代码语言:javascript
复制
import numpy as np
from scipy.interpolate import interp1d, pchip
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

list_points = [(-3,0.1),(-2,0.15),(0,4),(2,-6),(4,-2),(7,-0.15),(8,-0.1)]
(xp,yp) = zip(*list_points)
fun = interp1d(xp,yp,kind='cubic')

xc = np.linspace(min(xp),max(xp),300)

plt.plot(xp,yp,'o',color='black',ms=5)
plt.plot(xc,fun(xc))
fun2 = interp1d(xp,yp,kind='linear')
plt.plot(xc,fun2(xc))

p = pchip(xp, yp)
plt.plot(xc, p(xc), 'r', linewidth=3, alpha=0.6)

plt.show()

它生成的图如下所示。

  • 黑点:原始数据
  • 绿线:线性插值
  • 蓝线:三次样条插值
  • 红线: pchip插值

票数 5
EN

Stack Overflow用户

发布于 2014-01-04 09:36:01

你试过二次样条吗--尽管我不相信这会有帮助。另一个模糊选项是添加额外的数据点非常接近您的最大值。例如,在(-0.05,4)和(1.95,-6) -这将导致三次样条算法使那些面积在最大值附近变平。这取决于你想要达到什么目的。有一些技术可以限制最大和最小的三次样条,但我还不太熟悉这些或python / matplotlib来帮助您,对不起!

票数 0
EN

Stack Overflow用户

发布于 2014-01-04 09:57:27

您可以使用线性插值,然后对其进行过滤(使用均值滤波器):

代码语言:javascript
复制
size = 51.0;    
fun = interpolate.interp1d(xp, yp,kind='linear');
filt = (1/size)*np.ones(size);
yc = signal.convolve( fun(xc),filt,'same');

使用参数size,可以控制平滑度。

这是一个完整的代码:

代码语言:javascript
复制
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
from scipy import interpolate,signal

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

list_points=[(-3,0.1),(-2,0.15),(0,4),(2,-6),(4,-2),(7,-0.15),(8,-0.1)]
(xp,yp)=zip(*list_points)
xc=np.linspace(min(xp),max(xp),300)

########################################################
size = 41.0;#Put here any odd number
fun = interpolate.interp1d(xp, yp,kind='linear');
filt = (1/size)*np.ones(size);
yc = signal.convolve(fun(xc),filt,'same');
########################################################

plt.plot(xp,yp,'o',color='black',ms=5)
plt.plot(xc,yc)
plt.plot(xc,fun(xc))
plt.show()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20919038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档