在gnuplot中绘制具有多个记录的1D二进制数组(uint8)

时间:2013-01-23 04:23:25

标签: gnuplot

我理解这个问题类似于Gnuplot: How to plot multiple time series from a binary format;但是我已经设置了一个略有不同的例子,所以希望发布(自我回答如下)。

我正在生成这样的二进制数据(请参阅下面的genbindata.pl Perl脚本):

$ perl genbindata.pl > bin.dat
$ du -b bin.dat 
234 bin.dat

此二进制文件bin.dat的格式如下(前两行是基于1和基于0的索引):

>|  1   2   3   4 |  5   6 ... 104 |105 106 ... 204 |205 206 ... 234
>|000 001 002 003 |004 005 ... 103 |104 105 ... 203 |204 205 ... 233
>| WW  WW  WW  WW | XX  XX ...  XX | YY  YY ...  YY | ZZ  ZZ ...  ZZ  

...其中WW是4个字节的签名; XX是100字节的正弦曲线,值为0到63; YY是100字节的余弦值,值为64到127; ZZ是30字节的随机值;这里考虑一个字节为uint8

我想要做的是,就是使用这个bin.dat原样(也就是说,我不想编写脚本来解析数据,并以更gnuplot友好格式输出) - 并在单个图表上绘制具有单独颜色的正弦和余弦数据。

我找到了Binary general部分的帮助(在gnuplot终端中输入help binary general),但很难理解它(并且找不到更多其他信息在线)。所以 - 在线搜索(少数)示例之后 - 我在终端模式下启动gnuplot,我正在尝试以下gnuplot命令:

plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uint8%uint8' origin=(0,0):(100,0) using 0:1 with lines

...希望它意味着:“跳过前四个字节,将下一个字节解释为100字节的1D数据(格式化为'%uint8',并在跳过后原点为0,0),后跟100个字节1D数据(一列100行,格式为'%uint8',跳过后原点为100,0);并使用伪列0(点索引)作为x轴,并使用数组的第一个结果来绘制用线“......不幸的是,它意味着 - 因为没有绘制任何内容,并且命令失败并且”太多使用此样式的规范“。< / p>

然后我想 - 好吧,如果有“using太多”,那么我只是在那里绘制1

    gnuplot> plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uint8%uint8' origin=(0,0):(100,0) using 1 with lines
    Warning: empty y range [0:0], adjusting to [-1:1]
实际上,这确实会产生一个图 - 在y = 0时出现一条扁平的红线。

因此,如果它抱怨y范围,我将原始参数((100,0)的顺序更改为(0,100)),最后得到一个不生成任何消息的命令:

gnuplot> plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uchar%uchar' origin=(0,0):(0,100) using 1 with lines
gnuplot> 

...但它只绘制了一条倾斜线:

gnuplot-fail-1

......没有像我期望的那样的正弦曲线:(

所以,我的问题是 - 如何让gnuplot绘制我想要的数据?


以下是genbindata.pl

#!/usr/bin/env perl

use 5.10.1;
use warnings;
use strict;
use open IO => ':raw'; 

binmode(STDIN);
binmode(STDOUT);

my $signatur = "SIGN";
my @signature = unpack('C*', $signatur);

my (@ch1, @ch2) = ()x2;

# generate 100 samples of (co)sinusoid
for ( my $ix = 0; $ix < 100; $ix++ ) {
  my $val1 = 1 + sin($ix*2*3.14/100); # range: 0-2
  my $val2 = 1 + cos($ix*2*3.14/100); # range: 0-2
  my $ch1val = int($val1*32);
  my $ch2val = int($val2*32+64);
  push(@ch1, $ch1val);
  push(@ch2, $ch2val);
  #print STDERR "val[$ix]: $ch1val, $ch2val\n";
}

# generate 30 samples random
my @end = ();
for ( my $ix = 0; $ix < 30; $ix++ ) {
  my $val = int(128*rand() + 32);
  push(@end, $val);
  #~ print STDERR "val[$ix]: $val\n";
}

# concatenate arrays:
my @output = (@signature,@ch1,@ch2,@end);
my $sizarr = scalar(@output);
#~ print STDERR " ".." ";

# print output - uint8: "C"
my $outstr = pack("C*", @output);
my $lenstr = length($outstr);
#~ print STDERR "output size: $sizarr; output length: $lenstr\n";
print $outstr;

# end

0 个答案:

没有答案