Вопрос или проблема
Я подстраиваю лоренциан к следующим данным. Если я строю график наилучшей подгонки, он отображает результаты только для определенных значений 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()
Объяснение изменений
-
Выборка данных для подгонки: Важно использовать
result.eval(x=all_xslices_fit)
для вычисления подгонки, так как это обеспечивает плавность кривой. Вы создаете новые значения по оси X, что позволяет получить оценку подгонки в этих точках. -
Отображение данных: На графике вы отображаете исходные данные в виде точек и добавляете гладкую кривую подгонки, что позволяет лучше визуализировать модель.
-
Конфигурация графика: Установка шкалы по оси Y в логарифмическом масштабе дает четкое представление о различиях в амплитудах FFT.
В результате, корректная подгонка Лоренцианской модели и применение нового распределения оси X обеспечат более гладкую и точную кривую, отражающую суть ваших данных.