Plotando matriz binária 1D (uint8) com vários registros no gnuplot
Eu entendo esta pergunta é semelhante aoGnuplot: Como plotar várias séries temporais a partir de um formato binário; no entanto, eu já configurei um exemplo que é um pouco diferente, então espero que seja OK postar (auto-resposta a seguir).
Estou gerando meus dados binários como este (veja abaixo para ogenbindata.pl
Script Perl):
$ perl genbindata.pl > bin.dat
$ du -b bin.dat
234 bin.dat
Este arquivo binário,bin.dat
é formatado assim (as primeiras duas linhas são baseadas em 1 e em 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
... OndeWW
são 4 bytes de assinatura;XX
são 100 bytes de uma sinusóide com valores de 0 a 63;YY
são 100 bytes de um co-seno com valores de 64 a 127; eZZ
são 30 bytes de valor aleatório; aqui considerando um byte a seruint8
.
O que eu quero fazer, é usar issobin.dat
como isso é (isto é, eu não gostaria de escrever scripts para analisar os dados e enviá-los de uma forma maisgnuplot
formato amigável) - e plotar os dados de seno e cosseno, com cor separada, em um único diagrama.
eu encontreiGeral binário seção da ajuda (o mesmo emgnuplot
terminal digitandohelp binary general
), mas têm dificuldades em entendê-lo (e não conseguimos encontrar muito mais outras informações on-line). Então - depois de procurar por (alguns) exemplos online - eu iniciognuplot
no modo terminal, e estou tentando o seguintegnuplot
comando:
plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uint8%uint8' origin=(0,0):(100,0) using 0:1 with lines
... na esperança de que isso signifique: "Ignore os primeiros quatro bytes, interprete o próximo como 100 bytes de dados 1D (formatados como '% uint8' e origem em 0,0 após o salto), seguido por 100 bytes de dados 1D (100 linhas de uma coluna, formatadas como '% uint8' e origem em 100,0 após o salto) e usar pseudocoluna 0 (índice de ponto) como eixo xe o primeiro resultado das matrizes para traçar com linhas " ... infelizmente,não faz significa que - como nada é plotado, e o comando falha com "Muitos usando especificações para este estilo".
Então eu acho - ok, se houver "muitosusing
", então eu vou apenas traçar o1
lá:
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]
Isso de fato gera um gráfico - uma única linha vermelha chata no y = 0.
Então, dado que se queixa de y range, mudo a ordem dos argumentos de origem ((100,0) para (0,100)), e finalmente obtenho um comando que não gera nenhuma mensagem:
gnuplot> plot "bin.dat" binary skip=4 array=100x1:100x1 format='%uchar%uchar' origin=(0,0):(0,100) using 1 with lines
gnuplot>
... mas traça apenas uma linha inclinada:
... nada como a sinusóide que eu espero:(
Então, minha pergunta é - como posso obtergnuplot
plotar os dados que eu quero?
Aqui está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