[PYTHON] Ich möchte ein Histogramm erstellen und die Normalverteilungskurve darauf überlagern. matplotlib edition

Überblick

Ich möchte ein ** Histogramm ** mit Python + Pandas + Matplotlib erstellen und die erhaltene ** Normalverteilungskurve ** überlagern, vorausgesetzt, die Population folgt einer Normalverteilung.

Zusätzlich ** Normalitätsprüfung ** durch Shapiro-Wilk-Test **, Intervallschätzung für Populationsmittel ** unter Annahme einer Normalverteilung ** (95% -Konfidenzintervall) Ich werde es auch tun).

Hier möchte ich als Beispiel ein Histogramm für das Testergebnis (für 100 Personen) aus 100 Punkten erstellen.

fig1.png

■ Durchschnitt: 76,1 Punkte, Standardabweichung: 10,3 Punkte --p = 0,77 (p> = 0,05) und man kann sagen, dass die Bevölkerung Normalität hat --95% Konfidenzintervall CI des Populationsmittelwerts CI = [74.09, 78.19]

Verwandte Einträge

Ausführungsumgebung

Wir haben die Ausführung und den Betrieb mit Google Colab (Python 3.6.9) bestätigt. Es ist fast das gleiche wie Jupyter Notebook.

!pip list 
matplotlib               3.1.2
numpy                    1.17.4
pandas                   0.25.3
scipy                    1.3.3

Vorbereitung für die Verwendung von Japanisch mit Matplotlib

Stellen Sie Japanisch im Ausgabediagramm von matplotlib zur Verfügung.

!pip install japanize-matplotlib
import japanize_matplotlib

Mit dem oben genannten wird japanize-matplotlib-1.0.5 installiert und importiert, und selbst wenn Sie Japanisch für Etiketten usw. verwenden, werden die Zeichen nicht verstümmelt (Tofu).

Code

python


%reset -f
import numpy as np
import pandas as pd
import scipy.stats as st
import math                        
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker 
import matplotlib.transforms as ts 

#Generieren Sie Dummy-Daten von Testergebnissen (normale Zufallszahlen (Ganzzahl) im Bereich von 0 bis 100).
def getTestData(mu,sig,n) : #Mittelwert mu, Standardabweichung sig, Anzahl normaler Zufallszahlen n
  f = lambda x: min(100,max(0,round( np.random.normal(mu,sig),0)))
  return (np.frompyfunc(f, 1, 1)(np.zeros(n))).astype(np.float)

df = pd.DataFrame( {'p1':getTestData(75,8,40)} )

#Diagrammzeichnungsparameter
target = 'p1'           #Zu zeichnende Spalten im Datenrahmen
x_min, x_max = 40, 100  #Bewertungsbereich für die Darstellung (untere und obere Grenze)
j = 5                   #Schrittweite der Y-Achse (Frequenz)
k = 5                   #Abschnittsbreite
bins = 12               #Anzahl der Abschnitte(x_max-x_min)/k  (100-40)/5->12

#Grafikzeichnungsprozess von hier
plt.figure(dpi=96)
plt.xlim(x_min,x_max)
d = 0.001

# (1)Statistische Verarbeitung
n   = len(df[target])         #Probengröße
mu  = df[target].mean()       #durchschnittlich
sig = df[target].std(ddof=0)  #Standardabweichung: ddof(Freiheitsgrad)=0
print(f'■ Durchschnitt:{mu:.1f}Punkt, Standardabweichung:{sig:.1f}Punkt')
ci1, ci2 = (None, None)

#Normalitätstest (Signifikanzniveau 5)%) Und der Bevölkerungsdurchschnitt von 95%Konfidenzintervall
_, p = st.shapiro(df[target])
if p >= 0.05 :
  print(f'  - p={p:.2f} ( p>=0.05 )Und man kann sagen, dass die Bevölkerung Normalität hat')
  U2 = df[target].var(ddof=1)  #Populationsvarianzschätzung (unvoreingenommene Varianz)
  DF = n-1                     #Freiheitsgrad
  SE = math.sqrt(U2/n)         #Standart Fehler
  ci1,ci2 = st.t.interval( alpha=0.95, loc=mu, scale=SE, df=DF )
  print(f'  -Bevölkerungsdurchschnitt 95%Konfidenzintervall CI= [{ci1:.2f} , {ci2:.2f}]')
