Гистограммы, используя его?
Я знаю, как создать гистограмму (просто используйте "с коробками") в gnuplot, если мой .файл DAT уже правильно сегментированных данных. Есть ли способ взять список чисел и предоставить gnuplot гистограмму на основе диапазонов и размеров ячеек, которые предоставляет пользователь?
9 ответов:
да, и его быстрый и простой, хотя очень скрытый:
binwidth=5 bin(x,width)=width*floor(x/width) plot 'datafile' using (bin(,binwidth)):(1.0) smooth freq with boxes
проверить
help smooth freq
чтобы увидеть, почему выше делает гистограммудля работы с диапазонами просто установите переменную xrange.
у меня есть пара исправлений / дополнений к очень полезному ответу Born2Smile:
- пустые бункеры вызвали поле для соседнего бункера неправильно расширяться в его пространство; избегайте этого с помощью
set boxwidth binwidth
- в версии Born2Smile ячейки отображаются как центрированные по их нижней границе. Строго они должны простираться от нижней границы до верхней границы. Это можно исправить, изменив
bin
функция:bin(x,width)=width*floor(x/width) + binwidth/2.0
будьте очень осторожны: все ответы на этой странице неявно принимают решение о том, где начинается биннинг - левый край самого левого Бина, если хотите-из рук пользователя. Если пользователь комбинирует любую из этих функций для биннинга данных с его / ее собственным решением о том, где начинается биннинг (как это делается в блоге, который связан с выше), все вышеперечисленные функции неверны. С произвольной начальной точкой для биннинга 'Min', правильная функция это:
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
вы можете видеть, почему это правильно последовательно (это помогает нарисовать несколько бункеров и точку где-то в одном из них). Вычтите Min из вашей точки данных, чтобы увидеть, как далеко она находится в диапазоне биннинга. Затем разделите на 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.
вы хотите построить график, как этот? да? Тогда вы можете посмотреть на мою статью в блоге: 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(,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(,binwidth,1)):(1.0) smooth freq with boxes
этот рекурсивный метод это для x >=0; можно было бы обобщить это с помощью более условных утверждений, чтобы получить что-то еще более общее.
нам не нужно использовать рекурсивный метод, он может быть медленным. Мое решение использует пользовательскую функцию rint instesd instrinsic function int или floor.
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))
что касается функций биннинга, я не ожидал результата функций, предлагаемых до сих пор. А именно, если моя ширина binwidth равна 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))
вот скрипт для сравнения некоторых предлагаемых функций 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