Smooth curved line between 3 points in plot

扶醉桌前 提交于 2019-12-06 14:12:49

问题


I have 3 data points on the x axis and 3 on the y axis:

x = [1,3,5]
y=[0,5,0]

I would like a curved line that starts at (1,0), goes to the highest point at (3,5) and then finishes at (5,0)

I think I need to use interpolation, but unsure how. If I use spline from scipy like this:

import bokeh.plotting as bk
from scipy.interpolate import spline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
y_smooth = spline(x,y,xvals)
p.line(xvals, y_smooth)

bk.show(p)

I get the highest point before (3,5) and it looks unbalanced:


回答1:


The issue is due to that spline with no extra argument is of order 3. That means that you do not have points/equations enough to get a spline curve (which manifests itself as a warning of an ill-conditioned matrix). You need to apply a spline of lower order, such as a cubic spline, which is of order 2:

import bokeh.plotting as bk
from scipy.interpolate import spline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
y_smooth = spline(x,y,xvals, order=2) # This fixes your immediate problem
p.line(xvals, y_smooth)

bk.show(p)

In addition, spline is deprecated in SciPy, so you should preferably not use it, even if it is possible. A better solution is to use the CubicSpline class:

import bokeh.plotting as bk
from scipy.interpolate import CubicSpline
p = bk.figure()
xvals=np.linspace(1, 5, 10)
spl = CubicSpline(x, y) # First generate spline function
y_smooth = spl(xvals) # then evalute for your interpolated points
p.line(xvals, y_smooth)

bk.show(p)

Just to show the difference (using pyplot):

As can be seen, the CubicSpline is identical to the spline of order=2




回答2:


You can use quadratic interpolation. This is possible by making use of scipy.interpolate.interp1d.

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



x = [1, 3, 5]
y = [0, 5, 0]

f = interp1d(x, y, kind='quadratic')

x_interpol = np.linspace(1, 5, 1000)
y_interpol = f(x_interpol)

plt.plot(x_interpol, y_interpol)
plt.show()

Check the documentation for more details.




回答3:


use pchip_interpolate():

import numpy as np
from scipy import interpolate

x = [1,3,5]
y=[0,5,0]

x2 = np.linspace(x[0], x[-1], 100)
y2 = interpolate.pchip_interpolate(x, y, x2)
pl.plot(x2, y2)
pl.plot(x, y, "o")

the result:



来源:https://stackoverflow.com/questions/48875339/smooth-curved-line-between-3-points-in-plot

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!