使用gnuplot直方图?
我知道如何创build一个直方图(只是使用“框”)在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
看看为什么上面做直方图
处理范围只需设置xrangevariables。
我对Born2Smile非常有用的答案有一些更正/补充:
- 空箱导致相邻箱的箱子错误地伸入其空间; 避免使用
set boxwidth binwidth
- 在Born2Smile的版本中,垃圾箱呈现为居中的下限。 严格地说,他们应该从下界延伸到上界。 这可以通过修改
bin
函数来纠正:bin(x,width)=width*floor(x/width) + binwidth/2.0
要非常小心:这个页面上的所有答案都隐含地决定了分档开始的位置 – 如果你愿意的话,最左边的分档的左边 – 从用户的手中移出。 如果用户将这些用于装箱数据的function与他/她自己的关于开始装箱的决定(如在上面链接的博客上所做的)相结合,则上述function都是不正确的。 对于任意分箱起始点“Min”,正确的function是:
bin(x) = width*(floor((x-Min)/width)+0.5) + Min
你可以看到为什么这是正确的顺序(这有助于画几个箱子和其中一个地方)。 从你的数据点减去Min来看它到底有多远。 然后除以binwidth,这样就可以有效地以“bin”为单位进行工作。 然后,将结果“落地”到该垃圾箱的左侧边缘,加0.5到垃圾箱的中间,乘以宽度,以便不再以垃圾箱为单位工作,而是以绝对比例再次,最后加回你在开始减去的最小偏移量。
考虑这个function:
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中:
- 此function将其正确地映射到左侧箱(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时才是正确的。
你想绘制一个这样的图吗? 是? 那么你可以看看我的博客文章: 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
我发现这个讨论非常有用,但是我经历了一些“四舍五入”的问题。
更准确地说,使用0.05的binwidth,我已经注意到,用上面介绍的技术,读取0.1和0.15的数据点落入同一个bin。 这种(明显不想要的行为)很可能是由于“地板”function。
以下是我想尽量规避这一点的小小贡献。
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
这个recursion方法是为x> = 0; 我们可以用更多的条件语句来概括这个,以获得更一般的东西。
像往常一样,Gnuplot是绘制甜美graphics的绝妙工具,可以进行各种计算。 然而 ,它的目的是绘制数据,而不是作为一个计算器,通常使用外部程序(例如八度)来执行更复杂的计算,将这些数据保存在文件中,然后使用Gnuplot生成图表。 对于上述问题,使用[freq,bins]=hist(data)
检查出“hist”函数是Octave,然后在Gnuplot中使用
set style histogram rowstacked gap 0 set style fill solid 0.5 border lt -1 plot "./data.dat" smooth freq with boxes
我们不需要使用recursion方法,可能会很慢。 我的解决scheme是使用一个用户定义的函数rint in instr函数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的解决scheme做了一些修改。
我知道这没什么意义,但你可能需要它以防万一。 如果您的数据是整数,并且您需要一个浮动块大小(可能用于与另一组数据比较,或在更细的网格中绘制密度),则需要在楼层内部0和1之间添加一个随机数。 否则,由于整数错误会出现尖峰。 floor(x/width+0.5)
将不会执行,因为它会创build与原始数据不一致的模式。
binwidth=0.3 bin(x,width)=width*floor(x/width+rand(0))
关于分箱function,我没有想到到目前为止提供的function的结果。 也就是说,如果我的binwidth是0.001,那么这些函数将会把这个bin分为0.0005个点,而我觉得把这个bin分配在0.001个边界上会更直观。
换句话说,我想要
Bin 0.001 contain data from 0.0005 to 0.0014 Bin 0.002 contain data from 0.0015 to 0.0024 ...
我想出的分箱function是
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