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.

137
demandé sur Mark Amery 2011-07-29 13:37:08

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()

entrez la description de l'image ici

276
répondu joaquin 2014-05-23 06:35:59

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()

entrez la description de l'image ici

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

84
répondu Gustavo Bezerra 2018-03-16 05:27:01

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()

hist_single_ax

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()

hist_twin_ax

11
répondu Andrew 2017-12-11 10:05:59

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()
7
répondu stochastic_zeitgeist 2018-01-30 06:48:42

On dirait que vous voudrez peut-être juste un graphique à barres:

Vous pouvez également utiliser des sous-parcelles.

3
répondu carl 2011-07-29 09:50:25

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()
3
répondu serv-inc 2017-06-16 12:35:46

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)

Deux histogrammes matplotlib avec le même binning

0
répondu Adrien Renaud 2018-07-31 14:48:37