如何将余弦曲线的一部分拟合到Python中的数据?

时间:2019-03-22 20:15:56

标签: python plot graph cos

编写这段代码,尝试将y = a(1 + cos(bx-pi))+ c的aa图绘制到我们收集的数据中,但是当使用np.cos时,它将尝试将整个cos周期拟合到数据上,这与我们的结果不符。对于如何仅将曲线的一部分拟合到我们的数据的任何帮助将是fab!

试图通过使用maclaurin系列扩展来避免使用cos,但这仍然行不通。

x_data = w
y_data = mean
e = error

from scipy import optimize

def test_func(x, a, b, c):
    y = (a/2)*(1 + (1 - (1/2)*(b*x - np.pi)**2 + (1/24)*(b*x - np.pi)**4)) + c
    return y

params, params_covariance = optimize.curve_fit(test_func, x_data, y_data)
print(params)

a = params[0]
b = params[1]
c = params[2]

figure(num=None, figsize=(12, 6), dpi=80, facecolor='w', edgecolor='k')
plt.errorbar(x_data, y_data, yerr=e, fmt='o', marker='o', label='Data', markersize=3, color='k', elinewidth=1, capsize=2, markeredgewidth=1)
plt.plot(x_data, test_func(x_data, params[0], params[1], params[2]), label='Fitted function')
plt.legend(loc='best')
plt.ylabel('Interference intensity, $I$')
plt.xlabel('Rotational velocity of interferometer, $w$')
plt.show()

1 个答案:

答案 0 :(得分:1)

您的问题是“如何仅将曲线的一部分拟合到我们的数据中”。这可以通过定义分段功能并将数据的一部分拟合到该功能的每个相应部分来实现。您需要定义用于分隔数据各部分的临界值,并选择适合每个部分的函数。

为了仅将曲线拟合到数据的一部分,您只需要将数据的一部分传递到想要拟合的curve_fit即可。以下是一些使数据既符合Maclaurin系列又符合余弦函数的工作示例:

from scipy import optimize

# Generate sample data
np.random.seed(0)
x_data = np.linspace(-np.pi,3*np.pi,101)
y_data = np.cos(x_data) + np.random.rand(len(x_data))/4
idx = (x_data < 0) | (x_data > 2*np.pi)
y_data[idx] = 1 + np.random.rand(sum(idx))/4
e = np.random.rand(len(x_data))/10

# Select part of data to fit
fit_part = ~idx
x_data_to_fit = x_data[fit_part]
y_data_to_fit = y_data[fit_part]

余弦函数:

def test_func(x, a, b):
    y = a*np.cos(b*x)
    return y

params, params_covariance = optimize.curve_fit(test_func, x_data_to_fit, y_data_to_fit)
print(params)

a = params[0]
b = params[1]

plt.figure(num=None, figsize=(12, 6), dpi=80, facecolor='w', edgecolor='k')
plt.title('Cosine Function Fit')
plt.errorbar(x_data, y_data, yerr=e, fmt='o', marker='o', label='Data', markersize=3, color='k', elinewidth=1, capsize=2, markeredgewidth=1)
plt.plot(x_data_to_fit, test_func(x_data_to_fit, a, b), label='Fitted function')
plt.legend(loc='best')
plt.ylabel('Interference intensity, $I$')
plt.xlabel('Rotational velocity of interferometer, $w$')
plt.show()

Cosine Function fit

Maclaurin系列:

def test_func(x, a, b, c):
    y = (a/2)*(1 + (1 - (1/2)*(b*x - np.pi)**2 + (1/24)*(b*x - np.pi)**4)) + c
    return y

params, params_covariance = optimize.curve_fit(test_func, x_data_to_fit, y_data_to_fit)
print(params)

a = params[0]
b = params[1]
c = params[2]

plt.figure(num=None, figsize=(12, 6), dpi=80, facecolor='w', edgecolor='k')
plt.title('MacLaurin Series Fit')
plt.errorbar(x_data, y_data, yerr=e, fmt='o', marker='o', label='Data', markersize=3, color='k', elinewidth=1, capsize=2, markeredgewidth=1)
plt.plot(x_data_to_fit, test_func(x_data_to_fit, a, b, c), label='Fitted function')
plt.legend(loc='best')
plt.ylabel('Interference intensity, $I$')
plt.xlabel('Rotational velocity of interferometer, $w$')
plt.show()

Maclaurin series fit

在这种情况下,由于数据是使用余弦函数生成的,因此余弦函数与Maclaurin系列的数据匹配更好。