2011-07-29 31 views
114

Creé un gráfico de histograma usando datos de un archivo y no hay problema. Ahora quería superponer datos de otro archivo en el mismo histograma, por lo que hago algo así comoGrafique dos histogramas al mismo tiempo con matplotlib

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

pero el problema es que para cada intervalo, sólo aparece la barra con el valor más alto, y el otro es desconocido . Me pregunto cómo podría trazar ambos histogramas al mismo tiempo con diferentes colores.

Respuesta

224

Aquí tienen un ejemplo de trabajo:

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

+1

¿No sería una buena idea establecer 'pyplot.hold (True)' antes de trazar, por si acaso? – JAB

+2

No estoy seguro de si hold (True) está configurado en my matplotlib config params o pyplot se comporta así por defecto, pero para mí el código funciona tal como está. El código se extrae de una aplicación más grande que no da ningún problema hasta el momento.De todos modos, buena pregunta que ya me hice al escribir el código – joaquin

+0

@joaquin: ¿cómo podría especificar que x sea azul y que sea rojo? – amc

49

Las respuestas aceptadas da el código de un histograma con barras superpuestas, pero en caso de que quiera cada barra sea de lado a lado (como yo), trata de la variación a continuación:

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, 5000) 
data = np.vstack([x, y]).T 
bins = np.linspace(-10, 10, 30) 

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

enter image description here

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

+5

¿Cómo hago histogramas en el mismo diagrama de dos matrices de datos con diferentes tamaños? –

+0

Me temo que no es posible en este momento sin algunos retoques matplotlib de nivel inferior (es decir, no factible directamente de fábrica con una función de alto nivel como 'plt.hist'). Una solución simple sería usar la respuesta de @ joaquin en su lugar. Otra solución (potencialmente mejor) sería completar la matriz de diferentes tamaños con 'np.nan' para que pueda hacer' datos', pero aun así matplotlib falla. Hay una solicitud de extracción pendiente dirigiéndose a eso: https://github.com/matplotlib/matplotlib/pull/7133 –

+10

Lo resolví usando 'plt.hist ([x, y], color = ['g', 'r'] , alpha = 0.8, bins = 50) ' –

0

Sólo en caso de tener pandas (import pandas as pd) o estás bien con su uso:

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

Aquí es un método simple para trazar dos histogramas, con sus bares de lado a lado , en la misma parcela, cuando los datos tienen diferentes tamaños:

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

en el caso de tener diferentes tamaños de muestra, puede ser difícil comparar las distribuciones de un solo eje y. Por ejemplo:

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

En este caso, puede trazar sus dos conjuntos de datos en diferentes ejes. Para ello, puede obtener sus datos de histograma utilizando matplotlib, desactive el eje, y luego volver a terreno en dos ejes separados (el desplazamiento de los bordes de basura para que no se superpongan):

#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

Cuestiones relacionadas