Как подогнать часть кривой косинуса к данным в Python? - PullRequest
0 голосов
/ 22 марта 2019

Напишите этот код, чтобы попытаться построить график y = a (1 + cos (bx - pi)) + c для собранных нами данных, но при использовании np.cos он пытается вписать весь цикл cos в данные , что не соответствует нашим результатам. Любая помощь в том, как подогнать к нашим данным только часть кривой, будет потрясающей!

Попытка избежать использования 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 Ответ

1 голос
/ 22 марта 2019

Ваш вопрос: «Как подогнать к нашим данным только часть кривой?»Это может быть достигнуто путем определения пошаговой функции и подгонки части ваших данных к каждой соответствующей части функции.Вам необходимо определить предельные значения, которые разделяют части ваших данных, и выбрать, какие функции будут соответствовать каждой части.

Для того, чтобы подогнать кривую только к части данных, вам нужно толькоПередайте часть данных в Curve_fit, которую вы хотите подогнать.Вот рабочие примеры подгонки данных к ряду Маклаурина и функции косинуса:

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

Ряд Маклаурина:

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

В этом случае функция косинуса лучше, чем ряд Маклаурина, поскольку данные были сгенерированыиспользуя функцию косинуса.

...