在gnuplot中绘制具有多条记录的一维二进制数组(uint8)

在gnuplot中绘制具有多条记录的一维二进制数组(uint8),gnuplot,Gnuplot,我知道这个问题与,;不过,我已经设置了一个稍微不同的示例,所以希望可以发布(自答如下) 我像这样生成二进制数据(参见下面的genbindata.plPerl脚本): 这个二进制文件,bin.dat的格式如下(前两行是基于1和基于0的索引): 。。。其中,WW是4字节的签名XX是值为0到63的100字节正弦波YY是100字节的余弦,值从64到127;和ZZ是30字节的随机值;这里考虑一个字节是uint8 我想做的是使用这个bin.dat(也就是说,我不想编写脚本来解析数据,并以更友好的格式输出数

我知道这个问题与,;不过,我已经设置了一个稍微不同的示例,所以希望可以发布(自答如下)

我像这样生成二进制数据(参见下面的
genbindata.pl
Perl脚本):

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

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

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

我找到了帮助部分(通过键入
help binary general
,在
gnuplot
终端中找到了相同的内容),但理解起来有困难(在网上找不到更多其他信息)。因此-在联机搜索(少数)示例后-我在终端模式下启动
gnuplot
,并尝试以下
gnuplot
命令:

plot“bin.dat”binary skip=4数组=100x1:100x1格式='%uint8%uint8'原点=(0,0):(100,0)使用0:1和行

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

然后我想-好的,如果有“太多的
使用了
”,那么我将在那里绘制
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)更改为(0100)),最后得到一个不生成任何消息的命令:

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
!/usr/bin/env perl
使用5.10.1;
使用警告;
严格使用;
使用open IO=>':原始';
二进制模式(STDIN);
二进制模式(标准输出);
我的$signature=“SIGN”;
我的@signature=unpack('C*',$signature);
my(@ch1,@ch2)=()x2;
#生成100个(co)正弦波样本
对于(我的$ix=0;$ix<100;$ix++){
我的$val1=1+sin($ix*2*3.14/100)#范围:0-2
my$val2=1+cos($ix*2*3.14/100)#范围:0-2
my$ch1val=int($val1*32);
my$ch2val=int($val2*32+64);
推送(@ch1,$ch1val);
推送(@ch2,$ch2val);
#打印标准“val[$ix]:$ch1val,$ch2val\n”;
}
#随机生成30个样本
我的@end=();
对于(my$ix=0;$ix<30;$ix++){
my$val=int(128*rand()+32);
推送(@end,$val);
#~print STDERR“val[$ix]:$val\n”;
}
#连接数组:
my@output=(@signature,@ch1,@ch2,@end);
my$sizarr=标量(@output);
#~print STDERR“…”;
#打印输出-uint8:“C”
我的$outsr=包装(“C*”,@output);
my$lenstr=长度($outstr);
#~print STDERR“输出大小:$sizarr;输出长度:$lenstr\n”;
打印$outsr;
#结束

好吧,在上面的问题中有一些误解;我使用的是gnuplot 4.4。首先,请注意我是如何认为“
array=100x1:100x1
”中的“
100x1
”表示100行1列的数据集-这与1D数组相同(隐含索引)。但是,这不是
那么简单;请注意,
帮助二进制数组
中说:

注意:Gnuplot版本4.2使用了语法array=128x128,而不是
array=(128128)。旧语法现在已被弃用,但可能
仍在工作[……]

坐标将由gnuplot生成。必须指定一个数字
对于数组的每个维度。例如,
array=(10,20)
表示
基本采样结构是二维的,沿方向有10个点
第一(x)维[…]

因此,即使“
100x1
”在概念上可能与1D数组相同——仅通过这样编写,我已经向
gnuplot
指示了一个2D数据(例如,一个图像;我希望它的实例化方式不同于在
gnuplot
内部包含100个元素的1D数组)。因此,我应该编写“
array=(100)”:(100)
”。请注意,括号原则上可以删除1D,因此“
数组=100:100
”也可以-除非使用
-1
(读取到文件末尾)作为维度;然后必须使用括号,否则会发生错误

然后,出现了多条记录的问题。我在
gnuplot
中几乎找不到对这些“多条记录”的引用-有:

如果有多个大数据集要打印,只需创建多个文件

一、 首先,我很高兴他们保留了多记录功能,但我真希望能更好地解释它。我在以下网站上找到了另一条评论:

…gnuplot(即3.6)可以在单个记录上绘制数据组合,但不能组合来自多个记录的数据,更不用说多个数据集了

您必须编写一个预处理器来执行这些计算

帮助二进制数组只说:

冒号可以用来分隔
gnuplot> plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uchar%uchar' origin=(0,0):(0,100) using 1 with lines
gnuplot> 
#!/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