Intuitive interpolation between unevenly spaced points

倾然丶 夕夏残阳落幕 提交于 2019-11-29 15:52:16

问题


I have the following graph that I want to digitize to a high-quality publication grade figure using Python and Matplotlib:

I used a digitizer program to grab a few samples from one of the 3 data sets:

x_data = np.array([
1,
1.2371,
1.6809,
2.89151,
5.13304,
9.23238,
])

y_data = np.array([
0.0688824,
0.0490012,
0.0332843,
0.0235889,
0.0222304,
0.0245952,
])

I have already tried 3 different methods of fitting a curve through these data points. The first method being to draw a spline through the points using scipy.interpolate import spline

This results in (with the actual data points drawn as blue markers):

This is obvisously no good.

My second attempt was to draw a curve fit using a series of different order polinimials using scipy.optimize import curve_fit. Even up to a fourth order polynomial the answer is useless (the lower order ones were even more useless):

Finally, I used scipy.interpolate import interp1d to try and interpolate between the data points. Linear interpolation obviously yields expected results but the line are straight and the whole purpose of this exercise is to get a nice smooth curve:

If I then use cubic interpolation I get a rubish result, however quadratic interpolation yields a slightly better result:

But it's not quite there yet, and I don't think interp1d can do higher order interpolation.

Is there anyone out there who has a good method of doing this? Maybe I would be better off trying to do it in IPE or something?

Thank you!


回答1:


A standard cubic spline is not very good at reasonable looking interpolations between data points that are very unevenly spaced. Fortunately, there are plenty of other interpolation algorithms and Scipy provides a number of them. Here are a few applied to your data:

import numpy as np
from scipy.interpolate import spline, UnivariateSpline, Akima1DInterpolator, PchipInterpolator
import matplotlib.pyplot as plt

x_data = np.array([1, 1.2371, 1.6809, 2.89151, 5.13304, 9.23238])

y_data = np.array([0.0688824, 0.0490012, 0.0332843, 0.0235889, 0.0222304, 0.0245952])

x_data_smooth = np.linspace(min(x_data), max(x_data), 1000)
fig, ax = plt.subplots(1,1)

spl = UnivariateSpline(x_data, y_data, s=0, k=2)
y_data_smooth = spl(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'b')

bi = Akima1DInterpolator(x_data, y_data)
y_data_smooth = bi(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'g')

bi = PchipInterpolator(x_data, y_data)
y_data_smooth = bi(x_data_smooth)
ax.plot(x_data_smooth, y_data_smooth, 'k')

ax.plot(x_data_smooth, y_data_smooth)
ax.scatter(x_data, y_data)

plt.show()

I suggest looking through these, and also a few others, and finding one that matches what you think looks right. Also, though, you may want to sample a few more points. For example, I think the PCHIP algorithm wants to keep the fit monotonic between data points, so digitizing your minimum point would be useful (and probably a good idea regardless of the algorithm you use).



来源:https://stackoverflow.com/questions/31221444/intuitive-interpolation-between-unevenly-spaced-points

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