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{e\cdot U}{k\cdot 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.
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()