我知道如何在gnuplot中创建直方图(只是使用“带框”),如果我的.dat文件已经有正确的二进制数据。是否有一种方法可以获取数字列表,并让gnuplot根据用户提供的范围和bin大小提供一个直方图?
当前回答
要非常小心:本页上的所有答案都隐含地决定了装箱从哪里开始——如果你喜欢的话,从最左边的箱子的左边边缘开始——而不是由用户决定。如果用户将这些函数中的任何一个与他/她自己决定的数据分箱开始位置相结合(就像在上面链接的博客上所做的那样),上述函数都是不正确的。对于bin 'Min'的任意起始点,正确的函数是:
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
You can see why this is correct sequentially (it helps to draw a few bins and a point somewhere in one of them). Subtract Min from your data point to see how far into the binning range it is. Then divide by binwidth so that you're effectively working in units of 'bins'. Then 'floor' the result to go to the left-hand edge of that bin, add 0.5 to go to the middle of the bin, multiply by the width so that you're no longer working in units of bins but in an absolute scale again, then finally add back on the Min offset you subtracted at the start.
考虑这个函数:
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确实落在左bin中:
这个函数正确地将它映射到左bin的中心(0.75); Born2Smile的答案,bin(x)=width*floor(x/width),错误地将其映射为1; Mas90的答案,bin(x)=width*floor(x/width) + binwidth/2.0,错误地将其映射为1.5。
Born2Smile的答案只有在bin边界出现在(n+0.5)*binwidth (n经过整数)时才正确。Mas90的答案只有在bin边界出现在n*binwidth时才正确。
其他回答
我对Born2Smile的解决方案做了一些修改。
我知道这不太合理,但以防万一,你可能需要它。如果您的数据是整数,并且您需要一个浮动容器大小(可能是为了与另一组数据进行比较,或在更细的网格中绘制密度),您将需要在floor内添加一个0到1之间的随机数。否则,由于四舍五入误差会出现尖峰。地板(x/width+0.5)是不行的,因为它会创建与原始数据不相符的模式。
binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))
As usual, Gnuplot is a fantastic tool for plotting sweet looking graphs and it can be made to perform all sorts of calculations. However, it is intended to plot data rather than to serve as a calculator and it is often easier to use an external programme (e.g. Octave) to do the more "complicated" calculations, save this data in a file, then use Gnuplot to produce the graph. For the above problem, check out the "hist" function is Octave using [freq,bins]=hist(data), then plot this in Gnuplot using
set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes
关于分箱函数,到目前为止,我没有预料到函数提供的结果。也就是说,如果我的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
要非常小心:本页上的所有答案都隐含地决定了装箱从哪里开始——如果你喜欢的话,从最左边的箱子的左边边缘开始——而不是由用户决定。如果用户将这些函数中的任何一个与他/她自己决定的数据分箱开始位置相结合(就像在上面链接的博客上所做的那样),上述函数都是不正确的。对于bin 'Min'的任意起始点,正确的函数是:
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
You can see why this is correct sequentially (it helps to draw a few bins and a point somewhere in one of them). Subtract Min from your data point to see how far into the binning range it is. Then divide by binwidth so that you're effectively working in units of 'bins'. Then 'floor' the result to go to the left-hand edge of that bin, add 0.5 to go to the middle of the bin, multiply by the width so that you're no longer working in units of bins but in an absolute scale again, then finally add back on the Min offset you subtracted at the start.
考虑这个函数:
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确实落在左bin中:
这个函数正确地将它映射到左bin的中心(0.75); Born2Smile的答案,bin(x)=width*floor(x/width),错误地将其映射为1; Mas90的答案,bin(x)=width*floor(x/width) + binwidth/2.0,错误地将其映射为1.5。
Born2Smile的答案只有在bin边界出现在(n+0.5)*binwidth (n经过整数)时才正确。Mas90的答案只有在bin边界出现在n*binwidth时才正确。
是的,它快速而简单,但非常隐蔽:
binwidth=5
bin(x,width)=width*floor(x/width)
plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes
查看帮助平滑频率,看看为什么上面做了一个直方图
要处理范围,只需设置xrange变量。