我知道这个问题类似于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;是 30个ZZ
字节的随机值;这里考虑一个字节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 个字节的一维数据(格式为 '%uint8',跳过后原点位于 0,0),然后是 100 个字节的一维数据(一列100行,格式为'%uint8',跳过后原点为100,0);并使用伪列0(点的索引)作为x轴,以及数组的第一个结果,用线条绘制“ ...不幸的是,这并不意味着 - 因为没有绘制任何内容,并且该命令失败并显示“该样式的使用规范太多”。
然后我想 - 好吧,如果有“太多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
绘制我想要的数据?
这里是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