2015-05-19 92 views
1

我有csv文件,我想从第6列创建直方图使用Linux工具很简单:直方图在UNIX实用程序的gnuplot VS直方图

└──> cut -f6 -d, data.csv | sort | uniq -c | sort -k2,2n 
    563 0.0 
    72 0.025 
    35 0.05 
    22 0.075 
    14 0.1 
    21 0.125 
    14 0.15 
    10 0.175 
     5 0.2 
     3 0.225 
     7 0.25 
     3 0.275 
     6 0.3 
     5 0.325 
     3 0.35 
     1 0.375 
     3 0.4 
     1 0.425 
     3 0.45 
     3 0.475 
     5 0.5 
     7 0.525 
    11 0.55 
     3 0.575 
     4 0.6 
     3 0.625 
    11 0.65 
     5 0.675 
     9 0.7 
     5 0.725 
     7 0.75 
     8 0.775 
     5 0.8 
     3 0.825 
     3 0.85 
     4 0.875 
     2 0.9 
     1 0.925 
     1 0.975 
    109 1.0 

不过,我想用我的gnuplot尝试它绘制我修改了following脚本。这是我修改后的版本:

#!/usr/bin/gnuplot -p 
# http://psy.swansea.ac.uk/staff/carter/gnuplot/gnuplot_frequency.htm 

clear 
reset 

set datafile separator ","; 
# set term dumb 

set key off 
set border 3 

# Add a vertical dotted line at x=0 to show centre (mean) of distribution. 
set yzeroaxis 

# Each bar is half the (visual) width of its x-range. 
set boxwidth 0.05 absolute 
set style fill solid 1.0 noborder 

bin_width = 0.1; 
bin_number(x) = floor(x/bin_width) 
rounded(x) = bin_width * (bin_number(x) + 0.5) 

# MAKE BINS 
# plot dataset_path using (rounded($6)):(6) smooth frequency with boxes 

# DO NOT MAKE BINS 
plot "data.csv" using 6:6 smooth frequency with boxes 

这是结果:

this http://oi57.tinypic.com/x1acrm.jpg

跟它的东西比Unix工具完全不同。在gnuplot我见过各种类型的直方图,例如一些遵循正态分布模式,另一些则根据频率排序(好像我用最后的sort -k2,2n替换为sort -n),另一个按照创建直方图的数量(我的情况)排序,如果我可以选择,那将是很好的。

回答

2

smooth frequency呈现以x单调的数据(即在第一using栏中给出,在你的情况下,从塔6的数值的值),然后总结了所有的Y值(在第二using列中给出的值)。

这里还给出第六列,如果要计算第六列中每个不同值的出现次数,则使用using 6:(1)(即第二列中的数值1)来计算每个值出现的实际数量:

set style fill solid noborder 
set boxwidth 0.8 relative 
set datafile separator ',' 
plot 'nupic_out.csv' using 6:(1) smooth frequency with boxes notitle 

enter image description here

要应用logscale平滑后的数据,必须首先将它们保存到临时文件set table ...; plot然后绘制这个临时文件。

set datafile separator ',' 
set table 'tmp.dat' 
plot 'nupic_out.csv' using 6:(1) smooth frequency with lines 
unset table 

在这里,你一定要注意,因为在gnuplot的一个bug增加了错误的最后一行,你必须跳过输出文件。您可以使用using声明中的过滤器跳过此内容,例如

plot 'tmp.dat' using (strcol(3) eq "i" ? $1 : 1/0):2 with boxes 

其在这里工作得很好,或者你可以使用head削减最后两行一样

plot '< head -n-2 tmp.dat' using 1:2 with boxes 

还有一点要注意的是,gnuplot的总是使用空格写出来的数据文件,所以您必须在绘制tmp.dat之前将数据文件分隔符更改回whitespace

一个完整的工作脚本可以

set style fill solid noborder 
set boxwidth 0.8 relative 
set datafile separator ',' 

set table 'tmp.dat' 
plot 'nupic_out.csv' using 6:(1) smooth frequency with lines notitle 
unset table 

set datafile separator whitespace 
set logscale y 
set yrange [0.8:*] 
set autoscale xfix 
plot '< head -n-2 tmp.dat' using 1:2 with boxes notitle 

enter image description here

现在,使用装箱函数在第六列中的值,必须通过对操作的功能替换using 6:(1)6在第六栏中给出的值。此功能必须用(),并且您在使用$6函数内部的第六列引用当前值,像

plot 'nupic_out.csv' using (bin($6)):(1) smooth frequency with lines 

同样,一个完整的工作脚本,使用ChrisW's binning function可能是

set style fill solid noborder 
set datafile separator ',' 

set boxwidth 0.09 absolute 
Min = -0.05 
Max = 1.05 
n = 11.0 
width = (Max-Min)/n 
bin(x) = width*(floor((x-Min)/width)+0.5) + Min 

set table 'tmp.dat' 
plot 'nupic_out.csv' using (bin($6)):(1) smooth frequency with lines notitle 
unset table 

set datafile separator whitespace 
set logscale y 
set xrange [-0.05:1.05] 
set tics nomirror out 
plot '< head -n-2 tmp.dat' using 1:2 with boxes notitle 

enter image description here

+0

谢谢你,伙计这工作。只有几个问题:1.我可以在y上使用log scale吗?我做了'设置logscale y 10',但输出结果很乱(还有另一个数字)。 2.我可以以某种方式重新排列x轴(如我在OP中所述)。 3.封入()中的数字的目的是什么?我用()在这里尝试了各种版本'seq 1 12 | xargs -n 2 echo | gnuplot -p -e“设置样式填充固定noborder;设置boxwidth 0.3相对; plot' - '使用2:1平滑频率与box notitle”'但我无法弄清楚。谢谢 –

+0

1:不,你不能直接在平滑的数据上使用日志规模,我会扩展我的答案,为此包括一个可能的解决方案。 2.当然,不是使用'6',你可以在'using'语句中使用任何你想表达的东西,比如'using(rounded($ 6)):(1)'或者类似的。但要注意你的binning函数的细节,参见[这个答案](http://stackoverflow.com/a/19596160/2604213)。 3.“使用6:1”将使用x的第六列和y值的第一列。在()中包含某些东西会使gnuplot评估一个表达式,'(1)'给出数字1,而不是1. col – Christoph