使用gnuplot的直方图?
如果我的.dat文件已经有了正确的装箱数据,我知道如何在gnuplot中创建直方图(只需使用“with box”)。有没有一种方法可以获取数字列表,并让gnuplot根据用户提供的范围和箱子大小提供直方图?是的,它快速简单,但非常隐蔽:使用gnuplot的直方图?,gnuplot,histogram,binning,Gnuplot,Histogram,Binning,如果我的.dat文件已经有了正确的装箱数据,我知道如何在gnuplot中创建直方图(只需使用“with box”)。有没有一种方法可以获取数字列表,并让gnuplot根据用户提供的范围和箱子大小提供直方图?是的,它快速简单,但非常隐蔽: binwidth=5 bin(x,width)=width*floor(x/width) plot 'datafile' using (bin($1,binwidth)):(1.0) smooth freq with boxes 查看help smooth f
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非常有用的答案做了一些修正/补充:
set-boxwidth-binwidth
bin
功能来纠正:bin(x,宽度)=宽度*地板(x/宽度)+宽度/2.0
你想画一个像这样的图吗? 对然后你可以看看我的博客文章: 代码中的关键行:
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中。这(显然是不必要的行为)很可能是由于“地板”功能造成的 以下是我试图绕过这一点的小小贡献
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
bin(x,宽度,n)=x=0;我们可以用更多的条件语句来概括这一点,以获得更一般的结果。我们不需要使用递归方法,它可能很慢。我的解决方案是使用用户定义的函数rint instsd或instrinsic函数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
为什么??请仔细阅读请注意:本页上的所有答案都隐含着从用户手中决定装箱的开始位置-最左侧箱子的左侧边缘,如果您愿意的话。如果用户将这些用于装箱数据的功能与他/她自己关于装箱从何处开始的决定相结合(正如在上面链接的博客上所做的),则上述功能都是不正确的。对于装箱“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
e、 g.值1.1真正落在左侧箱子中:
- 此功能可将其正确映射到左侧储物箱的中心(0.75)李>
- Born2Smile的答案是bin(x)=width*floor(x/width),错误地将其映射为1李>
- mas90的答案,bin(x)=宽度*地板(x/宽度)+bin宽度/2.0,错误地将其映射到1.5
Born2Smile的答案只有在(n+0.5)*binwidth(其中n在整数上运行)出现bin边界时才是正确的。mas90的答案只有在料仓边界出现在n*binwidth时才是正确的。我对Born2Smile的解做了一些修改
我知道这没有多大意义,但你可能想要以防万一。如果您的数据是整数,并且您需要浮点数大小(可能是为了与另一组数据进行比较,或者在更精细的网格中绘制密度),则需要在地板内部添加一个介于0和1之间的随机数。否则,由于舍入误差将出现峰值<代码>地板(x/width+0.5)
将不起作用,因为它将创建与原始数据不符的图案
binwidth=0.3
bin(x,width)=width*floor(x/width+rand(0))
和往常一样,Gnuplot是绘制漂亮图形的绝佳工具,可以让它执行各种计算然而,它用于绘制数据,而不是用作计算器,使用外部程序(如倍频程)进行更“复杂”的计算,将数据保存在文件中,然后使用Gnuplot生成图形通常更容易。对于上述问题,请使用
[freq,bins]=hist(data)
检查“hist”函数是否为倍频程,然后使用
set style histogram rowstacked gap 0
set style fill solid 0.5 border lt -1
plot "./data.dat" smooth freq with boxes
关于bining函数,我没有想到到目前为止提供的函数会有这样的结果。也就是说,如果我的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
...
我提出的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
同一数据集上不同数量的存储箱可以显示数据的不同特征 不幸的是,没有通用的最佳方法可以确定垃圾箱的数量 其中一个强大的方法是,它根据给定数据集的统计信息自动确定存储箱的数量 因此,以下内容可用于在
gnuplot
脚本中使用Freedman–Diaconis规则:
...
## preceeding gnuplot commands
...
#
samples="$samplesFile"
stats samples nooutput
N = floor(STATS_records)
samplesMin = STATS_min
samplesMax = STATS_max
# Freedman–Diaconis formula for bin-width size estimation
lowQuartile = STATS_lo_quartile
upQuartile = STATS_up_quartile
IQR = upQuartile - lowQuartile
width = 2*IQR/(N**(1.0/3.0))
bin(x) = width*(floor((x-samplesMin)/width)+0.5) + samplesMin
plot \
samples u (bin(\$1)):(1.0/(N*width)) t "Output" w l lw 1 smooth freq
假设您有一个包含单个样本列的文件,samplesFile
:
# samples
0.12345
1.23232
...
以下内容(基于)可以嵌入到现有的gnuplot
脚本中:
...
## preceeding gnuplot commands
...
#
samples="$samplesFile"
stats samples nooutput
N = floor(STATS_records)
samplesMin = STATS_min
samplesMax = STATS_max
# Freedman–Diaconis formula for bin-width size estimation
lowQuartile = STATS_lo_quartile
upQuartile = STATS_up_quartile
IQR = upQuartile - lowQuartile
width = 2*IQR/(N**(1.0/3.0))
bin(x) = width*(floor((x-samplesMin)/width)+0.5) + samplesMin
plot \
samples u (bin(\$1)):(1.0/(N*width)) t "Output" w l lw 1 smooth freq
如果你没有得到答案,还有其他工具可以用来做这些事情。我使用Root()这里很多其他人使用R,至少还有一些其他选项