Ich habe ein Histogramm-Diagramm mit Daten aus einer Datei erstellt, und das ist kein Problem. Jetzt wollte ich Daten aus einer anderen Datei im selben Histogramm überlagern, also mache ich so etwas wie
n,bins,patchs = ax.hist(mydata1,100)
n,bins,patchs = ax.hist(mydata2,100)
das Problem ist jedoch, dass für jedes Intervall nur der Balken mit dem höchsten Wert angezeigt wird und der andere ausgeblendet wird. Ich frage mich, wie ich beide Histogramme gleichzeitig mit unterschiedlichen Farben zeichnen könnte.
Hier haben Sie ein Arbeitsbeispiel:
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()
Die akzeptierten Antworten geben den Code für ein Histogramm mit überlappenden Balken an. Wenn Sie jedoch möchten, dass jeder Balken nebeneinander angezeigt wird (wie ich es getan habe), probieren 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()
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
Wenn Sie unterschiedliche Stichprobengrößen haben, kann es schwierig sein, die Verteilungen mit einer einzelnen 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()
In diesem Fall können Sie Ihre beiden Datensätze auf verschiedenen Achsen zeichnen. Zu diesem Zweck können Sie Ihre Histogrammdaten mit matplotlib abrufen, die Achse löschen und dann auf zwei separaten Achsen neu zeichnen (wobei die Bin-Kanten verschoben werden, damit 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()
Hier ist eine einfache Methode, um zwei Histogramme mit ihren Balken nebeneinander im selben Diagramm zu zeichnen, wenn die Daten unterschiedliche Größen haben:
def plotHistogram(p, o):
"""
p and o are iterables with the values you want to
plot the histogram of
"""
plt.hist([p, o], color=['g','r'], alpha=0.8, bins=50)
plt.show()
Als Ergänzung zu Gustavo Bezerras Antwort :
Wenn Sie möchten, dass jedes Histogramm normalisiert wird (normed
für mpl <= 2.1 und density
für mpl> = 3.1) du kannst 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()
Zum Vergleich die exakt gleichen Vektoren x
und y
mit Standardgewichten und density=True
:
Es hört sich so an, als ob Sie nur ein Balkendiagramm möchten:
Alternativ können Sie Unterzeichnungen verwenden.
Sie sollten bins
aus den von hist
zurückgegebenen Werten verwenden:
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)
Nur für den Fall, dass Sie pandas (import pandas as pd
) oder sind damit einverstanden:
test = pd.DataFrame([[random.gauss(3,1) for _ in range(400)],
[random.gauss(4,2) for _ in range(400)]])
plt.hist(test.values.T)
plt.show()
Diese Frage wurde bereits beantwortet, wollte aber eine weitere schnelle/einfache Problemumgehung hinzufügen, die anderen Besuchern dieser Frage helfen könnte.
import seasborn as sns
sns.kdeplot(mydata1)
sns.kdeplot(mydata2)
Einige hilfreiche Beispiele sind hier für den Vergleich zwischen kde und Histogramm.
Inspiriert von Solomons Antwort, aber um bei der Frage zu bleiben, die sich auf das Histogramm bezieht, ist eine saubere Lösung:
sns.distplot(bar)
sns.distplot(foo)
plt.show()
Stellen Sie sicher, dass Sie zuerst das größere zeichnen, andernfalls müssen Sie plt.ylim (0,0.45) einstellen, damit das größere Histogramm nicht abgeschnitten wird.