In [35]:
import numpy as np
import matplotlib.pyplot as plt
import uncertainties as unt
import scipy.odr as odr
from matplotlib import gridspec
import uncertainties
import pandas as pd
import uncertainties.umath
from uncertainties import unumpy

In [68]:
#carregar os dados
dat = pd.read_csv("led.tsv", sep="\t", decimal='.')
x = dat["I"]
xerr = dat["sI"]
y = dat["U"]
yerr = dat["sU"]

In [147]:
#filtrar os dados
inds = x > 0.00002
x = x[inds]
y = y[inds]
xerr = xerr[inds]
yerr = yerr[inds]

In [148]:
#A lista B representa os parametros a serem ajustados. x é a variável independente e isUnt é uma gambiarra
def f(B, x, isUnt=False):
    if isUnt:
        return - B[0]*x + B[1] * unumpy.log(B[2]*x + 1)
    else:
        return - B[0]*x + B[1] * np.log(B[2]*x + 1)

In [149]:
#fazer o ajuste, beta0 são os chutes iniciais
#x e y são dados dos eixos. xerr e yerr são os erros respectivamente
mod = odr.Model(f)
dat = odr.RealData(x, y, sx=xerr, sy=yerr)
myodr = odr.ODR(dat, mod, beta0=[15, 0.08, 1e15])
out = myodr.run()
out.pprint()


Beta: [ -8.12376911e+00   1.47487473e-01   8.50309347e+10]
Beta Std Error: [  1.06329026e+00   1.02992260e-02   1.14488698e+11]
Beta Covariance: [[  1.37484105e+00   1.26242516e-02  -1.39389346e+11]
 [  1.26242516e-02   1.28990581e-04  -1.43349255e+09]
 [ -1.39389346e+11  -1.43349255e+09   1.59394765e+22]]
Residual Variance: 0.8223395486986673
Inverse Condition #: 8.754358494532752e-06
Reason(s) for Halting:
  Iteration limit reached

In [150]:
#quantos pontos em quais intervalos?
ylim = (0, 3.5) #eixos x
xlim = (0, 0.03) #eixos y
yres = (-5, 5) #residuos
size = 1e3
points = np.linspace(xlim[0], xlim[1], size)

#preparar o calculo da função ajustada
ay = np.zeros(size)
aye = np.zeros(size)
adj = unt.correlated_values(out.beta, out.cov_beta*out.res_var)
wrap_f = unt.wrap(f)

#calcular a função ajustada em varios pontos
i = 0
for point in points:
    val = wrap_f(adj, point, True)
    ay[i] = val.n
    aye[i] = val.s 
    i += 1
    
#residuos
res_size = len(y)
yadj = np.zeros(res_size)
yeadj = np.zeros(res_size)
for i in range(res_size):
    xu = unt.ufloat(x[i], xerr[i])
    val = f(adj, xu, True)
    yadj[i] = (y[i] - val.n)/val.s
    yeadj[i] = yerr[i]/(val.s)


/home/danilo/.local/lib/python3.4/site-packages/ipykernel/__main__.py:9: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
/home/danilo/.local/lib/python3.4/site-packages/ipykernel/__main__.py:10: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future

In [151]:
#plot
gs = gridspec.GridSpec(2, 1, height_ratios=[2, 1])
plt.subplot(gs[0])
plt.errorbar(x, y, fmt='.', xerr=xerr, yerr=yerr)

plt.plot(points, ay, '-k')
plt.plot(points, ay-aye, '--k', points, ay+aye, '--k')
plt.title("Gráfico")
plt.xlabel("Eixo x")
plt.ylabel("Eixo y")
plt.xlim(xlim)
plt.ylim(ylim)
plt.grid(True)

plt.subplot(gs[1])
plt.errorbar(x, yadj, yerr=yeadj, fmt='.')
plt.yticks(np.arange(yres[0], yres[1]))
plt.ylim(yres)
plt.xlabel("Eixo x")
plt.ylabel("Resíduos reduzidos")
plt.xlim(xlim)
plt.grid(True)

plt.show()

In [ ]: