我正在尝试用scipy做一个简单的线性曲线拟合,通常这种方法对我来说很好。但是这次由于一个我不知道的原因,它不起作用。
(我怀疑可能是因为这些数字太大了,以至于达到了给定数据类型下可以存储的极限。)
不管是什么原因,这个想法就是要做出这样的情节:
正如你在这里的轴上所看到的,这些数字是一个共同的数量级。然而,这次我试图拟合更大的数据点,数量级为1 E10,为此,我尝试使用以下代码(这里我只展示了制作散点图的代码,然后只拟合一个数据集)。
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
ucrt_T = 2/np.sqrt(3)
ucrt_U = 0.1/np.sqrt(3)
T = [314.1, 325.1, 335.1, 345.1, 355.1, 365.1, 374.1, 384.1, 393.1]
T_to_4th = [9733560790.61, 11170378213.80, 12609495509.84, 14183383217.88, 15900203737.92, 17768359469.96, 19586229219.65, 21765930026.49, 23878782252.31]
ucrt_T_lst = [143130823.11, 158701221.00, 173801148.95, 189829733.26, 206814686.75, 224783722.22, 241820148.88, 261735288.93, 280568229.17]
UBlack = [1.9,3.1, 4.4, 5.6, 7.0, 8.7, 10.2, 11.8, 13.4]
def lin_function(x,a,b):
return a*x + b
def line_fit_2():
#Dodanie pozostałych punktów na wykresie
plt.scatter(UBlack, T_to_4th, color='blue')
plt.errorbar(UBlack, T_to_4th, yerr=ucrt_T, fmt='o')
#Seria CZARNA
VltBlack = np.array(UBlack)
Tt4 = np.array(T_to_4th)
popt, pcov = curve_fit(lin_function, VltBlack, Tt4, absolute_sigma=False)
perr = np.sqrt(np.diag(pcov))
y = lin_function(VltBlack, *popt)
#Stylistyka i wygląd wykresu
#plt.plot(Pressure1, y, '--', color = 'g', label="fit with: $a={:.3f}\pm{:.3f}$, $b={:.3f}\pm{:.3f}$" .format(popt[0], perr[0], popt[1], perr[1]))
plt.plot(VltBlack, y, '--', color='green')
plt.ylabel(r'$T^4$ w $[K^4]$')
plt.xlabel(r'Napięcie termometru U w [mV]')
plt.legend(['Fit', 'Data points'])
plt.grid()
plt.show()
line_fit_2()
如果你运行它,你会发现散点图被创建,但是拟合没有正确执行,因为只有一条水平线被添加。此外,一个错误OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning)
被引发。
我会非常高兴知道我做错了什么或者如何解决这个问题。所有的帮助都很感激!
1条答案
按热度按时间oprakyz71#
你的问题已经回答得差不多了,我就证实一下你的怀疑:引发
OptimizeWarning
的原因是因为底层的优化算法由于较大的参数数而不能正常工作/发散。解决方法很简单,在使用拟合工具之前缩放输入参数即可。在向x/y轴添加标签时,请记住缩放:
我所做的只是用
10e6
来除大数字列表。这意味着这些值不再以kPa为单位,而是以兆kPa为单位(现在是GPa)。若要将整个列表除以相同的值,请先将其转换为numpy数组。
希望这对你有帮助:)