else:
  print(f'  ※ p={p:.2f} ( p<0.05 )Und die Bevölkerung kann nicht als normal bezeichnet werden')

# (2)Zeichnen eines Histogramms
hist_data = plt.hist(df[target], bins=bins, color='tab:cyan', range=(x_min, x_max), rwidth=0.9)
plt.gca().set_xticks(np.arange(x_min,x_max-k+d, k))

# (3)Ungefähre Kurve unter Annahme einer Normalverteilung
sig = df[target].std(ddof=1)  #Unvoreingenommene Standardabweichung: ddof(Freiheitsgrad)=1
nx = np.linspace(x_min, x_max+d, 150) #150 Abteilungen
ny = st.norm.pdf(nx,mu,sig) * k * len(df[target])
plt.plot( nx , ny, color='tab:blue', linewidth=1.5, linestyle='--')

# (4)X-Achsen-Skalierungs- / Beschriftungseinstellung
plt.xlabel('Testergebnisklassifizierung',fontsize=12)
plt.gca().set_xticks(np.arange(x_min,x_max+d, k))

# (5)Skalierungs- / Beschriftungseinstellung der Y-Achse
y_max = max(hist_data[0].max(), st.norm.pdf(mu,mu,sig) * k * len(df[target]))
y_max = int(((y_max//j)+1)*j) #Das kleinste Vielfache von j, das größer als die maximale Frequenz ist
plt.ylim(0,y_max)
plt.gca().set_yticks( range(0,y_max+1,j) )
plt.ylabel('Anzahl der Personen',fontsize=12)

# (6)Textausgabe der Durchschnittspunktzahl und der Standardabweichung
tx = 0.03 #Zur Einstellung der Zeichenausgabeposition
ty = 0.91 #Zur Einstellung der Zeichenausgabeposition
tt = 0.08 #Zur Einstellung der Zeichenausgabeposition
tp = dict( horizontalalignment='left',verticalalignment='bottom',
           transform=plt.gca().transAxes, fontsize=11 )
plt.text( tx, ty, f'Durchschnittliche Punktzahl{mu:.2f}', **tp)
plt.text( tx, ty-tt, f'Standardabweichung{sig:.2f}', **tp)
plt.vlines( mu, 0, y_max, color='black', linewidth=1 )

Code 2

Im Fall eines Histogramms kann es schwierig sein zu sagen, ob der Wert, der die Grenze der Teilung darstellt, in der linken oder rechten Frequenz gezählt wird. Unten finden Sie eine einfachere Version davon.

fig2.png

python


%reset -f
import numpy as np
import pandas as pd
import scipy.stats as st
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.transforms as ts
import math

#Test-Dummy-Daten generieren (0-100)
def getTestData(mu,sig,n) : #Mittelwert mu, Standardabweichung sig, Anzahl normaler Zufallszahlen n
  f = lambda x: min(100,max(0,round( np.random.normal(mu,sig),0)))
  return (np.frompyfunc(f, 1, 1)(np.zeros(n))).astype(np.float)

df = pd.DataFrame( {'p1':dm} )

#Diagrammzeichnungsparameter
target = 'p1'           #Spalten, die im Datenrahmen gezeichnet werden sollen
x_min, x_max = 40, 100  #Bewertungsbereich für die Darstellung (untere und obere Grenze)
j = 5                   #Schrittweite der Y-Achse (Frequenz)
k = 5                   #Abschnittsbreite
bins = 12               #Anzahl der Abschnitte(x_max-x_min)/k  (100-40)/5->12

#Grafikzeichnungsprozess von hier
plt.figure(dpi=96)
plt.xlim(x_min-k/2,x_max-k/2)
d = 0.001

# (1)Statistische Verarbeitung
n   = len(df[target])         #Probengröße
mu  = df[target].mean()       #durchschnittlich
sig = df[target].std(ddof=0)  #Standardabweichung: ddof(Freiheitsgrad)=0
print(f'■ Durchschnitt:{mu:.1f}Punkt, Standardabweichung:{sig:.1f}Punkt')
ci1, ci2 = (None, None)

#Normalitätstest (Signifikanzniveau 5)%) Und der Bevölkerungsdurchschnitt von 95%Konfidenzintervall
_, p = st.shapiro(df[target])
if p >= 0.05 :
  print(f'  - p={p:.2f} ( p>=0.05 )Und man kann sagen, dass die Bevölkerung Normalität hat')
  U2 = df[target].var(ddof=1)  #Populationsvarianzschätzung (unvoreingenommene Varianz)
  DF = n-1                     #Freiheitsgrad
  SE = math.sqrt(U2/n)         #Standart Fehler
  ci1,ci2 = st.t.interval( alpha=0.95, loc=mu, scale=SE, df=DF )
  print(f'  -Bevölkerungsdurchschnitt 95%Konfidenzintervall CI= [{ci1:.2f} , {ci2:.2f}]')
else:
  print(f'  ※ p={p:.2f} ( p<0.05 )Und die Bevölkerung kann nicht als normal bezeichnet werden')

# (2)Zeichnen eines Histogramms
hist_data = plt.hist(df[target], bins=bins, color='tab:cyan', range=(x_min, x_max), rwidth=0.9, align='left')
plt.gca().set_xticks(np.arange(x_min,x_max-k+d, k))

# (3)Ungefähre Kurve unter Annahme einer Normalverteilung
sig = df[target].std(ddof=1)  #Unvoreingenommene Standardabweichung: ddof(Freiheitsgrad)=1
nx = np.linspace(x_min, x_max+d, 150) #150 Abteilungen
ny = st.norm.pdf(nx,mu,sig) * k * len(df[target])
plt.plot( nx - k/2 , ny, color='tab:blue', linewidth=1.5, linestyle='--')

# (4)X-Achsen-Skalierungs- / Beschriftungseinstellung
plt.xticks(rotation=90)
plt.xlabel('Testergebnisklassifizierung',fontsize=12)
tmp = list([ f'${i} \\leq x < {i+k}$' for i in range(x_min,x_max-k+1, k) ]) 
tmp[-1] = f'${x_max-k} \\leq x \\leq {x_max}$'
plt.gca().set_xticklabels( tmp )

# (5)Skalierungs- / Beschriftungseinstellung der Y-Achse
y_max = max(hist_data[0].max(), st.norm.pdf(mu,mu,sig) * k * len(df[target]))
y_max = int(((y_max//j)+1)*j) #Das kleinste Vielfache von j, das größer als die maximale Frequenz ist
plt.ylim(0,y_max)
plt.gca().set_yticks( range(0,y_max+1,j) )
plt.ylabel('Anzahl der Personen',fontsize=12)

Recommended Posts

Ich möchte ein Histogramm erstellen und die Normalverteilungskurve darauf überlagern. matplotlib edition
Ich möchte eine Pipfile erstellen und im Docker wiedergeben
Ich habe ein POST-Skript erstellt, um ein Problem in Github zu erstellen und es im Projekt zu registrieren
Ich möchte manuell eine Legende mit matplotlib erstellen
Ich möchte vorerst eine Docker-Datei erstellen.
Ich möchte den Schnittpunkt einer Bezier-Kurve und einer geraden Linie finden (Bezier-Clipping-Methode)
Ich möchte eine wunderschön angepasste Wärmekarte der Korrelationsmatrix ausgeben. matplotlib edition
Ich möchte die Ausführungszeit aufzeichnen und ein Protokoll führen.
Ich möchte Matplotlib zu einem dunklen Thema machen
Ich möchte einfach ein Rauschmodell erstellen
Ich möchte eine Art von Implementierung erstellen, die angeschlossen werden kann
Ich möchte eine Datei auf tkinter ablegen und ihren Pfad abrufen [Tkinter DnD2]
Ich möchte gleichzeitig einen Musik-Player erstellen und Musik ablegen
Ich möchte ein Element mit numpy in eine Datei schreiben und es überprüfen.
Ich möchte horizontalen Text in vertikalen Text konvertieren und auf Twitter usw. veröffentlichen.
Ich möchte ein beliebtes Paket auf PyPi finden
Es war ein Leben, das ich auf AWS Lambda OCR wollte, um die Charaktere zu lokalisieren.
Ich möchte einen Screenshot der Site in Docker mit einer beliebigen Schriftart erstellen
Schritte zur Berechnung der Wahrscheinlichkeit einer Normalverteilung
Ich möchte die Variablen in der Python-Vorlagendatei ersetzen und in einer anderen Datei in Massenproduktion herstellen
Ich möchte zum ersten Mal eine Django-Studie zur Mittagsdatenbank [EP1] erstellen
[Python] So erstellen Sie mit Matplotlib ein zweidimensionales Histogramm
Es ist schwierig, einen grünen Bildschirm zu installieren, daher habe ich nur das Gesicht ausgeschnitten und es dem Hintergrundbild überlagert
Ich möchte mit Python nur das Gesicht aus einem Personenbild ausschneiden und speichern ~ Gesichtserkennung und Zuschneiden mit face_recognition ~
Bei matplotlib ist die vertikale Achse auf der linken Seite des Histogramms die Frequenz und die vertikale Achse auf der rechten Seite die relative Frequenz (möglicherweise ein böser Weg).
Ich habe ein Tool erstellt, mit dem das Erstellen und Installieren eines öffentlichen Schlüssels etwas einfacher ist.
Als ich versuchte, PIL und matplotlib in einer virtuellen Umgebung zu installieren, war ich süchtig danach.
Ich möchte den Unterschied zwischen der for-Anweisung in der Python + numpy-Matrix und der Julia for-Anweisung auffangen
Ich möchte eine Karaoke-Klangquelle erstellen, indem ich Instrumente und Gesang mit Python trenne
Ich möchte die Natur von Python und Pip kennenlernen
Ich möchte den EDINET-Code und die Wertpapiernummer zuordnen
Ich möchte die Legende der IT-Technologiewelt kennenlernen
Wenn ich mit matplotlib eine große Anzahl von Diagrammen generiere, möchte ich das Diagramm nicht auf dem Bildschirm anzeigen (Jupyter-Umgebung).
Ich möchte Informationen von fstab am ssh-Verbindungsziel abrufen und den Befehl ausführen
Ich möchte die Frage nach der Methode "__init__" und dem Argument "self" der Python-Klasse klären.
Ich möchte Tag-Informationen (Titel und Künstler) einer Musikdatei (flac, wav) extrahieren.
Wie einfach ist es, ein Medikament auf dem Markt zu synthetisieren?
Qiskit: Ich möchte eine Schaltung erstellen, die beliebige Zustände erzeugt! !!
Ich habe versucht, einen Sender auf der IoT-Plattform "Rimotte" zu registrieren.
Holz kratzen und essen - ich möchte ein gutes Restaurant finden! ~ (Arbeit)
Ich habe versucht, Bulls and Cows mit einem Shell-Programm zu erstellen
Ich möchte einen maschinellen Lerndienst ohne Programmierung erstellen! Web-API
Ich habe GhostScript mit Python ausgeführt, das PDF in Seiten aufgeteilt und es in ein JPEG-Bild konvertiert.
Ich möchte die Einstellungsdatei erhalten und prüfen, ob die von jinja2 generierte JSON-Datei eine gültige JSON ist
Ich habe versucht, Sphinx-Dokumente an BitBucket zu senden und sie automatisch auf dem Webserver wiederzugeben
Ich möchte das Problem des Speicherverlusts bei der Ausgabe einer großen Anzahl von Bildern mit Matplotlib lösen
Laden Sie Daten mit einem Befehl und einer Aktualisierung auf s3 von aws hoch und löschen Sie die verwendeten Daten (unterwegs).
Ich möchte die Farbe ändern, indem ich auf den Streupunkt in matplotlib klicke
Ich möchte Twitter mit Python twittern, bin aber süchtig danach
Ich habe versucht, die Altersgruppe und die Ratenverteilung von Atcoder zu visualisieren
Ich möchte die Verarbeitung zwischen Testzeit und Produktionsumgebung trennen
Ich möchte es nicht zugeben ... Die dynamische Systemdarstellung von Neural Network
Ich habe einen Küchentimer erstellt, der in der Statusleiste angezeigt wird!
[Python] Erstellen Sie einen Linebot, um den Namen und das Alter auf das Bild zu schreiben
Ich möchte eine Liste in der Reihenfolge anderer Listen sortieren
[Persönliches Memo] Holen Sie sich Daten im Web und machen Sie daraus einen DataFrame
Passende Karaoke-Tasten ~ Ich habe versucht, es auf Laravel zu setzen ~ <auf dem Weg>