हिस्टोग्राम gnuplot का उपयोग कर?


202

मुझे पता है कि gnuplot में हिस्टोग्राम (बस "बॉक्स के साथ" का उपयोग कैसे करें) अगर मेरी .dat फ़ाइल में पहले से ही ठीक से डेटा नहीं है। क्या संख्याओं की सूची लेने का एक तरीका है और gnuplot उपयोगकर्ता द्वारा प्रदान की जाने वाली श्रेणियों और बिन आकारों के आधार पर हिस्टोग्राम प्रदान करता है?


2
यदि आपको कोई उत्तर नहीं मिलता है तो अन्य उपकरण हैं जो इस तरह के काम करने के लिए हैं। मैं रूट का उपयोग करता हूं ( root.cern.ch ) आसपास के कई अन्य लोग आर का उपयोग करते हैं, और कम से कम कुछ अन्य विकल्प हैं।
dmckee --- पूर्व-संचालक बिल्ली का बच्चा

1
बिन हिस्टोग्राम में प्रत्येक पट्टी के लिए एक साथ एकत्र किए गए मानों की श्रेणी है। प्रत्येक बिन में एक निचली और ऊपरी सीमा होती है, और उस सीमा के मान वाले सभी डेटा उस बार की ओर गिने जाते हैं। बिनड का अर्थ है कि मेरी डेटा फ़ाइल पहले से ही व्यवस्थित है कि प्रत्येक बिन के भीतर कितने डेटा बिंदु गिरते हैं इसलिए यह हिस्टोग्राम के रूप में प्लॉट किए जाने के लिए तैयार है।
मैरी

जवाबों:


225

हाँ, और इसके त्वरित और सरल हालांकि बहुत छिपे हुए हैं:

binwidth=5
bin(x,width)=width*floor(x/width)

plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes

यह देखने के help smooth freqलिए कि ऊपर हिस्टोग्राम क्यों बनाता है

श्रेणियों से निपटने के लिए सिर्फ x चर को सेट करें।


11
मुझे लगता है कि @ क्रिस का जवाब नीचे किसी भी व्यक्ति के लिए नोटिस करने के लिए एक महत्वपूर्ण बिंदु लाता है जो Gnuplot में हिस्टोग्राम बनाना चाहता है।
अभिनव

2
बहुत सावधान रहें, यह केवल तभी काम करता है जब सेट में कोई "लापता" बिन नहीं होता है ... यह फ़ंक्शन किसी लापता बिन के y- मान को पिछले गैर-लापता बिन के y- मान को ठीक करता है। यह बहुत भ्रामक हो सकता है !!!
21-11 बजे पिंकफ्लॉइड

1
मैं set boxwidth binwidthऊपर जोड़ दूंगा। यह वास्तव में मेरे लिए मददगार था।
जाको

90

मेरे पास कुछ सुधार है / जोडने के लिए Born2Smile का बहुत उपयोगी उत्तर है:

  1. खाली डिब्बे के कारण बॉक्स आसन्न बिन के लिए गलत तरीके से अपने स्थान में फैल गया; इसके इस्तेमाल से बचेंset boxwidth binwidth
  2. Born2Smile के संस्करण में, डिब्बे को उनकी निचली सीमा पर केंद्रित किया गया है। सख्ती से उन्हें निचली सीमा से ऊपरी सीमा तक विस्तार करना चाहिए। binफ़ंक्शन को संशोधित करके इसे ठीक किया जा सकता है:bin(x,width)=width*floor(x/width) + width/2.0

10
वास्तव में वह दूसरा भाग होना चाहिए bin(x,width)=width*floor(x/width) + binwidth/2.0(फ्लोटिंग पॉइंट
गणनाएँ

8
आपका मतलब है bin(x,width)=width*floor(x/width) + width/2.0। यदि हम widthएक तर्क के रूप में पारित कर रहे हैं , तो इसका उपयोग करें। :-)
Mitar

78

बहुत सावधान रहें: इस पृष्ठ के सभी उत्तर स्पष्ट रूप से यह निर्णय ले रहे हैं कि बिनिंग कहाँ से शुरू होती है - बाईं ओर के सबसे बाएं किनारे पर, यदि आपको पसंद है - उपयोगकर्ता के हाथों से बाहर। यदि उपयोगकर्ता अपने स्वयं के निर्णय के साथ डेटा के बिनिंग के लिए इन कार्यों में से किसी को जोड़ रहा है, तो जहाँ से शुरू होता है (जहाँ ऊपर लिंक किया गया है ब्लॉग पर किया जाता है) के बारे में अपने सभी निर्णय गलत हैं। 'मिन' को कम करने के लिए एक प्रारंभिक बिंदु के साथ, सही कार्य है:

bin(x) = width*(floor((x-Min)/width)+0.5) + Min

आप देख सकते हैं कि यह क्रमिक रूप से सही क्यों है (यह उनमें से कुछ में कुछ डिब्बे और एक बिंदु खींचने में मदद करता है)। अपने डेटा बिंदु से मिन को घटाएं यह देखने के लिए कि यह बाइनिंग रेंज में कितनी दूर है। फिर बायनेरिज़ द्वारा विभाजित करें ताकि आप प्रभावी रूप से 'डिब्बे' की इकाइयों में काम कर सकें। फिर 'बिन' उस बिन के किनारे पर जाने के लिए परिणाम, बिन के मध्य में जाने के लिए 0.5 जोड़कर, चौड़ाई से गुणा करें ताकि आप अब डिब्बे की इकाइयों में काम न कर रहे हों लेकिन एक पूर्ण पैमाने पर फिर, फिर अंत में न्यूनतम ऑफसेट पर जोड़ें जो आपने शुरू में घटाया था।

कार्रवाई में इस कार्य पर विचार करें:

Min = 0.25 # where binning starts
Max = 2.25 # where binning ends
n = 2 # the number of bins
width = (Max-Min)/n # binwidth; evaluates to 1.0
bin(x) = width*(floor((x-Min)/width)+0.5) + Min

उदाहरण के लिए मान १.१ वास्तव में बाएं बिन में पड़ता है:

  • यह फ़ंक्शन सही ढंग से इसे बाएं बिन (0.75) के केंद्र में मैप करता है;
  • बॉर्न 2 समाइल का उत्तर, बिन (x) = चौड़ाई * मंजिल (x / चौड़ाई), गलत तरीके से इसे 1 में मैप करता है;
  • mas90 का जवाब, बिन (x) = चौड़ाई * मंजिल (x / चौड़ाई) + binwidth / 2.0, गलत तरीके से इसे 1.5 पर मैप करता है।

यदि बाउंड्रीज़ (n + 0.5) * बायनॉवर्सी (जहाँ n रन पर ओवर रन करती है) पर बॉर्न 2Smile का उत्तर केवल सही है। यदि बिन सीमाएँ n * binwidth पर होती हैं तो mas90 का उत्तर केवल सही है।


48

क्या आप इस तरह एक ग्राफ तैयार करना चाहते हैं? यहां छवि विवरण दर्ज करें हाँ? तो आप मेरे ब्लॉग लेख पर एक नज़र डाल सकते हैं: http://gnuplot-surprising.blogspot.com/2011/09/statistic-analysis-and-histogram.html

कोड से मुख्य लाइनें:

n=100 #number of intervals
max=3. #max value
min=-3. #min value
width=(max-min)/n #interval width
#function used to map a value to the intervals
hist(x,width)=width*floor(x/width)+width/2.0
set boxwidth width*0.9
set style fill solid 0.5 # fill style

#count and plot
plot "data.dat" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green" notitle

10

