Matplotlib के साथ सिंगल चार्ट पर दो हिस्टोग्राम लगाओ


233

मैंने फ़ाइल से डेटा का उपयोग करके हिस्टोग्राम प्लॉट बनाया और कोई समस्या नहीं। अब मैं उसी हिस्टोग्राम में एक अन्य फ़ाइल से डेटा को सुपरपोज करना चाहता था, इसलिए मैं ऐसा कुछ करता हूं

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

लेकिन समस्या यह है कि प्रत्येक अंतराल के लिए, केवल उच्चतम मान वाला बार दिखाई देता है, और दूसरा छिपा हुआ है। मुझे आश्चर्य है कि मैं अलग-अलग रंगों के साथ एक ही समय में दोनों हिस्टोग्राम कैसे साजिश कर सकता हूं।

जवाबों:


418

यहाँ आपके पास एक काम करने का उदाहरण है:

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

यहां छवि विवरण दर्ज करें


1
क्या pyplot.hold(True)सिर्फ मामले में, साजिश रचने से पहले इसे स्थापित करना अच्छा नहीं होगा ?
JAB

2
यह सुनिश्चित नहीं है कि मेरे matplotlib config params या pyplot में होल्ड (ट्रू) सेट है, डिफ़ॉल्ट रूप से इस तरह का व्यवहार करता है, लेकिन मेरे लिए कोड उसी तरह काम करता है जैसा वह है। कोड एक बड़े अनुप्रयोग से निकाला जाता है जो अब तक कोई समस्या नहीं दे रहा है। वैसे भी, अच्छा सवाल मैं पहले से ही कोड
joaquin

@joaquin: मैं x को नीला और y को लाल होने के लिए कैसे निर्दिष्ट कर सकता हूं?
amc

7
जब मैंने बार के edgecolor के साथ भूखंड को पुन: प्रस्तुत Noneकिया, तो डिफ़ॉल्ट रूप से। यदि आप वही डिज़ाइन चाहते हैं जैसा कि ग्राफ़ में दिखाया गया है तो आप edgecolorउदाहरण के लिए k(काला) दोनों में पैरामीटर सेट कर सकते हैं । किंवदंती के लिए प्रक्रिया समान है।
तो एस

2
और भी आसान: pyplot.hist([x, y], bins, alpha=0.5, label=['x', 'y'])
अगस्‍त

174

स्वीकृत जवाब ओवरलैपिंग बार के साथ एक हिस्टोग्राम के लिए कोड देता है, लेकिन यदि आप चाहते हैं कि प्रत्येक बार साइड-बाय-साइड हो (जैसा मैंने किया था), नीचे दिए गए भिन्नता का प्रयास करें:

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

यहां छवि विवरण दर्ज करें

संदर्भ: http://matplotlib.org/examples/statistics/histogram_demo_multihist.html

EDIT [2018/03/16]: @stochastic_zeitgeist द्वारा सुझाए गए विभिन्न आकारों के सरणियों की साजिश रचने की अनुमति


@GustavoBezerra, plt.histप्रत्येक हिस्टोग्राम के लिए एक पीडीएफ फाइल बनाने के लिए कैसे उपयोग करें? मैंने अपने डेटा का उपयोग करके लोड किया है pandas.read_csvऔर फ़ाइल में 36 कॉलम और 100 लाइनें हैं। तो मुझे 100 पीडीएफ़ फाइलें चाहिए।
सिगुर

2
@ सिगुर यह काफी ऑफ टॉपिक है। कृपया Google या एक नया प्रश्न पूछें। यह संबंधित प्रतीत होता है: stackoverflow.com/questions/11328958/…
Gustavo Bezerra

1
@stochastic_zeitgeist मैं @pasbi से सहमत हूं। मैंने आपकी टिप्पणी का उपयोग पंडों के डेटाफ़्रेम के साथ किया क्योंकि मुझे nans के कारण अलग-अलग भार की आवश्यकता थी। के साथ x=np.array(df.a)और y=np.array(df.b.dropna())यह मूल रूप से समाप्त हो रहा हैplt.hist([x, y], weights=[np.ones_like(x)/len(x), np.ones_like(y)/len(y)])
grinsbaeckchen

1
यदि आपके नमूने के आकार में बहुत भिन्नता है, तो आप वितरणों की तुलना करने के लिए जुड़वां कुल्हाड़ियों का उपयोग करके इसे बेहतर बनाना चाह सकते हैं। नीचे देखें ।
एंड्रयू

