Sulla base della lettura di un file CSV, viene eseguita una linearizzazione dei valori in ordinata (tensione) e quindi si calcolano i coefficienti della retta di regressione, le incertezze dei parametri e il coefficiente di correlazione utilizzando la funzione linregress
del pacchetto SciPy.
I risultati appaiono in tre grafici a dispersione: il primo rappresenta il logaritmo della tensione in funzione del tempo, il secondo i residui della linearizzazione e il terzo riporta la funzione di scarica che ne deriva con i dati grezzi.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress
nome_file = input("Inserire il nome del file CSV: ")
# scarica.csv
file_in = open(nome_file, "r")
coppie_dati = np.loadtxt(file_in, delimiter = ",", comments = '#', usecols = (0,1))
n = len(coppie_dati)
nparrayX_Y = coppie_dati.transpose()
dati_x = nparrayX_Y[0]
dati_y = nparrayX_Y[1]
file_in.close()
ln_dati_y = np.log(dati_y)
esiti = linregress(dati_x,ln_dati_y)
a = esiti.slope
b = esiti.intercept
tau = -1/a
Deviazioni standard dei parametri e dei residui e calcolo del coefficiente di correlazione.
previsioni_lny = a*dati_x + b
residui = ln_dati_y - previsioni_lny
sigma = np.std(residui, ddof = 2)
sigma_a = esiti.stderr
sigma_b = esiti.intercept_stderr
coeff_correlazione = esiti.rvalue
min_x = min(dati_x)
max_x = max(dati_x)
min_y = min(ln_dati_y)
max_y = max(ln_dati_y)
delta_x = (max_x-min_x)/15
delta_y = (max_y-min_y)/15
Elementi per tracciare la retta di regressione e la corrispondente funzione esponenziale.
x = np.linspace(min_x-delta_x, max_x+delta_x, 100)
y = a*x + b
xx = np.linspace(0, 50, 100)
yy = a*xx + b
massimo_residui = max(abs(residui))
if a>=0:
posizione_txt = max_x - 4*delta_x
elif a<0:
posizione_txt = min_x + delta_x
Primo grafico: dispersione del logaritmo(tensione) e retta di regressione.
plt.grid(which = 'both', color = '.85', linestyle = '-', linewidth=1)
plt.plot(x, y, color = 'red', linewidth = 2, label = 'retta di regressione')
plt.scatter(dati_x, ln_dati_y, s = 1, c = 'cornflowerblue', zorder = 3, label = 'logaritmo della tensione rilevata')
plt.title("Linearizzazione della relazione esponenziale")
plt.xlabel('tempo (s)')
plt.ylabel('ln_tensione (ln(V))')
plt.text(posizione_txt-delta_x, min_y+delta_y/2, 'ln(y) = ({0:5.3f})t + ({1:4.1f})\na = {0:5.3f} $\pm$ {2:6.3f}\nb = {1:4.1f} $\pm$ {3:4.2f}\n r = {4:6.4f}\n$\\tau$ = {5:4.3}'.format(a, b, sigma_a, sigma_b, coeff_correlazione, tau), c = 'r')
plt.legend()
plt.show()
Distribuzione dei residui e relativa deviazione standard.
plt.grid(which = 'both', color = '.85', linestyle = '-', linewidth=1)
plt.xlim([min_x-delta_x, max_x+delta_x])
plt.ylim([-13/10*massimo_residui, 13/10*massimo_residui])
plt.vlines(dati_x, np.zeros(n), residui, linewidth = .5, color = 'orange')
plt.fill_between(x, -sigma, sigma, alpha =.1, linewidth = 0, color = 'r')
plt.plot(x,np.zeros(100), color = 'red', linewidth = 2)
plt.scatter(dati_x, residui, s = 5, c = 'cornflowerblue', zorder = 3, label = 'residui: $e_i=ln(y_i)-\hat ax_i-\hat b$')
plt.title("Distribuzione dei residui\n devSt $\sigma=$" + str(round(sigma,2)))
plt.xlabel('tempo (s)')
plt.ylabel('residui (ln(V))')
plt.legend()
plt.show()
Funzione esponenziale di scarica con i parametri dedotti dalla linearizzazione, dati grezzi e valore della costante di circuito $\tau$.
plt.grid(which = 'both', color = '.85', linestyle = '-', linewidth=1)
plt.plot(xx, np.exp(yy), color = 'red', linewidth = 2, label = 'funzione di regressione')
plt.scatter(dati_x, dati_y, s = 2, c = 'cornflowerblue', zorder = 3, label = 'tensione rilevata')
plt.title("Scarica esponenziale del condensatore")
plt.xlabel('tempo (s)')
plt.ylabel('tensione (V)')
plt.text(30, 1.5, 'y = exp({0:5.3f} t + {1:4.1f})\na = {0:5.3f} $\pm$ {2:6.3f}\nb = {1:4.1f} $\pm$ {3:4.2f}\n$\\tau$ = {4:4.3}'.format(a, b, sigma_a, sigma_b, tau), c = 'r')
plt.legend()
plt.show()