Here is a bit of code, based on yours. Here, there is an option to read from a file, or curve fit perfect data that is created on the fly. If you have “nice” values, like (a,b,c,d)=1,2,3,4, and take the log of the data, the curve fit does well. However, if you fiddle with the parameters, you can wind up with bad fits, even with “perfect” data. I did notice that when rejecting the data V<-3.0, and not taking the log10(I90), you get a fit that looks OK, but it isn’t perfect. When trying data when V>-2.5, and taking the log of the I90 data, you get this, which isn’t bad:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ https://stackoverflow.com/questions/71008658/how-to-fit-a-tanhx-function-to-data-in-python?noredirect=1#71008658 test code to check tanh fitting """ import matplotlib.pyplot as plt from scipy.optimize import curve_fit import numpy as np def fitfunction(v,a,b,c,d): return (a * np.tanh((b * v) + c) + d) # x data = V90 # y data = np.log10(I90) # read data from file readdata=False if(readdata==True): # arr = np.loadtxt("anode_90ma_test1.csv", delimiter=",") arr = np.loadtxt("test_data4.csv", delimiter=",") V90=arr[:,0] # option of using raw data or log of raw data I90=arr[:,1] # I90=np.log10(arr[:,1]) else: a_coeff=100 b_coeff=1 c_coeff=0.2 d_coeff=-99 V90=np.arange(-4,4,0.1) createvalues = np.vectorize(fitfunction) I90=createvalues(V90,a_coeff,b_coeff,c_coeff,d_coeff) # optionally take log10 # I90=np.log10(I90) # pars, cov = curve_fit(fitfunction,V90,np.log10(I90)) pars, cov = curve_fit(fitfunction,V90,I90) print("fit pars = ",pars) plt.plot(V90,fitfunction(V90,*pars),'r-',linewidth='3',label='Line of Best Fit') plt.scatter(V90,I90,marker='.',label='Data') plt.title('Graph of Line of Best Fit of Anode Current against Anode Potential') plt.grid(True) plt.xlabel('Voltage (V)') plt.ylabel('Current (A)') plt.legend() plt.show()
CLICK HERE to find out more related problems solutions.