I can't fit an exponential function in a data set

Question:

I have a data set from a laboratory that I did in which I studied the characteristics of current and voltage in a solar panel. The data is a bit inconsistent but it is visible that it is an exponential function. I need to determine the exponential function for my data set.

The exponential formula is this $I=I_s(exp{frac{ecdot U}{kcdot T}}-1)$. Where e, k, and T are constants.

My code that describes the formula and the data set:

data = [
    (64.5, -2.84),
    (85.4, -2.6),
    (111.7, -2.6),
    (137.1, -2.6),
    (162.3, -2.56),
    (188.1, -2.56),
    (214, -2.56),
    (238, -2.56),
    (262.2, -2.52),
    (283.5, -2.52),
    (367.3, -1.72),
    (388, -0.92),
    (393, -0.64),
    (395, -0.48),
    (399.3, -0.38),
    (400, -0.2)
]

# unpack the data into separate arrays
U_1, I_1 = zip(*data)
def exponential(x, a, b):
    print(a*(np.exp(b*x)-1))
    return a*(np.exp(b*x)-1)

I plot it like this:

# fit the curve to the data, using the weights
params, params_covariance = curve_fit(exponential, U_1, I_1,p0=initial_params)
# plot the data and the fit
plt.plot( U_1, I_1,'bo', label='data')

# compute the fitted curve point by point
U_1_fit = np.linspace(min(U_1), max(U_1), 1000)
I_1_fit = exponential(U_1_fit, *params)
plt.plot(U_1_fit, I_1_fit, 'r', label='fit')

The exponential function was in the millions so I gave an initial parameter:

initial_params = [0, -3]

It is stuck, for some reason, on the value -1.89125. I tried different methods and they didn’t work or gave me the same answer of -1.89125. I just need to be an exponential that makes sense for my data.

Asked By: Ghidic Vladislav

||

Answers:

You need to add a third parameter c to make your model more flexible. Then, the initial value for b is wrong, it cannot be negative.

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

data = [
    (64.5, -2.84),
    (85.4, -2.6),
    (111.7, -2.6),
    (137.1, -2.6),
    (162.3, -2.56),
    (188.1, -2.56),
    (214, -2.56),
    (238, -2.56),
    (262.2, -2.52),
    (283.5, -2.52),
    (367.3, -1.72),
    (388, -0.92),
    (393, -0.64),
    (395, -0.48),
    (399.3, -0.38),
    (400, -0.2)
]

data = np.array(data)
x = data[:, 0]
y = data[:, 1]

def f(x, a, b, c):
    return a * (np.exp(b * x) - 1) + c

p0 = [1, 0.02, 0]
popt, pcov = curve_fit(f, x, y, p0=p0)

plt.scatter(x, y)
xx = np.linspace(50, 400, 1000)
plt.plot(xx, f(xx, *popt))
plt.show()

enter image description here

Answered By: blunova