हमेशा की तरह, Gnuplot मीठा दिखने वाले रेखांकन की साजिश रचने का एक शानदार उपकरण है और इसे हर तरह की गणना करने के लिए बनाया जा सकता है। हालांकि , यह एक कैलकुलेटर के रूप में सेवा करने के बजाय डेटा को प्लॉट करने का इरादा है और अधिक "जटिल" गणना करने के लिए बाहरी प्रोग्राम (जैसे ऑक्टेव) का उपयोग करना अक्सर आसान होता है, इस डेटा को एक फ़ाइल में सहेजें, फिर उत्पादन के लिए Gnuplot का उपयोग करें लेखाचित्र। उपरोक्त समस्या के लिए, "hist" फ़ंक्शन का उपयोग करके ऑक्टेव देखें [freq,bins]=hist(data), फिर Gnuplot का उपयोग करके इसे प्लॉट करें

set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes

7

मुझे यह चर्चा बेहद उपयोगी लगी, लेकिन मैंने कुछ "राउंडिंग ऑफ" समस्याओं का अनुभव किया है।

अधिक सटीक रूप से, ०.०५ के एक बैंडविड्थ का उपयोग करते हुए, मैंने देखा है कि, ऊपर प्रस्तुत तकनीकों के साथ, डेटा बिंदु जो एक ही बिन में ०.१ और ०.१५ पढ़ते हैं। यह (स्पष्ट रूप से अवांछित व्यवहार) "मंजिल" फ़ंक्शन के कारण सबसे अधिक संभावना है।

इसके बाद मेरा छोटा सा योगदान है, इसको दरकिनार करने का।

bin(x,width,n)=x<=n*width? width*(n-1) + 0.5*binwidth:bin(x,width,n+1)
binwidth = 0.05
set boxwidth binwidth
plot "data.dat" u (bin($1,binwidth,1)):(1.0) smooth freq with boxes

यह पुनरावर्ती विधि x> = 0 के लिए है; कोई और अधिक सामान्य प्राप्त करने के लिए अधिक सशर्त बयानों के साथ इसे सामान्य कर सकता है।


6

हमें पुनरावर्ती पद्धति का उपयोग करने की आवश्यकता नहीं है, यह धीमा हो सकता है। मेरा समाधान एक उपयोगकर्ता-परिभाषित फ़ंक्शन का उपयोग कर रहा है इंस्टेंट फ़ंक्शन इंट या फ़्लोर के इंस्टेंट।

rint(x)=(x-int(x)>0.9999)?int(x)+1:int(x)

यह फ़ंक्शन देगा rint(0.0003/0.0001)=3, जबकि int(0.0003/0.0001)=floor(0.0003/0.0001)=2

क्यों? कृपया पर्ल इंट फंक्शन और पेडिंग जीरो देखें


4

मेरे पास बोर्न 2Smile के समाधान के लिए थोड़ा संशोधन है।

मुझे पता है कि इसका बहुत मतलब नहीं है, लेकिन आप इसे सिर्फ मामले में चाहते हैं। यदि आपका डेटा पूर्णांक है और आपको फ़्लोट बिन आकार की आवश्यकता है (हो सकता है कि डेटा के किसी अन्य सेट के साथ तुलना के लिए, या महीन ग्रिड में प्लॉट घनत्व), तो आपको अंदर और 0 और 1 के बीच एक यादृच्छिक संख्या जोड़ना होगा। अन्यथा, राउंड अप त्रुटि के कारण स्पाइक्स होंगे। floor(x/width+0.5)ऐसा नहीं करेगा क्योंकि यह पैटर्न बनाएगा जो मूल डेटा के लिए सही नहीं है।

binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))

1
आपने ऐसी स्थितियों का सामना नहीं किया है, लेकिन आप बाद में कर सकते हैं। आप इसे सामान्य रूप से वितरित किए गए पूर्णांकों के साथ एक फ्लोट एसडी और प्लॉट हिस्टोग्राम के साथ बिन = 1, और बिन = एसडी के साथ देख सकते हैं कि आप क्या और बिना रैंड के साथ मिलते हैं (0) चाल। मैंने उसकी पांडुलिपि की समीक्षा करते समय एक सहयोगी की गलती पकड़ी। अपेक्षा के अनुसार उनके परिणाम बिल्कुल बकवास से सुंदर आंकड़े में बदल गए।
पाथ 4

