简体   繁体   中英

fitting the python plot with exponential function

I am trying to fit my python plot with an exponential function. I have attached the code here. Any inputs is highly appreciated.

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

x=[0.21, 0.43, 0.50, 0.65, 0.86, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0]
y=[43, 33, 30, 24, 18, 16, 14, 13, 14, 13, 13]
yerr= [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
xerr=[0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01, 0.01,0.01,0.01]
plt.ylim (0,60)
plt.xlabel ('Thickness (d) [mm]')
plt.ylabel ('Counts')
def exponenial_func(x, a, b, c):
    return a*np.exp(-b*x)+c
popt, pcov = curve_fit(exponenial_func, x, y, p0=(1, 1e-6, 1))
yy = exponenial_func(x, *popt)

plt.plot(x,y,'o', x, yy)
#plt.errorbar(x,y,yerr=yerr,xerr=xerr, fmt= '.')
plt.show()

I always get an error msg:

Traceback (most recent call last):
  File "/home/manisha/Desktop/Moessbauer effect/countsvsd.py", line 16, in <module>
    yy = exponenial_func(x, *popt)
  File "/home/manisha/Desktop/Moessbauer effect/countsvsd.py", line 14, in exponenial_func
    return a*np.exp(-b*x)+c
TypeError: 'numpy.float64' object cannot be interpreted as an index

Since I am a new programmer I don't know what it means. Please help.

Your problem lies in the way you are trying to define yy ; you can't call your function on the list x . Instead, call it on each individual item in x , for instance, in a list iteration like this:

yy = [exponenial_func(i, *popt) for i in x]

Then, everything else in your code works fine: 指数的

[EDIT] : to extrapolate the zero in your exponential function (as per your comment), you can do this:

xx = x.copy()    
yy = [exponenial_func(i, *popt) for i in [0]+xx]
plt.plot(x,y,'o',[0]+xx,yy)

Or, to just see the value, do this:

exponenial_func(0, *popt)

While the answer of @sacul works, it does not tell you yet what is happening.

if you have a list , you can append copies of this list to itself by multiplication.

my_list = [1, 2]
print(my_list * 2) #[1, 2, 1, 2]

So, when you try to multiply the list with a float , it will become undefined what the behaviour of the copying should be, and an Exception is thrown.

print(my_list * 1.5) #TypeError: can't multiply sequence by non-int of type 'float'

Trying to do so with a floating point object, will instead be caught before evaluation time and raise the following error:

a = 1.5
print(my_list*a) #TypeError: 'numpy.float64' object cannot be interpreted as an integer

So there are multiple solutions to your problem. You can feed the individual items in your list to the function one by one, like in the answer provided by @sacul, or convert your container to a type which will yield array behaviour like you expected it to:

def exponenial_func(x, a, b, c):
    if isinstance(x,list):
        x = np.array(x)
    return a*np.exp(-b*x)+c

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM