Нужна плавная кривая от lmfit на большем количестве точек данных.

Вопрос или проблема

Я подстраиваю лоренциан к следующим данным. Если я строю график наилучшей подгонки, он отображает результаты только для определенных значений x, где у меня есть данные. Я пытался получить гладкую кривую, которая была бы более адекватным представлением, но что-то не так.

данные:

y_means = [2.32070822e-06, 1.90175015e-06, 2.09473380e-06, 2.80934411e-06,
   2.38255275e-06, 3.02204121e-06, 3.84290466e-06, 3.84136311e-06,
   7.53941486e-06, 8.68364774e-06, 1.20078494e-05, 2.20557048e-05,
   3.73314724e-05, 6.03141332e-05, 9.84530711e-05, 1.58565010e-04,
   3.61269554e-04, 7.53586472e-04, 3.56518897e-04, 1.60734633e-04,
   1.06442283e-04, 5.41622644e-05, 2.73085592e-05, 2.54361900e-05,
   9.10802093e-06, 4.81356192e-06, 6.49884117e-06, 4.94871197e-06,
   3.27389990e-06, 2.65197533e-06, 2.52672943e-06, 2.56496345e-06,
   2.11445845e-06, 1.96091323e-06, 2.60823301e-06]

all_xsclices = [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
   17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
   34]

код:

# подгонка лоренциана
from lmfit.models import LorentzianModel

model = LorentzianModel()
params = model.guess(y_means, x=all_xslices)
all_xslices_fit = np.linspace(min(all_xslices), max(all_xslices), 100)
result = model.fit(y_means, params, x=all_xslices)
result_smooth = model.eval(x=all_xslices_fit)


# построение распада вдоль оси y: логарифмическая ось
plt.figure(figsize=(8, 5), dpi=300)
plt.scatter(all_xslices, y_means, marker=".", s = 200, c="g", label = "")      
# plt.plot(all_xslices, lorentzian(all_xslices,*popt), 'g', label="Лоренц 1")
plt.plot(all_xslices, result.best_fit, 'g', label="Лоренц")
plt.plot(all_xslices_fit, result_smooth, 'r', label="Лоренц")
plt.xlabel("длина y", fontsize = 15)
plt.ylabel("амплитуда FFT", fontsize = 15)
plt.xticks(fontsize = 15)
plt.yticks(fontsize = 15)
plt.yscale('log')
plt.subplots_adjust(right=0.96,left=0.15,top=0.96,bottom=0.12)
plt.legend(loc="best")
plt.show()

Вот текущий результат:

график данных с подгонкой

Немного чтения документации и проб и ошибок, и я обнаружил, что вам нужно сделать следующее:

result_smooth = result.eval(x=all_xslices_fit)

Уменьшение количества точек данных, чтобы это было более очевидно:

вставьте описание изображения здесь

Ответ или решение

В данной задаче вы пытаетесь выполнить подгонку Лоренцианской модели к вашим данным и получить гладкую кривую, представляющую собой лучший подход к вашим данным. Рассмотрим подробнее, как достичь желаемого результата.

Проблема

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

Решение

Основная идея, чтобы получить гладкую кривую, заключается в создании дополнительной выборки X, по которой можно оценить результаты подгонки. Прежде всего, вам нужно убедиться, что вы вызываете метод eval() для полученного объекта result, а не для вашего доступного набора данных. Это обеспечит получение гладкой кривой.

Исправленный код

Вот как должен выглядеть ваш код с учетом необходимых изменений:

# Импорт необходимых библиотек
import numpy as np
import matplotlib.pyplot as plt
from lmfit.models import LorentzianModel

# Данные
y_means = [2.32070822e-06, 1.90175015e-06, 2.09473380e-06, 2.80934411e-06,
   2.38255275e-06, 3.02204121e-06, 3.84290466e-06, 3.84136311e-06,
   7.53941486e-06, 8.68364774e-06, 1.20078494e-05, 2.20557048e-05,
   3.73314724e-05, 6.03141332e-05, 9.84530711e-05, 1.58565010e-04,
   3.61269554e-04, 7.53586472e-04, 3.56518897e-04, 1.60734633e-04,
   1.06442283e-04, 5.41622644e-05, 2.73085592e-05, 2.54361900e-05,
   9.10802093e-06, 4.81356192e-06, 6.49884117e-06, 4.94871197e-06,
   3.27389990e-06, 2.65197533e-06, 2.52672943e-06, 2.56496345e-06,
   2.11445845e-06, 1.96091323e-06, 2.60823301e-06]

all_xslices = np.arange(35)  # Создание диапазона от 0 до 34

# Подгонка Лоренцианской модели
model = LorentzianModel()
params = model.guess(y_means, x=all_xslices)
result = model.fit(y_means, params, x=all_xslices)

# Создаем гладкие точки для оси X
all_xslices_fit = np.linspace(min(all_xslices), max(all_xslices), 100)

# Оценка подгонки для гладких точек
result_smooth = result.eval(x=all_xslices_fit)

# Построение графика
plt.figure(figsize=(8, 5), dpi=300)
plt.scatter(all_xslices, y_means, marker=".", s=200, c="g", label="Данные")      
plt.plot(all_xslices_fit, result_smooth, 'r', label="Лоренцианская подгонка")
plt.xlabel("длина в оси Y", fontsize=15)
plt.ylabel("амплитуда FFT", fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.yscale('log')
plt.subplots_adjust(right=0.96, left=0.15, top=0.96, bottom=0.12)
plt.legend(loc="best")
plt.show()

Объяснение изменений

  1. Выборка данных для подгонки: Важно использовать result.eval(x=all_xslices_fit) для вычисления подгонки, так как это обеспечивает плавность кривой. Вы создаете новые значения по оси X, что позволяет получить оценку подгонки в этих точках.

  2. Отображение данных: На графике вы отображаете исходные данные в виде точек и добавляете гладкую кривую подгонки, что позволяет лучше визуализировать модель.

  3. Конфигурация графика: Установка шкалы по оси Y в логарифмическом масштабе дает четкое представление о различиях в амплитудах FFT.

В результате, корректная подгонка Лоренцианской модели и применение нового распределения оси X обеспечат более гладкую и точную кривую, отражающую суть ваших данных.

Оцените материал
Добавить комментарий

Капча загружается...