Skip to content
Themen
Matplotlib
Matplotlib Histogram: The Complete Guide to plt.hist() in Python

Matplotlib Histogram: Der vollständige Leitfaden zu plt.hist() in Python

Updated on

Sie haben einen Datensatz mit Tausenden von numerischen Werten -- Alter, Testergebnisse, Antwortzeiten, Sensordaten -- und Sie müssen verstehen, wie diese Werte verteilt sind. Sind sie um einen zentralen Punkt gruppiert? Zu einem Ende hin verzerrt? Folgen sie einer Normalverteilung? Ein Streudiagramm hilft hier nicht weiter. Ein Balkendiagramm ist für Kategorien gedacht, nicht für kontinuierliche Daten. Was Sie brauchen, ist ein Histogramm, und in Python ist matplotlib.pyplot.hist() der Standardweg, um eines zu erstellen.

Das Problem ist, dass plt.hist() über ein Dutzend Parameter hat und die Standardausgabe oft schlicht oder irreführend aussieht. Die Wahl der falschen Anzahl von Bins kann wichtige Muster in Ihren Daten verbergen. Der Vergleich mehrerer Verteilungen in einem Diagramm erfordert die Kenntnis der richtigen Kombination von Optionen. Dieser Leitfaden behandelt jeden Parameter, der wichtig ist, mit funktionierenden Codebeispielen, die Sie direkt in Ihr Notebook oder Skript kopieren können.

📚

Was ist ein Histogramm und wann sollten Sie eines verwenden?

Ein Histogramm unterteilt einen Bereich numerischer Werte in gleichbreite Intervalle, sogenannte Bins, und zählt, wie viele Datenpunkte in jeden Bin fallen. Die x-Achse zeigt den Wertebereich, und die y-Achse zeigt die Häufigkeit (Anzahl) oder Dichte für jeden Bin. Im Gegensatz zu einem Balkendiagramm, das kategoriale Daten darstellt, repräsentiert ein Histogramm die Verteilung kontinuierlicher numerischer Daten.

Verwenden Sie ein Histogramm, wenn Sie:

  • Die Form einer Verteilung sehen müssen (normal, schief, bimodal, gleichmäßig)
  • Ausreißer oder Lücken in Daten identifizieren möchten
  • Die Streuung von Werten über Gruppen hinweg vergleichen möchten
  • Datentransformationen vor der Modellierung entscheiden müssen

Grundlegende plt.hist()-Syntax

Das einfachste Histogramm benötigt nur ein Argument: das Datenarray.

import matplotlib.pyplot as plt
import numpy as np
 
# Generate 1000 normally distributed values
np.random.seed(42)
data = np.random.normal(loc=50, scale=15, size=1000)
 
plt.hist(data)
plt.title('Basic Histogram')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

Standardmäßig unterteilt matplotlib die Daten in 10 Bins. Die Funktion gibt drei Objekte zurück: die Bin-Zählungen, die Bin-Kanten und die Patch-Objekte (die gezeichneten Rechtecke). Wir werden diese Rückgabewerte später im Detail behandeln.

Vollständige Signatur

plt.hist(x, bins=None, range=None, density=False, weights=None,
         cumulative=False, bottom=None, histtype='bar', align='mid',
         orientation='vertical', rwidth=None, log=False, color=None,
         label=None, stacked=False, edgecolor=None, alpha=None)

Bins steuern

Der bins-Parameter ist die wichtigste Einstellung in einem Histogramm. Zu wenige Bins verbergen Muster. Zu viele Bins erzeugen Rauschen.

Eine feste Anzahl von Bins festlegen

fig, axes = plt.subplots(1, 3, figsize=(14, 4))
 
axes[0].hist(data, bins=5, edgecolor='black')
axes[0].set_title('5 Bins')
 
axes[1].hist(data, bins=30, edgecolor='black')
axes[1].set_title('30 Bins')
 
axes[2].hist(data, bins=100, edgecolor='black')
axes[2].set_title('100 Bins')
 
plt.tight_layout()
plt.show()

Mit 5 Bins sehen Sie nur eine grobe Form. Mit 100 Bins führen kleine Stichprobengrößen pro Bin zu visuellem Rauschen. Für diesen Datensatz von 1.000 Punkten ergibt 30 Bins ein klares Bild der Normalverteilung.

Benutzerdefinierte Bin-Kanten

Übergeben Sie eine Sequenz an bins, um exakte Grenzen zu definieren:

custom_edges = [0, 20, 35, 50, 65, 80, 100]
plt.hist(data, bins=custom_edges, edgecolor='black', color='steelblue')
plt.title('Histogram with Custom Bin Edges')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

Dies ist nützlich, wenn Ihre Daten bedeutungsvolle Schwellenwerte haben -- Buchstabennoten, Altersgruppen oder Leistungsstufen.

Automatische Bin-Algorithmen

Matplotlib unterstützt mehrere Algorithmen, die die optimale Anzahl von Bins basierend auf Dateneigenschaften berechnen:

Algorithmusbins=-WertMethodeGeeignet für
Sturges'sturges'1 + log2(n)Kleine, annähernd normalverteilte Datensätze
Scott'scott'Basierend auf Standardabweichung und nNormale oder nahezu normale Daten
Freedman-Diaconis'fd'Basierend auf IQR und nRobust gegenüber Ausreißern
Quadratwurzel'sqrt'sqrt(n)Schnelle grobe Schätzung
Auto'auto'Maximum von Sturges und FDAllgemeiner Standard
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
 
for ax, method in zip(axes, ['sturges', 'scott', 'fd']):
    ax.hist(data, bins=method, edgecolor='black', color='#4C72B0')
    ax.set_title(f'bins="{method}"')
 
plt.tight_layout()
plt.show()

Für die meisten Fälle ist bins='auto' ein solider Ausgangspunkt. Wechseln Sie zu 'fd', wenn Ihre Daten Ausreißer enthalten, da es den Interquartilsabstand anstelle der Standardabweichung verwendet.

Normalisierte und Dichte-Histogramme

Standardmäßig zeigt die y-Achse Rohzählungen. Setzen Sie density=True, um das Histogramm so zu normalisieren, dass die Gesamtfläche unter den Balken gleich 1 ist. Dies konvertiert die y-Achse von Häufigkeit zu Wahrscheinlichkeitsdichte.

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
 
axes[0].hist(data, bins=30, edgecolor='black', color='#55A868')
axes[0].set_title('Frequency (default)')
axes[0].set_ylabel('Count')
 
axes[1].hist(data, bins=30, edgecolor='black', color='#C44E52', density=True)
axes[1].set_title('Density (density=True)')
axes[1].set_ylabel('Probability Density')
 
plt.tight_layout()
plt.show()

Dichtenormalisierung ist unerlässlich, wenn Sie eine theoretische Verteilungskurve überlagern oder Datensätze unterschiedlicher Größe vergleichen möchten:

from scipy import stats
 
plt.hist(data, bins=30, density=True, edgecolor='black', color='#55A868', alpha=0.7)
 
# Overlay the theoretical normal curve
x_range = np.linspace(data.min(), data.max(), 200)
plt.plot(x_range, stats.norm.pdf(x_range, loc=50, scale=15), 'r-', linewidth=2, label='Normal PDF')
plt.legend()
plt.title('Density Histogram with Normal Curve Overlay')
plt.show()

Erscheinungsbild anpassen

Farbe, Kantenfarbe und Transparenz

plt.hist(data, bins=30, color='#4C72B0', edgecolor='white', alpha=0.85)
plt.title('Styled Histogram')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

Histogramm-Typen

Der Parameter histtype ändert den visuellen Stil:

histtype-WertBeschreibung
'bar'Traditionelle gefüllte Balken (Standard)
'barstacked'Gestapelte Balken für mehrere Datensätze
'step'Ungefüllter Linienumriss
'stepfilled'Gefüllte Fläche mit Stufenumriss
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
types = ['bar', 'barstacked', 'step', 'stepfilled']
 
for ax, ht in zip(axes.flat, types):
    ax.hist(data, bins=30, histtype=ht, edgecolor='black', color='#4C72B0')
    ax.set_title(f'histtype="{ht}"')
 
plt.tight_layout()
plt.show()

Der Typ 'step' ist besonders nützlich beim Überlagern mehrerer Verteilungen, da ungefüllte Umrisse sich nicht gegenseitig verdecken.

Mehrere Histogramme in einem Diagramm

Überlappende Histogramme

Verwenden Sie alpha (Transparenz), um zwei oder mehr Verteilungen zu überlagern:

np.random.seed(42)
group_a = np.random.normal(loc=50, scale=10, size=800)
group_b = np.random.normal(loc=65, scale=12, size=800)
 
plt.hist(group_a, bins=30, alpha=0.6, color='#4C72B0', edgecolor='black', label='Group A')
plt.hist(group_b, bins=30, alpha=0.6, color='#C44E52', edgecolor='black', label='Group B')
plt.legend()
plt.title('Overlapping Histograms')
plt.xlabel('Score')
plt.ylabel('Frequency')
plt.show()

Nebeneinander liegende Histogramme

Übergeben Sie eine Liste von Arrays, um sie mit gruppierten Balken darzustellen:

plt.hist([group_a, group_b], bins=20, color=['#4C72B0', '#C44E52'],
         edgecolor='black', label=['Group A', 'Group B'])
plt.legend()
plt.title('Side-by-Side Histograms')
plt.xlabel('Score')
plt.ylabel('Frequency')
plt.show()

Wenn Sie eine Liste von Arrays übergeben, platziert matplotlib die Balken für jeden Datensatz nebeneinander innerhalb jedes Bins.

Gestapelte Histogramme

Setzen Sie stacked=True, um einen Datensatz auf einen anderen zu stapeln. Dies zeigt sowohl die einzelnen Verteilungen als auch deren kombinierte Summe.

np.random.seed(42)
freshmen = np.random.normal(loc=68, scale=8, size=500)
sophomores = np.random.normal(loc=72, scale=7, size=400)
juniors = np.random.normal(loc=75, scale=6, size=300)
 
plt.hist([freshmen, sophomores, juniors], bins=25, stacked=True,
         color=['#4C72B0', '#55A868', '#C44E52'], edgecolor='black',
         label=['Freshmen', 'Sophomores', 'Juniors'])
plt.legend()
plt.title('Stacked Histogram: Exam Scores by Class Year')
plt.xlabel('Score')
plt.ylabel('Frequency')
plt.show()

Gestapelte Histogramme funktionieren gut, wenn Sie zeigen möchten, wie Untergruppen zu einer Gesamtverteilung beitragen. Allerdings werden sie mit mehr als drei oder vier Gruppen schwer lesbar.

Kumulative Histogramme

Setzen Sie cumulative=True, um zu zeigen, wie sich Werte von links nach rechts akkumulieren. Der letzte Balken erreicht die Gesamtzahl (oder 1,0, wenn density=True).

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
 
axes[0].hist(data, bins=30, cumulative=True, edgecolor='black', color='#DD8452')
axes[0].set_title('Cumulative Histogram (Count)')
axes[0].set_ylabel('Cumulative Count')
 
axes[1].hist(data, bins=30, cumulative=True, density=True, edgecolor='black', color='#8172B3')
axes[1].set_title('Cumulative Histogram (Density)')
axes[1].set_ylabel('Cumulative Probability')
 
plt.tight_layout()
plt.show()

Kumulative Histogramme sind nützlich, um Fragen zu beantworten wie "Welcher Prozentsatz der Werte liegt unter 60?", indem man direkt von der y-Achse abliest.

Horizontale Histogramme

Setzen Sie orientation='horizontal', um die Achsen zu tauschen. Dies ist hilfreich, wenn Wertebeschriftungen lang sind oder wenn Sie das Histogramm neben einem anderen vertikalen Diagramm platzieren möchten.

