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

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

本文介绍了不添加不必要极值的插值方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题一半是编程,一半是数学.我想通过曲线插入一组点,而不添加不必要的极值,保持接近线性插值",同时保持看起来平滑的曲线.我知道这个公式很模糊,但我希望它会从一个例子开始更清晰.让我们看看下面这段代码和结果:

This question is half programming but also half mathematics. I want to interpolate a set of points by a curve without adding unnecessary extremums staying "close to the linear interpolation" while keeping a curve that looks smooth.I know this formulation is vague, but I hope it will begin clearer with an example. Lets's look at the following piece of code and the result:

#! /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中).

I would have expected an interpolant that have only two extremums (around x~0 and x~2) while here we have 5 extremums. It is what most people will draw if we ask them to join the points with a smooth curve by hand. Is there a way to achieve this aim (in python).

更新:请注意,xfig与曲线有些接近(称为近似样条图"),其不便之处在于曲线不能精确地经过指定点.我希望曲线能精确地通过指定点,但是如果没有人知道更好的解决方案,我会欢迎使用xfig方法.

Update: Note that xfig has something close (called "approximate spline drawing") with the inconveniences that the curve does not pass exactly by the specified points. I would prefer a curve that passes exactly through the specified points but I would welcome the xfig method if no one knows a better solution.

推荐答案

虽然不完全相同(?),但您的问题与,那么也许相同的答案将是有用的.您可以尝试单调插值器. PchipInterpolator 类(您可以参考可以使用 scipy.interpolate 中较短的别名 pchip).这是脚本的一个版本,其中包含使用 pchip 创建的曲线:

While not exactly the same(?), your question is similar to this one, so perhaps the same answer would be useful. You can try a monotonic interpolator. The PchipInterpolator class (which you can refer to by its shorter alias pchip) in scipy.interpolate can be used. Here's a version of your script with a curve created using pchip included:

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插值

这篇关于不添加不必要极值的插值方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:27