Scipy fit stats box

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
trublu
User
Beiträge: 18
Registriert: Montag 20. Juni 2016, 20:05

Hallo erstmal,

Kurzfassung der Frage: Kann man mit scipy eine Fit "zusammenfassung" ähnlich der stats box in ROOT in den Plot integrieren? Wer das nicht kennt dass ist einfach nur eine Box, die die Fitparameter mit Fehler und dem chi**2 / number degrees of freedom beinhaltet und irgendwo schön platziert werden kann. (sieht dann z.B. so aus https://root.cern.ch/doc/master/pict1_T ... ph_002.png)

Mir ist durchaus bewusst dass man die Fehler aus der covariance matrix im Rückgabewert vom curve_fit berechnen kann. Für das red. Chi2 hab ich keine fertige Funktion in Scipy gefunden, was mich durchaus wundert. Hab ich da was übersehen? Natürlich kann man sich auch das selber schreiben, aber eigentlich hätte ich erwartet das es da was fertiges geben müsste. Kann man das alles möglichst allgemein gecoded in einer Box hübsch in den Plot packen?
trublu
User
Beiträge: 18
Registriert: Montag 20. Juni 2016, 20:05

ich hab mir das jetzt mal etwas selbst zusammengebastelt, bin damit aber noch nicht ganz zufrieden. Zumindest die Zahlenwerte in der Box hätte ich gerne am rechten Rand ausgerichtet, kriegt man das noch irgendwie hin? Geht das nicht doch generell eleganter?

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from pylab import annotate

def fitfunc(x, a, b):
    return a*x + b

if __name__ == "__main__":
    x = np.array([1.2, 2.2, 3.4, 4.1])
    x_err = np.array([0.1, 0.1, 0.1, 0.1])

    y = np.array([3.5, 5.7, 7.8, 5.2])
    y_err = np.array([0.08, 0.1, 0.07, 0.1])

    plt.errorbar(x, y, xerr=x_err, yerr=y_err, fmt="ro")
    popt, pcov = curve_fit(fitfunc, x, y, sigma = y_err, absolute_sigma = True)
    a, a_err = popt[0], pcov[0][0]**0.5
    b, b_err = popt[1], pcov[1][1]**0.5

    xx = np.arange(1, 5, 0.1)
    plt.plot(xx, fitfunc(xx, *popt))

    dof = len(y) - len(popt)
    chi2 = sum( ((fitfunc(x, *popt)-y)/y_err)**2 )

    # Stats box
    boxtext =\
r"""f(x) = ax + b 
a = %f $\pm$ %f
b = %f $\pm$ %f
$\chi^2$/ ndf = %f / %d""" % (a, a_err, b, b_err, chi2, dof)

    props = dict(boxstyle='round, pad=1', facecolor='white', edgecolor='black')
    annotate(boxtext, xy=(1.5,8), xytext=(1.5,8), fontsize=20, bbox=props)
    #"""
    print 'results of general_fit:'
    print '   chi squared = ', chi2
    print '   degrees of freedom = ', dof
    print '   reduced chi squared = ', chi2/dof
    #"""
    plt.rcParams.update({'font.size': 20})
    plt.show()
Antworten