Tracer deux histogrammes en même temps avec matplotlib
J'ai créé un tracé d'histogramme en utilisant les données d'un fichier et aucun problème. Maintenant, je voulais superposer les données de un autre fichier dans le même histogramme, donc je fais quelque chose comme
n,bins,patchs = ax.hist(mydata1,100)
n,bins,patchs = ax.hist(mydata2,100)
Mais le problème est que pour chaque intervalle, seule la barre avec la valeur la plus élevée apparaît, et l'autre est cachée. Je me demande comment pourrais-je tracer les deux histogrammes en même temps avec des couleurs différentes.
7 réponses
Ici vous avez un exemple de travail:
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()
Les réponses acceptées donnent le code pour un histogramme avec des barres qui se chevauchent, mais si vous voulez que chaque barre soit côte à côte (comme je l'ai fait), essayez la variation ci-dessous:
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()
Référence: http://matplotlib.org/examples/statistics/histogram_demo_multihist.html
EDIT [2018/03/16]: mise à jour pour permettre le traçage de tableaux de différentes tailles, comme suggéré par @stochastic_zeitgeist
Dans le cas où vous avez des tailles d'échantillon différentes, il peut être difficile de comparer les distributions avec un seul axe Y. Par exemple:
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()
Dans ce cas, vous pouvez tracer vos deux ensembles de données sur des axes différents. Pour ce faire, vous pouvez obtenir vos données d'histogramme en utilisant matplotlib, effacer l'axe, puis le tracer à nouveau sur deux axes distincts (en déplaçant les bords de la corbeille afin qu'ils ne se chevauchent pas):
#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()
Voici une méthode simple pour tracer deux histogrammes, avec leurs barres côte à côte, sur le même tracé lorsque les données ont des tailles différentes:
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()
On dirait que vous voudrez peut-être juste un graphique à barres:
- http://matplotlib.sourceforge.net/examples/pylab_examples/bar_stacked.html
- http://matplotlib.sourceforge.net/examples/pylab_examples/barchart_demo.html
Vous pouvez également utiliser des sous-parcelles.
Juste au cas où vous avez des pandas (import pandas as pd
) ou êtes ok avec l'utiliser:
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()
Vous devez utiliser les valeurs de retour bins
de 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)