【问题标题】:fit exponential to range and plot results and fit将指数拟合到范围并绘制结果并拟合
【发布时间】:2020-08-04 07:01:29
【问题描述】:

我有两个数据帧,对应于我从文件 (Pos10.csv) 中获取的强度与时间的关系。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

csv_file="Pos10.csv"
df=pd.read_csv(csv_file)
df_01=df.iloc[:,0]
df_time=df_01*10
df_02=df.iloc[:,2]
df_intensity=df_02
plt.scatter(df_time,df_intensity)#scatter plot
plt.xlabel("Time (min)")
plt.ylabel("Normalized intensity")
plt.title("Kinetic exponential decay")
plt.show

This is how my data is looking after running the code above

df_intensity和df_time对应的值可以从下面得到。

df_intensity [2.80816437e-04 4.68942336e-03 1.86014497e-03 4.91956615e-03 1.71023544e-03 1.27739808e-03 2.69837148e-03 3.03619576e-03 2.93695988e-03 1.00000000e+00 9.86672832e-01 9.35505121e-01 9.10113403e-01 8.63508432e-01 8.13620231e-01 7.95973135e-01 7.86302914e-01 7.65104440e-01 7.51126961e-01 7.23412701e-01 6.78247705e-01 6.94902443e-01 6.83302401e-01 6.61177022e-01 6.58689791e-01 6.40576075e-01 6.31106438e-01 6.36152688e-01 6.24960147e-01 6.03523085e-01 5.75500561e-01 5.79641019e-01 5.79132172e-01 5.63659819e-01 5.61770115e-01 5.59135085e-01 5.48466172e-01 5.32841799e-01 5.28933594e-01 5.22816863e-01 5.11256939e-01 5.06882114e-01 5.00026393e-01 4.97034536e-01 4.89032323e-01 4.82624219e-01 4.79193191e-01 4.73355165e-01 4.61712896e-01 4.59367128e-01 4.59443139e-01 4.51200226e-01 4.44606319e-01 4.46339779e-01 4.39093449e-01 4.30048203e-01 4.29030508e-01 4.28589225e-01 4.19683332e-01 4.13034528e-01 4.14086006e-01 4.11921819e-01 4.04496019e-01 3.96624713e-01 3.98299055e-01 3.89500844e-01 3.82822480e-01 3.81116467e-01 3.85759440e-01 3.83958414e-01 3.75875968e-01 3.75905527e-01 3.75681719e-01 3.69588213e-01 3.65200720e-01 3.66254310e-01 3.66418999e-01 3.61814032e-01 3.55682521e-01 3.56459517e-01 3.54392455e-01 3.48763458e-01 3.47853443e-01 3.49859275e-01 3.48366514e-01 3.40265065e-01 3.41580469e-01 3.40355856e-01 3.37516020e-01 3.33388230e-01]

df_time [ 20. 30. 40. 50. 60. 70. 80. 90. 100. 110. 120. 130. 140. 150. 160. 170. 180. 190. 200. 210. 220. 230. 240. 250. 260. 270. 280. 290. 300. 310. 320. 330. 340. 350. 360. 370. 380. 390. 400. 410. 420. 430. 440. 450. 460. 470. 480. 490. 500. 510. 520. 530. 540. 550. 560. 570. 580. 590. 600. 610. 620. 630. 640. 650. 660. 670. 680. 690. 700. 710. 720. 730. 740. 750. 760. 770. 780. 790. 800. 810. 820. 830. 840. 850. 860. 870. 880. 890. 900. 910.]

有了这些数据...我想: 1) 拟合从最大强度点(y=1,与 x 位置 y=1 的位置无关,因为它因迹线而异)到迹线末端的指数衰减。 2)用拟合绘制我的数据并从拟合中获得系数。

我对 python 非常缺乏经验......到目前为止,我已经设法合并以下代码来拟合我的数据,但我还没有设法将拟合限制在范围内(从最大值点到曲线的末端或绘制它)

from pylab import *
from scipy.optimize import curve_fit
def func(x, a, c, d):
  return a*np.exp(-c*x)+d

popt, pcov = curve_fit(func, df_time, df_intensity)