1
@ AgapeGal'lo एंड्रयू के जवाब को देखें।
गुस्तावो बीज़र्रा

30

यदि आपके पास अलग-अलग नमूना आकार हैं, तो एकल y- अक्ष के साथ वितरण की तुलना करना मुश्किल हो सकता है। उदाहरण के लिए:

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

इस स्थिति में, आप अपने दो डेटा सेट अलग-अलग अक्षों पर बना सकते हैं। ऐसा करने के लिए, आप matplotlib का उपयोग करके अपना हिस्टोग्राम डेटा प्राप्त कर सकते हैं, अक्ष को साफ़ कर सकते हैं, और फिर इसे दो अलग-अलग अक्षों पर फिर से प्लॉट कर सकते हैं (बिन किनारों को स्थानांतरित कर सकते हैं ताकि वे ओवरलैप न हों):

#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
यह एक अच्छा संक्षिप्त जवाब है, इसके अलावा आपको प्रत्येक टिक लेबल पर सलाखों को केंद्र में कैसे जोड़ना चाहिए
Odisseo

12

गुस्तावो बीज़र्रा के जवाब के पूरा होने के रूप में :

यदि आप चाहते हैं कि प्रत्येक हिस्टोग्राम को सामान्यीकृत किया जाए ( normedmpl के लिए <= 2.1 और densitympl के लिए = = 3.1 ) normed/density=Trueजिसका आप उपयोग नहीं कर सकते , तो आपको इसके बजाय प्रत्येक मान के लिए वेट सेट करने की आवश्यकता है:

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

यहां छवि विवरण दर्ज करें

एक तुलना के रूप में, एक ही समान xऔर yडिफ़ॉल्ट वजन वाले वैक्टर और density=True:

यहां छवि विवरण दर्ज करें


9

आपको binsदिए गए मानों से उपयोग करना चाहिए 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)

एक ही बिनिंग के साथ दो मैटलपोटलिब हिस्टोग्राम


7

यहाँ दो हिस्टोग्राम्स को प्लॉट करने की एक सरल विधि है, उनकी पट्टियाँ अगल-बगल, उसी प्लॉट पर जब डेटा अलग-अलग आकार का हो:

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

ऐसा लगता है कि आप बस एक बार ग्राफ चाहते हैं:

वैकल्पिक रूप से, आप सबप्लॉट्स का उपयोग कर सकते हैं।


अंतर यह है कि हिस्ट के साथ आपको एक प्लॉटेड प्लॉट मिलता है। शायद आपको यह दिखाना चाहिए कि यह कैसे करना है। पंडों के साथ आवृत्ति + बार साजिश = हिस्ट ()
वीपी।

2

बस अगर आपके पास पांडा है ( import pandas as pd) या इसका उपयोग करने के साथ ठीक हैं:

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

मेरा मानना ​​है कि अगर हिस्टोग्राम की तुलना अलग-अलग नमूना आकार में की जाए तो पांडा का उपयोग करना काम नहीं करेगा। यह भी अक्सर संदर्भ होता है जिसमें सामान्यीकृत हिस्टोग्राम का उपयोग किया जाता है।
सोलोमन विमल

2

जब आप हिस्टोग्राम को 2-डी के बराबर आरी से प्लॉट करना चाहते हैं तो एक कैविएट होता है। आपको 2 अक्षों को स्वैप करने की आवश्यकता है।

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

यहां छवि विवरण दर्ज करें


0

इस प्रश्न का उत्तर पहले भी दिया जा चुका है, लेकिन एक और त्वरित / आसान वर्कअराउंड जोड़ना चाहते हैं जो अन्य आगंतुकों को इस प्रश्न में मदद कर सकता है।

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

केडी बनाम हिस्टोग्राम तुलना के लिए कुछ उपयोगी उदाहरण यहां दिए गए हैं ।


0

सोलोमन के उत्तर से प्रेरित होकर, लेकिन इस प्रश्न से बचने के लिए, जो हिस्टोग्राम से संबंधित है, एक साफ समाधान है:

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

पहले लम्बे प्लॉट करना सुनिश्चित करें, अन्यथा आपको plt.ylim (0,0.45) सेट करने की आवश्यकता होगी ताकि लम्बे हिस्टोग्राम को काट न दिया जाए।


0

यह भी एक विकल्प है जो जोकॉइन उत्तर के समान है:

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

निम्नलिखित आउटपुट देता है:

यहां छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.