سؤال

أعرف كيفية إنشاء رسم بياني (فقط استخدم "مع صناديق") في GNUPLOT إذا كان ملف .DAT الخاص بي يحتوي بالفعل على بيانات بشكل صحيح. هل هناك طريقة لاتخاذ قائمة بالأرقام وتوفير gnuplot رسمًا بيانيًا يعتمد على النطاقات وأحجام الحاوية التي يوفرها المستخدم؟

هل كانت مفيدة؟

المحلول

نعم ، وسريع وبسيط رغم مخفي للغاية:

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

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

الدفع help smooth freq لمعرفة لماذا ما سبق يصنع رسم بياني

للتعامل مع النطاقات ، فقط قم بتعيين متغير Xrange.

نصائح أخرى

لدي بعض التصحيحات/الإضافات إلى إجابة Born2Smile المفيدة للغاية:

  1. تسببت الصناديق الفارغة في أن يمتد الصندوق المجاور بشكل غير صحيح إلى مساحته ؛ تجنب هذا باستخدام set boxwidth binwidth
  2. في نسخة Born2Smile ، يتم تقديم الصناديق على أنها تركز على الحد الأدنى. بدقة يجب أن تمتد من الحد الأدنى إلى الحد الأعلى. يمكن تصحيح هذا عن طريق تعديل bin وظيفة: bin(x,width)=width*floor(x/width) + width/2.0

كن حذرًا جدًا: جميع الإجابات في هذه الصفحة تتخذ ضمنيًا قرار المكان الذي تبدأ فيه binning - الحافة اليسرى من صندوق اليسار الأكثر ، إذا أردت - من أيدي المستخدم. إذا كان المستخدم يجمع بين أي من هذه الوظائف لبيانات binning وقراره الخاص حول المكان الذي يبدأ فيه Binning (كما هو الحال في المدونة المرتبطة أعلاه) ، فإن الوظائف أعلاه كلها غير صحيحة. مع نقطة انطلاق تعسفية لـ Binning 'min' ، الوظيفة الصحيحة هي:

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

يمكنك أن ترى لماذا هذا صحيح بالتتابع (يساعد على رسم بعض الصناديق ونقطة في مكان ما في أحدها). قم بطرح دقيقة من نقطة بياناتك لمعرفة مدى وجودها في نطاق Binning. ثم اقسم على Binwidth حتى تعمل بفعالية في وحدات "الصناديق". ثم "الأرضية" النتيجة للذهاب إلى الحافة اليسرى لتلك الصندوق ، أضف 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

على سبيل المثال ، تقع القيمة 1.1 حقًا في الصندوق الأيسر:

  • هذه الوظيفة تقوم بتعيينه بشكل صحيح إلى مركز سلة اليسار (0.75) ؛
  • إجابة Born2Smile ، bin (x) = width*floor (x/width) ، يرسمها بشكل غير صحيح إلى 1 ؛
  • إجابة MAS90 ، bin (x) = width*floor (x/width) + binwidth/2.0 ، يرسمه بشكل غير صحيح إلى 1.5.

إجابة Born2Smile صحيحة فقط في حالة حدوث حدود الصندوق عند (n+0.5)*binwidth (حيث يركض n فوق الأعداد الصحيحة). إجابة MAS90 صحيحة فقط في حالة حدوث حدود الصندوق في n*binwidth.

هل تريد رسم رسم بياني مثل هذا؟enter image description hereنعم؟ ثم يمكنك إلقاء نظرة على مقال مدونتي: 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

كالعادة ، تعد 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

لقد وجدت هذه المناقشة مفيدة للغاية ، لكنني واجهت بعض المشكلات "التقريب".

بتعبير أدق ، باستخدام عريض من 0.05 ، لاحظت أنه مع التقنيات المقدمة هنا أعلاه ، نقاط البيانات التي تقرأ 0.1 و 0.15 تنخفض في نفس الحاوية. هذا (السلوك غير المرغوب فيه بشكل واضح) هو على الأرجح بسبب وظيفة "الأرضية".

الآخرة هي مساهمتي الصغيرة في محاولة للتحايل على هذا.

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 ؛ يمكن للمرء تعميم هذا مع المزيد من البيانات الشرطية للحصول على شيء أكثر عمومية.

لا نحتاج إلى استخدام الطريقة العودية ، فقد يكون بطيئًا. الحل الخاص بي هو استخدام وظيفة محددة من قبل المستخدم rint instesd من الوظيفة instrinsic int أو الكلمة.

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.

لماذا ا؟ يرجى النظر في وظيفة Perl Int وحشو الأصفار

لدي القليل من التعديل لحل Born2Smile.

أعلم أن هذا ليس له معنى كبير ، لكنك قد ترغب في ذلك فقط في حالة. إذا كانت بياناتك صحيحة وتحتاج إلى حجم صندوق عائم (ربما للمقارنة مع مجموعة أخرى من البيانات ، أو كثافة المؤامرة في الشبكة الدقيقة) ، فستحتاج إلى إضافة رقم عشوائي بين 0 و 1 داخل الطابق. خلاف ذلك ، سيكون هناك طفرات بسبب خطأ جولة. floor(x/width+0.5) لن تفعل لأنه سيخلق نمطًا غير صحيح للبيانات الأصلية.

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

فيما يتعلق بوظائف binning ، لم أكن أتوقع نتيجة الوظائف المقدمة حتى الآن. وهي ، إذا كانت ثنائية الأداء الخاصة بي هي 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
...

وظيفة binning التي توصلت إليها هي

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

إليك نصًا لمقارنة بعض وظائف Bin المعروضة بهذا:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top