【问题讨论】:

    标签: python curve-fitting


    【解决方案1】:

    正如您所说,您需要将第一个点与指数衰减开始的点分开。在这里,我通过使用最大强度点作为衰减的第一个点来做到这一点。

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    def func(x, a, c, d):
        return a*np.exp(-c*x)+d
    
    df_intensity = '2.80816437e-04 4.68942336e-03 1.86014497e-03 4.91956615e-03 1.71023544e-03 1.27739808e-03 2.69837148e-03 3.03619576e-03 2.93695988e-03 1.00000000e+00 9.86672832e-01 9.35505121e-01 9.10113403e-01 8.63508432e-01 8.13620231e-01 7.95973135e-01 7.86302914e-01 7.65104440e-01 7.51126961e-01 7.23412701e-01 6.78247705e-01 6.94902443e-01 6.83302401e-01 6.61177022e-01 6.58689791e-01 6.40576075e-01 6.31106438e-01 6.36152688e-01 6.24960147e-01 6.03523085e-01 5.75500561e-01 5.79641019e-01 5.79132172e-01 5.63659819e-01 5.61770115e-01 5.59135085e-01 5.48466172e-01 5.32841799e-01 5.28933594e-01 5.22816863e-01 5.11256939e-01 5.06882114e-01 5.00026393e-01 4.97034536e-01 4.89032323e-01 4.82624219e-01 4.79193191e-01 4.73355165e-01 4.61712896e-01 4.59367128e-01 4.59443139e-01 4.51200226e-01 4.44606319e-01 4.46339779e-01 4.39093449e-01 4.30048203e-01 4.29030508e-01 4.28589225e-01 4.19683332e-01 4.13034528e-01 4.14086006e-01 4.11921819e-01 4.04496019e-01 3.96624713e-01 3.98299055e-01 3.89500844e-01 3.82822480e-01 3.81116467e-01 3.85759440e-01 3.83958414e-01 3.75875968e-01 3.75905527e-01 3.75681719e-01 3.69588213e-01 3.65200720e-01 3.66254310e-01 3.66418999e-01 3.61814032e-01 3.55682521e-01 3.56459517e-01 3.54392455e-01 3.48763458e-01 3.47853443e-01 3.49859275e-01 3.48366514e-01 3.40265065e-01 3.41580469e-01 3.40355856e-01 3.37516020e-01 3.33388230e-01'
    df_time = '20. 30. 40. 50. 60. 70. 80. 90. 100. 110. 120. 130. 140. 150. 160. 170. 180. 190. 200. 210. 220. 230. 240. 250. 260. 270. 280. 290. 300. 310. 320. 330. 340. 350. 360. 370. 380. 390. 400. 410. 420. 430. 440. 450. 460. 470. 480. 490. 500. 510. 520. 530. 540. 550. 560. 570. 580. 590. 600. 610. 620. 630. 640. 650. 660. 670. 680. 690. 700. 710. 720. 730. 740. 750. 760. 770. 780. 790. 800. 810. 820. 830. 840. 850. 860. 870. 880. 890. 900. 910.'
    df_intensity = np.array([float(i) for i in df_intensity.split(' ')])
    df_time = np.array([float(i) for i in df_time.split(' ')])
    
    # starting point for the decay to fit
    decay_start = np.argmax(df_intensity)
    
    # use only decay points in the fit
    guess = [1, 0.001, 0]
    popt, pcov = curve_fit(func, df_time[decay_start:],
                           df_intensity[decay_start:],
                           p0=guess)
    
    # get the fit curve
    fit = func(df_time[decay_start:], *popt)
    
    # plot the fit and data
    plt.plot(df_time[decay_start:], fit, label='fit', c='r')
    plt.scatter(df_time, df_intensity, label='data')
    plt.legend()
    plt.show()
    
    print('Fit parameters: {}'.format(popt))
    

    返回

    Fit parameters: [0.99347494 0.00407874 0.32579395]
    

    【讨论】:

    • 感谢您的建议!我会试试看。但是,我确实有以类似于跟踪开始的值结束的跟踪,如果我正确理解它,那么将从达到这些低值的端点切断拟合。但也许我可以使用查找最大值来定义从最大值到跟踪结束的衰减点
    • 我们总是可以实现一个更复杂的阈值来保存这些点。如“如果它们在数据集的前半部分,则切出小于最大强度 10% 的点”
    • 那行得通!你知道我怎么能做到这一点...我对 Python 非常缺乏经验...
    • 有没有办法在这里共享数据集?我知道如果没有示例数据集,很难提供帮助
    • 它有多大?你可以打印(df_intensity, df_time) 并将结果粘贴到问题中吗?
    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    相关资源
    最近更新 更多