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 d'un autre fichier dans le même histogramme, alors 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 masquée. Je me demande comment pourrais-je tracer les deux histogrammes en même temps avec des couleurs différentes.
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 d'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 variante 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 tailles différentes, comme suggéré par @stochastic_zeitgeist
Si la taille des échantillons est différente, il peut être difficile de comparer les distributions avec un seul axe des ordonnées. 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 les données de votre histogramme à l'aide de matplotlib, effacer l'axe, puis le représenter à nouveau sur deux axes distincts (en décalant les bords des casiers 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()
En complément de réponse de Gustavo Bezerra :
Si vous voulez normaliser chaque histogramme (normed
pour mpl <= 2.1 et density
pour mpl> = 3.1 ), vous ne pouvez pas simplement utiliser normed/density=True
, vous devez définir les poids pour chaque valeur:
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()
À titre de comparaison, les mêmes vecteurs x
et y
avec les pondérations par défaut et density=True
:
Il semble que vous souhaitiez simplement un graphique à barres:
Alternativement, vous pouvez utiliser des intrigues secondaires.
Vous devez utiliser bins
à partir des valeurs renvoyées par 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)
Juste au cas où vous avez pandas (import pandas as pd
) ou êtes prêt à 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()
On a déjà répondu à cette question, mais je voulais ajouter une autre solution de contournement rapide/facile qui pourrait aider d'autres visiteurs à cette question.
import seasborn as sns
sns.kdeplot(mydata1)
sns.kdeplot(mydata2)
Quelques exemples utiles sont ici pour la comparaison kde vs histogramme.
Inspirée par la réponse de Solomon, mais pour en rester à la question, qui est liée à l'histogramme, une solution propre est la suivante:
sns.distplot(bar)
sns.distplot(foo)
plt.show()
Assurez-vous de tracer le plus grand en premier, sinon vous devrez définir plt.ylim (0,0,45) pour que l'histogramme le plus grand ne soit pas coupé.