ठीक है, शायद स्पष्टीकरण इतना छोटा है, कि कोई इसे और अधिक ठोस परीक्षण के मामले के बिना समझ नहीं सकता है। मैं आपके उत्तर का एक छोटा-सा संपादन करूँगा ताकि मैं नीचे की ओर जा सके।)
क्रिस्टोफ़

सामान्य वितरण के पूर्णांक पर विचार करें। चूंकि वे पूर्णांक हैं, उनमें से कई का एक्स / चौड़ाई समान होगा। मान लीजिए कि संख्या 1.3 है। मंजिल (x / चौड़ाई + 0.5) के साथ, उन सभी को बिन को सौंपा जाएगा। लेकिन घनत्व के संदर्भ में वास्तव में 1.3 का मतलब क्या है कि उनमें से 70% बिन 1 में होना चाहिए और 30% बिन 2 में होना चाहिए। रैंड (0) ) उचित घनत्व रखता है। इसलिए, 0.5 स्पाइक्स बनाता है और रैंड (0) इसे सही रखता है। मैं शर्त लगाता हूं कि hxxz द्वारा आंकड़ा 0.5 के बजाय रैंड (0) का उपयोग करके अधिक चिकना होगा। यह सिर्फ गोल नहीं है, यह बिना गड़बड़ी के गोल हो रहा है।
पाथ 4

3

बिनिंग कार्यों के संबंध में, मुझे अब तक पेश किए गए कार्यों के परिणाम की उम्मीद नहीं थी। अर्थात्, यदि मेरी सीमा 0.001 है, तो ये फ़ंक्शन 0.0005 बिंदुओं पर डिब्बे को केंद्रित कर रहे थे, जबकि मुझे लगता है कि यह डिब्बे 0.001 सीमाओं पर केंद्रित होना अधिक सहज है।

दूसरे शब्दों में, मैं करना चाहूंगा

Bin 0.001 contain data from 0.0005 to 0.0014
Bin 0.002 contain data from 0.0015 to 0.0024
...

बिनिंग फंक्शन मैं साथ आया हूं

my_bin(x,width)     = width*(floor(x/width+0.5))

यहां कुछ बिन कार्यों की तुलना करने के लिए यहां एक स्क्रिप्ट दी गई है:

rint(x) = (x-int(x)>0.9999)?int(x)+1:int(x)
bin(x,width)        = width*rint(x/width) + width/2.0
binc(x,width)       = width*(int(x/width)+0.5)
mitar_bin(x,width)  = width*floor(x/width) + width/2.0
my_bin(x,width)     = width*(floor(x/width+0.5))

binwidth = 0.001

data_list = "-0.1386 -0.1383 -0.1375 -0.0015 -0.0005 0.0005 0.0015 0.1375 0.1383 0.1386"

my_line = sprintf("%7s  %7s  %7s  %7s  %7s","data","bin()","binc()","mitar()","my_bin()")
print my_line
do for [i in data_list] {
    iN = i + 0
    my_line = sprintf("%+.4f  %+.4f  %+.4f  %+.4f  %+.4f",iN,bin(iN,binwidth),binc(iN,binwidth),mitar_bin(iN,binwidth),my_bin(iN,binwidth))
    print my_line
}

और यहाँ आउटपुट है

   data    bin()   binc()  mitar()  my_bin()
-0.1386  -0.1375  -0.1375  -0.1385  -0.1390
-0.1383  -0.1375  -0.1375  -0.1385  -0.1380
-0.1375  -0.1365  -0.1365  -0.1375  -0.1380
-0.0015  -0.0005  -0.0005  -0.0015  -0.0010
-0.0005  +0.0005  +0.0005  -0.0005  +0.0000
+0.0005  +0.0005  +0.0005  +0.0005  +0.0010
+0.0015  +0.0015  +0.0015  +0.0015  +0.0020
+0.1375  +0.1375  +0.1375  +0.1375  +0.1380
+0.1383  +0.1385  +0.1385  +0.1385  +0.1380
+0.1386  +0.1385  +0.1385  +0.1385  +0.1390
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.