[Python] Fit Power Law

Messaggioda mic_1 » 24/09/2021, 17:14

Mi potreste gentilmente correggere il codice?
Codice:
def OnFitPowerLaw(self, e):
        obj = e.GetEventObject()
        self.isPressed_POWERLAW = obj.GetValue()
        x = np.array(self.degr, dtype=int)
        y = np.array(self.cnt, dtype=int)
        logA = np.log10(x) ; logB = np.log10(y)
        fitfunc = lambda p, x: p[0] + p[1] * x
        errfunc = lambda p, x, y: (y - fitfunc(p, x))
        pinit = [1.0, -1.0]
        out = optimize.leastsq(errfunc, pinit, args=(logA, logB), full_output=1)
        pfinal = out[0]
        index = pfinal[1]
        amp = 10.0**pfinal[0]
        xdata = np.linspace(1, max(x), len(x))    # min(x)
        powerlaw = lambda x, amp, index: amp * (x**index)
        ydata = powerlaw(xdata, amp, index)
        new_xdata = []; new_ydata = []
        print('max(y) ', max(y))
        print('max(logB) ', max(logB))
        print('max(ydata) ', max(ydata))       
        # controllare ciclo for
        for i in range(len(ydata)):
           # if ydata[i] >= 1.0 :    # min(y)): 
            if float(min(y)) <= ydata[i] <= float(max(y)) :
                new_ydata.append(ydata[i]) ; new_xdata.append(xdata[i])
            else: continue
        #print(min(new_xdata), max(new_xdata), 'np.log10(min(new_xdata)) ', np.log10(min(new_xdata)))
        #print(min(new_ydata), max(new_ydata), 'np.log10(max(new_ydata))', np.log10(max(new_ydata)))
        self.a_POWERLAW = np.around(amp, 3) # Non è preciso
        self.b_POWERLAW = np.around(index, 3) #ok

        self.corr_POWERLAW = np.corrcoef(logA, logB, rowvar=0)[0,1]   # NON TORNA
        #self.corr_POWERLAW = np.corrcoef(new_xdata, new_ydata, rowvar=0)[0,1]
        # Corr corretto = 0.733   NON TORNA
        #print('corr ', np.corrcoef(np.log10(xx), np.log10(yy), rowvar=0)[0,1] ) # NON TORNA

        self.R_squared_POWERLAW = np.around( linregress(logA, logB).rvalue**2, 3)  #ok
        fig, ax = plt.subplots()   
        fig.set_size_inches(int(sizeFig_x), int(sizeFig_y+2))
        #ax.loglog(xdata, ydata, "r-", linewidth=2.0)
        ax.loglog(new_xdata, new_ydata, "r-", linewidth=2.0)
        ax.scatter(self.degr, self.cnt, alpha=0.0)
        ax.xaxis.label.set_size(10)
        ax.yaxis.label.set_size(10)
        ax.set_xscale('log')
        ax.set_yscale('log')
        ax.set_xticks(self.xticks)
        ax.set_yticks(self.yticks)
        ax.set_xticklabels(self.xticks, fontsize=8)   
        ax.set_yticklabels(self.yticks, fontsize=8)
        self.buf3 = io.BytesIO()
        fig.savefig(self.buf3, format = 'png', dpi= 72) #, bbox_inches='tight')
        self.buf3.seek(0)
        plt.close(fig)


Ho considerato i valori positivi che rientrano nell'intervallo dei dati iniziali, ma il FITPL viene leggermente più corto. Potreste dirmi dove sbaglio? Premetto che se carico un file diverso, il Fit Power Law viene correttamente. Grazie mille

Immagine

PS: Vorrei allegare il file con i dati self.degr, self.cnt ma non so come procedere.
mic_1
Junior Member
Junior Member
 
Messaggio: 185 di 386
Iscritto il: 11/01/2011, 18:11

Re: [Python] Fit Power Law

Messaggioda mic_1 » 26/09/2021, 21:00

Dimenticavo....Tutto dipende dalla condizione inserita nel ciclo, o almeno credo :
Codice:
for i in range(len(ydata)):
    if float(min(y)) <= ydata[i]  : #<= float(max(y)) :
          new_ydata.append(ydata[i]) ; new_xdata.append(xdata[i])
    else: continue

Con questa condizione ottengo la seguente immagine che viene spostata sfasando l'asse delle y:

Immagine

Non so proprio come risolvere il problema. Consigli? Grazie

PS: Ho poi da risolvere il valore di correlazione che non torna e il valore di "self.a_POWERLAW " che non è preciso. Mi viene 7541.582 anzichè 7544.etc

Ringrazio anticipatamente
mic_1
Junior Member
Junior Member
 
Messaggio: 186 di 386
Iscritto il: 11/01/2011, 18:11

Re: [Python] Fit Power Law

Messaggioda vict85 » 27/09/2021, 12:12

Penso che manchi qualcosa nel codice. Per esempio, mancano tutti gli import. Inoltre la funzione linregress non è definita (si tratta di scipy.stats.linregress?). Inoltre non so cosa siano sizeFig_x e sizeFig_y.
vict85
Moderatore
Moderatore
 
Messaggio: 10506 di 19253
Iscritto il: 16/01/2008, 00:13
Località: Berlin

Re: [Python] Fit Power Law

Messaggioda mic_1 » 28/09/2021, 14:00

Ciao, le inserisco subito :
Codice:
from scipy.stats import linregress
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt

Dovrei aver inserito tutte le librerie che interessano questa porzione di codice.
Le funzioni
Codice:
sizeFig
le puoi sostituire con qualsiasi valore di (x, y) di dimensione figura.
Si può tranquillamente omettere la parte legata ala figura è fare un semplice plt delle 2 figure.
Tralasciando la parte della figura (da plt.subplot() per interderci ) credo si possa semplificare con
Codice:
plt.loglog(new_xdata, new_ydata, "r-", linewidth=2.0)
plt.scatter(self.degr, self.cnt, alpha=0.6)
plt.show()

A me interessa principalmente la parte di calcolo. Grazie

Allego in dati in questo modo:
self.degr = [ 358, 124, 106, 96, 94, 92, 90, 88, 84, 80, 76, 74, 72, 70, 68, 64, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2 ]

self.cnt = [ 1, 1, 1, 1, 2, 1,, 1, 1, 1, 3, 1, 1, 3, 2, 6, 3, 3, 7, 2, 1, 1, 16, 4, 5, 9, 6, 10, 10, 9, 15, 19, 35, 21, 29, 30, 49, 43, 55, 52, 66, 70, 99, 110, 186, 238, 418, 835 ]
mic_1
Junior Member
Junior Member
 
Messaggio: 187 di 386
Iscritto il: 11/01/2011, 18:11


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite