359 Stimmen

Zwei Histogramme in einem einzigen Diagramm mit matplotlib darstellen

Ich habe eine Histogrammdarstellung mit Daten aus einer Datei erstellt, und es gab keine Probleme. Nun wollte ich Daten aus einer anderen Datei im selben Histogramm überlagern, also habe ich etwas wie folgt gemacht

n,bins,patchs = ax.hist(mydata1,100)
n,bins,patchs = ax.hist(mydata2,100)

aber das Problem ist, dass für jedes Intervall nur der Balken mit dem höchsten Wert erscheint und die anderen ausgeblendet werden. Ich frage mich, wie ich beide Histogramme gleichzeitig mit unterschiedlichen Farben darstellen kann.

595voto

joaquin Punkte 77782

Hier haben Sie ein funktionierendes Beispiel:

import random
import numpy
from matplotlib import pyplot

x = [random.gauss(3,1) for _ in range(400)]
y = [random.gauss(4,2) for _ in range(400)]

bins = numpy.linspace(-10, 10, 100)

pyplot.hist(x, bins, alpha=0.5, label='x')
pyplot.hist(y, bins, alpha=0.5, label='y')
pyplot.legend(loc='upper right')
pyplot.show()

enter image description here

306voto

Gustavo Bezerra Punkte 8388

Die akzeptierten Antworten enthalten den Code für ein Histogramm mit sich überlappenden Balken, aber wenn Sie jeden Balken nebeneinander haben möchten (wie ich), versuchen Sie die folgende Variante:

import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-deep')

x = np.random.normal(1, 2, 5000)
y = np.random.normal(-1, 3, 2000)
bins = np.linspace(-10, 10, 30)

plt.hist([x, y], bins, label=['x', 'y'])
plt.legend(loc='upper right')
plt.show()

enter image description here

Referenz: http://matplotlib.org/examples/statistics/histogram_demo_multihist.html

EDIT [2018/03/16]: Aktualisiert, um das Plotten von Arrays unterschiedlicher Größe zu ermöglichen, wie von @stochastic_zeitgeist vorgeschlagen

40voto

Andrew Punkte 5105

Wenn Sie unterschiedliche Stichprobengrößen haben, kann es schwierig sein, die Verteilungen mit einer einzigen y-Achse zu vergleichen. Zum Beispiel:

import numpy as np
import matplotlib.pyplot as plt

#makes the data
y1 = np.random.normal(-2, 2, 1000)
y2 = np.random.normal(2, 2, 5000)
colors = ['b','g']

#plots the histogram
fig, ax1 = plt.subplots()
ax1.hist([y1,y2],color=colors)
ax1.set_xlim(-10,10)
ax1.set_ylabel("Count")
plt.tight_layout()
plt.show()

hist_single_ax

In diesem Fall können Sie Ihre beiden Datensätze auf verschiedenen Achsen darstellen. Dazu können Sie Ihre Histogrammdaten mit matplotlib abrufen, die Achse löschen und sie dann auf zwei separaten Achsen neu auftragen (wobei Sie die Bin-Ränder so verschieben, dass sie sich nicht überlappen):

#sets up the axis and gets histogram data
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.hist([y1, y2], color=colors)
n, bins, patches = ax1.hist([y1,y2])
ax1.cla() #clear the axis

#plots the histogram data
width = (bins[1] - bins[0]) * 0.4
bins_shifted = bins + width
ax1.bar(bins[:-1], n[0], width, align='edge', color=colors[0])
ax2.bar(bins_shifted[:-1], n[1], width, align='edge', color=colors[1])

#finishes the plot
ax1.set_ylabel("Count", color=colors[0])
ax2.set_ylabel("Count", color=colors[1])
ax1.tick_params('y', colors=colors[0])
ax2.tick_params('y', colors=colors[1])
plt.tight_layout()
plt.show()

hist_twin_ax

23voto

Adrien Renaud Punkte 2039

Sie sollten Folgendes verwenden bins aus den Werten, die von hist :

import numpy as np
import matplotlib.pyplot as plt

foo = np.random.normal(loc=1, size=100) # a normal distribution
bar = np.random.normal(loc=-1, size=10000) # a normal distribution

_, bins, _ = plt.hist(foo, bins=50, range=[-6, 6], normed=True)
_ = plt.hist(bar, bins=bins, alpha=0.5, normed=True)

Two matplotlib histograms with same binning

22voto

jojo Punkte 8953

Als Ergänzung zu Gustavo Bezerra's Antwort :

Wenn Sie wollen jedes zu normalisierende Histogramm ( normed für mpl<=2.1 und density für mpl>=3.1 ) können Sie nicht einfach normed/density=True müssen Sie stattdessen die Gewichte für jeden Wert festlegen:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(1, 2, 5000)
y = np.random.normal(-1, 3, 2000)
x_w = np.empty(x.shape)
x_w.fill(1/x.shape[0])
y_w = np.empty(y.shape)
y_w.fill(1/y.shape[0])
bins = np.linspace(-10, 10, 30)

plt.hist([x, y], bins, weights=[x_w, y_w], label=['x', 'y'])
plt.legend(loc='upper right')
plt.show()

enter image description here

Zum Vergleich: Genau die gleichen x y y Vektoren mit Standardgewichten und density=True :

enter image description here

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X