plt.hist(data, bins=30, orientation='horizontal', color='#64B5CD', edgecolor='black')
plt.title('Horizontal Histogram')
plt.xlabel('Frequency')
plt.ylabel('Value')
plt.show()

Rückgabewerte von plt.hist()

plt.hist() gibt drei Werte zurück, die Ihnen programmatischen Zugriff auf die Histogrammdaten geben:

n, bin_edges, patches = plt.hist(data, bins=20, edgecolor='black', color='#4C72B0')
plt.show()
 
print(f"Bin counts (n): shape = {n.shape}, first 5 = {n[:5]}")
print(f"Bin edges: shape = {bin_edges.shape}, first 5 = {bin_edges[:5]}")
print(f"Patches: {len(patches)} Rectangle objects")
RückgabewertTypBeschreibung
nndarrayAnzahl (oder Dichte) für jeden Bin
bin_edgesndarrayKantenwerte für jeden Bin (Länge = len(n) + 1)
patchesListe von RectanglesDie matplotlib-Patch-Objekte für jeden Balken

Sie können patches verwenden, um einzelne Balken basierend auf ihrer Höhe oder Position einzufärben:

n, bin_edges, patches = plt.hist(data, bins=30, edgecolor='black')
 
# Color bars based on height
for count, patch in zip(n, patches):
    if count > 50:
        patch.set_facecolor('#C44E52')
    else:
        patch.set_facecolor('#4C72B0')
 
plt.title('Conditional Bar Coloring')
plt.show()

Referenz häufiger plt.hist()-Parameter

ParameterTypBeschreibungStandard
xarray-likeEingabedatenErforderlich
binsint, Sequenz oder strAnzahl der Bins, Bin-Kanten oder Algorithmusname10
rangetupleUnterer und oberer Bereich der Bins(x.min(), x.max())
densityboolNormalisieren, sodass die Fläche gleich 1 istFalse
weightsarray-likeGewichtung für jeden DatenpunktNone
cumulativeboolKumulatives Histogramm berechnenFalse
histtypestr'bar', 'barstacked', 'step', 'stepfilled''bar'
orientationstr'vertical' oder 'horizontal''vertical'
colorcolor oder ListeBalkenfarbe(n)None
edgecolorcolorKantenfarbe der BalkenNone
alphafloatTransparenz (0 bis 1)None
labelstrBeschriftung für die LegendeNone
stackedboolMehrere Datensätze stapelnFalse
logboolLogarithmische y-AchseFalse
rwidthfloatRelative Breite der Balken (0 bis 1)None
bottomarray-like oder SkalarBasislinie für jeden Balken0

plt.hist() vs. sns.histplot(): Wann welches verwenden

Wenn Sie seaborn neben matplotlib verwenden, fragen Sie sich vielleicht, welche Histogrammfunktion Sie verwenden sollten. Hier ist ein direkter Vergleich:

Featureplt.hist()sns.histplot()
Bibliothekmatplotlibseaborn
EingabetypenArray, Liste, SeriesArray, Series, DataFrame-Spalte
KDE-ÜberlagerungManuell (scipy benötigt)Eingebaut (kde=True)
Standard-StylingMinimalPublikationsreif
Mehrere GruppenListe von Arrays übergebenhue-Parameter
Statistik-OptionenAnzahl, DichteAnzahl, Dichte, Häufigkeit, Wahrscheinlichkeit, Prozent
Bin-Algorithmensturges, scott, fd, sqrt, autoauto, fd, doane, scott, stone, rice, sturges, sqrt
Log-Skalalog=Truelog_scale=True
Kategoriale AchseNicht unterstütztUnterstützt über hue
Leistung (große Daten)SchnellerEtwas langsamer
AnpassungstiefeVollständige matplotlib-APISeaborn + matplotlib-API

Verwenden Sie plt.hist(), wenn Sie volle Kontrolle über jedes visuelle Element benötigen, wenn Sie mit Subplots arbeiten oder wenn seaborn nicht verfügbar ist. Verwenden Sie sns.histplot(), wenn Sie KDE-Überlagerungen, sauberere Standardstile wünschen oder Daten mit minimalem Code nach einer kategorialen Variable aufteilen müssen.

