【问题标题】:How to plot line (polygonal chain) with numpy/scipy/matplotlib with minimal smoothing如何使用 numpy/scipy/matplotlib 以最小平滑度绘制线(多边形链)
【发布时间】:2012-10-07 18:10:08
【问题描述】:

我正在尝试在 matplotlib 中绘制一条线。我正在寻找正确的插值类型。我想要这样的东西

每条线都经过平滑处理。我尝试了scipy和matplotlib的几种组合,比如

x_new = np.arange(x, x_length, 1)
tck = interpolate.splrep(x, y, s=3)
y_new = interpolate.splev(x_new, tck, der=0)
ax.plot(x_new, y_new, color+lstyle)

但我得到的最好结果是

这条线代表一个递增的变量..所以它是一个错误的表示。我可以搜索什么?

谢谢

编辑:我正在考虑自己实现一个方法,但我不知道它是否已经完成..伪代码如下

take x and y
calculate spline for each three points 
x[0], x[1], x[2] ... x[1], x[2], x[3] ... and so on
for each y[n] sums every computation done for it and divide by number of 
computations (i.e. y[1] is computed for triplette x[0..2] and x[1..3] so the 
sum is divided by two (average for each point is taken as its value)

【问题讨论】:

  • 你为什么要插值?这是为了美观还是您声称知道数据点之间的值?
  • @tcaswell 我出于两个原因进行插值,主要是为了美观

标签: python numpy matplotlib scipy spline


【解决方案1】:

对于这种类型的图,您需要 单调 插值。可以使用 scipy.interpolate 中的 PchipInterpolator 类(您可以通过其较短的别名 pchip 引用):

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


# Data to be interpolated.
x = np.arange(10.0)
y = np.array([5.0, 10.0, 20.0, 15.0, 13.0, 22.0, 20.0, 15.0, 12.0, 16.0])

# Create the interpolator.
interp = pchip(x, y)

# Dense x for the smooth curve.
xx = np.linspace(0, 9.0, 101)

# Plot it all.
plt.plot(xx, interp(xx))
plt.plot(x, y, 'bo')
plt.ylim(0, 25)
plt.grid(True)
plt.show()

结果:

【讨论】:

  • 这是我正在寻找的 :) 谢谢
  • 有N-D版本吗? :)
【解决方案2】:

我已经环顾了一下。你要的就叫

单调三次插值,

参见维基百科here。你在 mathexchange 上有一个关于它的讨论 here,我在 python here 中找到了一个实现。让我知道这是否有效!

【讨论】:

  • 我已经尝试过您的解决方案并且它有效,但是 scipy.interpolate 中有一个类似的功能。无论如何,我为您的努力投票赞成您的回答 :) 谢谢
【解决方案3】:

重要的是要了解插值不仅仅是用于可视化的一条线。它是一个数学模型,表示您认为系统的行为方式(生成您测量的数据的系统)。不同类型的插值代表对系统的不同假设。

因此,如果您知道您的系统是这样一个变量只能增加,您应该拟合一个适当的模型(即使用适当的插值)。查看您的数据,看起来二次多项式或指数函数可能很合适。黄土(局部回归)拟合也将起作用。您可以使用 numpy.polyfit() 等定制函数,也可以使用 scipy.optimize.curve_fit() 进行通用曲线拟合。如果您对系统有进一步的了解,您应该使用它来选择适合的模型。

【讨论】:

  • 我知道.. 我在插值方面有点 nescient,对不起。我尝试了多项式拟合,但这不是我要寻找的。无论如何,我为你的时间投票。谢谢:)
【解决方案4】:

你应该看看

scipy.interpolate.LSQUnivariateSpline 并使用 k 参数(样条的度数)

或 scipy.interpolate.UnivariateSpline 并使用 k 和 s 参数。

【讨论】:

  • 我试过了,但这不是我想要的。无论如何,我赞成你的回答,因为它对你的时间很有用。谢谢:)
【解决方案5】:

问题不是显示问题。这是一个插值问题。您正在使用样条函数进行插值。选择正确的插值方法很大程度上取决于您拥有的数据类型。你不能期望有一个插值函数在任何情况下都会表现正确(插值无法知道你的函数正在增加)。

【讨论】:

  • 尝试使用另一个插值函数,如scipy.interpolate.interp1d(),调整参数kind,直到它满足你
  • 谢谢,我会试试的。 @Nicolas 是的,我错了。我会相应地更改这篇文章的标题和内容
  • @flebool 我尝试了所有可能的 kind 值,但没有一个让我满意.. :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-16
  • 2015-08-11
  • 1970-01-01
  • 2017-06-01
  • 2019-08-26
  • 2013-01-20
相关资源
最近更新 更多