İki histogramı matplotlib ile tek bir grafik üzerinde çizin


234

Bir dosyadan veri kullanarak bir histogram grafiği oluşturdum ve sorun değil. Şimdi aynı histogramdaki başka bir dosyadan veri toplamak istedim, bu yüzden böyle bir şey yapıyorum

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

ancak sorun, her aralık için yalnızca en yüksek değere sahip çubuğun görünmesi ve diğerinin gizlenmesidir. Her iki histogramı aynı anda nasıl farklı renklerle çizebileceğimi merak ediyorum.

Yanıtlar:


418

Burada çalışan bir örnek var:

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

resim açıklamasını buraya girin


1
Her pyplot.hold(True)ihtimale karşı, çizmeden önce ayarlamak iyi bir fikir olmaz mı?
JAB

2
Matplotlib yapılandırma parametrelerimde veya pyplot'umda hold (True) öğesinin ayarlanıp ayarlanmadığından emin değilim, ancak benim için kod olduğu gibi çalışır. Kod şimdiye kadar herhangi bir sorun vermeyen daha büyük bir uygulamadan çıkarılır. Her neyse, kodu yazarken zaten kendime yaptım iyi bir soru
joaquin

@joaquin: x'i mavi ve y'yi kırmızı olarak nasıl belirleyebilirim?
amc

7
Çubukların kenar rengi ile çizimi yeniden oluşturduğumda Nonevarsayılan olarak. Grafikte gösterilenle aynı tasarımı istiyorsanız, edgecolorher ikisinde de parametreyi k(siyah) olarak ayarlayabilirsiniz . Prosedür efsaneye benzer.
Yani

2
Daha kolay: pyplot.hist([x, y], bins, alpha=0.5, label=['x', 'y']).
Augustin

174

Kabul edilen cevaplar, üst üste gelen çubuklara sahip bir histogram için kod verir, ancak her çubuğun yan yana olmasını istediğinizde (yaptığım gibi), aşağıdaki varyasyonu deneyin:

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

resim açıklamasını buraya girin

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

EDIT [2018/03/16]: @stochastic_zeitgeist tarafından önerildiği gibi farklı boyutlardaki dizilerin çizilmesine izin vermek için güncellendi


@GustavoBezerra, plt.histher histogram için bir pdf dosyası üretmek için nasıl kullanılır ? Verilerimi kullanarak pandas.read_csvyükledim ve dosyada 36 sütun ve 100 satır var. 100 pdf dosyası istiyorum.
Sigur

2
@Sigur Bu konu dışı. Lütfen Google veya yeni bir soru sorun. Bu ilgili gibi görünüyor: stackoverflow.com/questions/11328958/…
Gustavo Bezerra

1
@stochastic_zeitgeist @pasbi'ye katılıyorum. Yorumunuzu bir panda veri çerçevesi ile kullandım çünkü nanslardan dolayı farklı ağırlıklara ihtiyacım vardı. ile x=np.array(df.a)ve y=np.array(df.b.dropna())temelde olmak sona erdiplt.hist([x, y], weights=[np.ones_like(x)/len(x), np.ones_like(y)/len(y)])
grinsbaeckchen

1
Örnek boyutlarınızın büyük ölçüde farklı olması durumunda, dağılımları daha iyi karşılaştırmak için çift eksen kullanarak çizim yapmak isteyebilirsiniz. Aşağıya bakınız .
Andrew

1
@ AgapeGal'lo Lütfen Andrew'un cevabına bakınız.
Gustavo Bezerra

30

Farklı örnek boyutlarınız olması durumunda, dağılımları tek bir y ekseni ile karşılaştırmak zor olabilir. Örneğin:

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

Bu durumda, iki veri kümenizi farklı eksenlere çizebilirsiniz. Bunu yapmak için, matplotlib kullanarak histogram verilerinizi alabilir, ekseni temizleyebilir ve daha sonra iki ayrı eksende yeniden çizebilirsiniz (bin kenarlarını üst üste binmeyecek şekilde kaydırma):

#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


1
Her kene etiketindeki çubukları nasıl ortalayacağınızı eklemeniz dışında bu güzel kısa bir cevaptır
Odisseo

12

Gustavo Bezerra'nın cevabının tamamlanması olarak :

Her histogramın normalleştirilmesini istiyorsanız ( normedmpl <= 2.1 ve densitympl> = 3.1 için ) sadece kullanamazsınız normed/density=True, bunun yerine her değer için ağırlıkları ayarlamanız gerekir:

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

resim açıklamasını buraya girin

Bir karşılaştırma olarak, tam olarak aynı xve yvarsayılan ağırlıkları olan vektörler density=True:

resim açıklamasını buraya girin


9

binsTarafından döndürülen değerlerden kullanmalısınız 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)

Aynı binning ile iki matplotlib histogramı


7

Veriler farklı boyutlara sahip olduğunda, iki histogramı çubukları yan yana olarak aynı grafikte çizmek için basit bir yöntem:

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


2

Pandalar ( import pandas as pd) varsa veya kullanmakta sorun yoksa:

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

Karşılaştırılacak histogramların farklı örnek boyutları varsa, panda kullanmanın işe yaramayacağına inanıyorum. Bu genellikle normalleştirilmiş histogramların kullanıldığı bağlamdır.
Solomon Vimal

2

Histogramı 2-d numpy dizisinden çizmek istediğinizde bir uyarı var. 2 ekseni değiştirmeniz gerekir.

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(size=(2, 300))
# swapped_data.shape == (300, 2)
swapped_data = np.swapaxes(x, axis1=0, axis2=1)
plt.hist(swapped_data, bins=30, label=['x', 'y'])
plt.legend()
plt.show()

resim açıklamasını buraya girin


0

Bu soru daha önce yanıtlandı, ancak bu soruya diğer ziyaretçilere yardımcı olabilecek başka bir hızlı / kolay geçici çözüm eklemek istedi.

import seasborn as sns 
sns.kdeplot(mydata1)
sns.kdeplot(mydata2)

Kde ve histogram karşılaştırması için bazı yararlı örnekler burada .


0

Solomon'ın cevabından esinlenerek, histogramla ilgili soruya sadık kalmak için temiz bir çözüm:

sns.distplot(bar)
sns.distplot(foo)
plt.show()

Önce uzun boylu çizdiğinizden emin olun, aksi takdirde uzun boylu histogram kesilmeyecek şekilde plt.ylim (0,0.45) ayarlamanız gerekir.


0

Ayrıca joaquin cevabına oldukça benzer bir seçenek:

import random
from matplotlib import pyplot

#random data
x = [random.gauss(3,1) for _ in range(400)]
y = [random.gauss(4,2) for _ in range(400)]

#plot both histograms(range from -10 to 10), bins set to 100
pyplot.hist([x,y], bins= 100, range=[-10,10], alpha=0.5, label=['x', 'y'])
#plot legend
pyplot.legend(loc='upper right')
#show it
pyplot.show()

Aşağıdaki çıktıyı verir:

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.