Erstellen Sie interaktive Histogramme mit PyGWalker

Statische Histogramme sind großartig für Berichte und Skripte, aber bei der explorativen Datenanalyse müssen Sie oft Bins ändern, Teilmengen filtern und schnell zwischen Diagrammtypen wechseln. PyGWalker (opens in a new tab) ist eine Open-Source-Python-Bibliothek, die jeden pandas- oder polars-DataFrame in eine interaktive Drag-and-Drop-Visualisierungsoberfläche direkt im Jupyter Notebook verwandelt -- kein Frontend-Code erforderlich.

pip install pygwalker
import pandas as pd
import pygwalker as pyg
 
# Load your dataset into a DataFrame
df = pd.DataFrame({
    'score': np.random.normal(70, 12, 2000),
    'group': np.random.choice(['A', 'B', 'C'], 2000)
})
 
# Launch the interactive UI
walker = pyg.walk(df)

Sobald die Oberfläche geöffnet ist, ziehen Sie score auf die x-Achse und PyGWalker generiert automatisch ein Histogramm. Sie können die Bin-Größe anpassen, nach group mit Farbkodierung aufteilen, in den Dichtemodus wechseln und das resultierende Diagramm exportieren -- alles ohne zusätzlichen Code zu schreiben. Dies ist besonders nützlich, wenn Sie mehrere Variablen schnell erkunden müssen, bevor Sie den endgültigen matplotlib-Code für einen Bericht schreiben.

Häufig gestellte Fragen

Wie wähle ich die richtige Anzahl von Bins für ein matplotlib-Histogramm?

Beginnen Sie mit bins='auto', das das Maximum der Sturges- und Freedman-Diaconis-Methoden verwendet. Für Daten mit Ausreißern verwenden Sie bins='fd'. Für kleine Datensätze (unter 200 Punkte) funktioniert bins='sturges' gut. Sie können auch eine Ganzzahl übergeben und nach Augenmaß anpassen: Erhöhen Sie die Zahl, wenn die Verteilung zu glatt aussieht, verringern Sie sie, wenn die Balken verrauscht aussehen.

Was ist der Unterschied zwischen density=True und cumulative=True in plt.hist()?

density=True normalisiert das Histogramm, sodass die Gesamtfläche unter allen Balken gleich 1 ist, und konvertiert die y-Achse in Wahrscheinlichkeitsdichte. cumulative=True lässt jeden Balken die Summe aller vorherigen Balken plus sich selbst darstellen. Sie können beides kombinieren: density=True, cumulative=True erzeugt eine kumulative Verteilungsfunktion, bei der der letzte Balken 1,0 erreicht.

Wie überlagere ich zwei Histogramme in matplotlib?

Rufen Sie plt.hist() zweimal mit demselben bins-Wert auf und setzen Sie alpha auf einen Wert kleiner als 1 (z.B. 0,5 oder 0,6), damit beide Verteilungen sichtbar bleiben. Fügen Sie jedem Aufruf label hinzu und schließen Sie mit plt.legend() ab. Die Verwendung von histtype='step' als Alternative vermeidet die Notwendigkeit von Transparenz vollständig, da nur Umrisse gezeichnet werden.

Kann plt.hist() pandas Series und DataFrame-Spalten direkt verarbeiten?

Ja. plt.hist() akzeptiert jede array-ähnliche Eingabe, einschließlich pandas Series. Sie können df['column_name'] direkt übergeben. Zum Plotten aus einem DataFrame mit der eingebauten pandas-Methode verwenden Sie df['column_name'].plot.hist(bins=30), das matplotlib im Hintergrund verwendet.

Wie speichere ich ein matplotlib-Histogramm als Bilddatei?

Nach dem Aufruf von plt.hist() verwenden Sie plt.savefig('histogram.png', dpi=150, bbox_inches='tight') vor plt.show(). Der Parameter bbox_inches='tight' verhindert, dass Beschriftungen abgeschnitten werden. Unterstützte Formate sind PNG, PDF, SVG und EPS.

📚