2015-07-04 39 views
4

我有以下的圖,我想數字化使用Python和Matplotlib高品質的出版物等級圖:直觀插補

enter image description here

我用了一個數字化計劃,以抓幾個從3個數據集合中的一個樣本:

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, 
]) 

我已經嘗試3種不同,通過這些數據點擬合的曲線的方法。第一種方法是使用scipy.interpolate import spline

這導致(與繪製爲藍色標記的實際數據點)繪製通過點的樣條:

enter image description here

這是obvisously沒有好處。

我的第二次嘗試是使用scipy.optimize import curve_fit使用一系列不同的有序polinimials繪製曲線擬合。即使到四階多項式的答案是沒有用的(低階者甚至再多也沒用):

enter image description here

最後,我用scipy.interpolate import interp1d嘗試和數據點之間插入。直線插補顯然產生預期的效果,但線是直的,這運動的全部目的是爲了得到一個不錯的平滑曲線:

enter image description here

如果我再使用三次插值,我得到一個rubish結果,但是二次插值產生一個稍微好一點的結果是:

enter image description here

但是這還沒有應用,並且我不認爲interp1d可以做更高階插值。

有沒有人有這樣做的好方法?也許我會更好地嘗試在IPE或其他方面做到這一點?

謝謝!

回答

7

標準三次樣條不太適合非常不均勻間隔的數據點之間的合理外觀插值。幸運的是,還有很多其他插值算法和Scipy provides a number of them。這裏有幾個應用到您的數據:

enter image description here

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() 

我建議找過這些,和其他人也不在少數,並找到一個符合你的想法看起來正確。另外,你可能想要再抽取幾點。例如,我認爲PCHIP算法希望保持數據點之間的擬合單調性,因此數字化最小點會很有用(並且無論您使用哪種算法,這可能都是一個好主意)。

+1

謝謝@ tom10徹底的回答!我一定會看看,你做的所有適合看起來足夠好,爲我的目的! – Jonny