Como posso fazer um gráfico de uma sequência de números a partir da entrada padrão?

38

Se tiver um arquivo de texto longo e desejar exibir todas as linhas nas quais um determinado padrão ocorre, eu faço:

grep -n form innsmouth.txt | cut -d : -f1

Agora, tenho uma sequência de números (um número por linha)

Gostaria de fazer uma representação gráfica 2D com a ocorrência no eixo x e o número da linha no eixo y. Como posso conseguir isso?

insira a descrição da imagem aqui

Abdul Al Hazred
fonte
1
Você poderia explicar o que você quer dizer com ocorrência? Você quer dizer quantas vezes um número específico é encontrado no arquivo? Ou você quer apenas o valor real do número no eixo xe o número da linha em que esse número foi encontrado no eixo y?
terdon
Quero dizer por ocorrência simplesmente em que ordem um padrão foi encontrado. por exemplo: primeira vez na linha 400, segunda vez na linha 410, terceira vez na linha 412 ...
Abdul Al Hazred 15/03

Respostas:

44

Você pode usar gnuplotpara isso:

 primes 1 100 |gnuplot -p -e 'plot "/dev/stdin"'

produz algo como

insira a descrição da imagem aqui

Você pode configurar a aparência do gráfico para o deleite do seu coração, imprimir em vários formatos de imagem, etc.

Nate Eldredge
fonte
2
Eu baixei o gnuplot e tentei testá-lo digitando: seq 100 | gnuplot -p -e 'plot "/ dev / stdin"'. estranhamente nenhum gráfico apareceu, mas o código de saída (eco $?) era 0, então nenhum erro apareceu também.
Abdul Al Hazred 15/03/2015
@AbdulAlHazred você instalou gnuplotou gnuplot-x11? no primeiro caso, somente fornece saída de arquivo (ou seja, gera arquivos pdf, png etc. ) em vez de gráficos interativos diretamente na tela.
steeldriver
@AbdulAlHazred: O que acontece se você apenas fizer seq 100 >seq.date executar de forma gnuplotinterativa e no tipo de prompt plot "seq.dat"?
Nate Eldredge
@steeldriver Estou com um erro Failed to initialize wxWidgets.no gnuplot-x11 ... Preciso ter um ou outro? ou ambos gnuplote podem gnuplot-x11ser instalados?
3kstc 17/03/2015
1
Muito agradável; acrescente notitleà plotagem sem o título.
Victoria Stuart
13

Eu faria isso R. Você precisará instalá-lo, mas ele deverá estar disponível em seus repositórios de distribuição. Para sistemas baseados no Debian, execute

sudo apt-get install r-base

Isso também deve trazer, r-base-coremas se não, corra sudo apt-get install r-base-coretambém. Depois de Rinstalar, você pode escrever um script R simples para isso:

#!/usr/bin/env Rscript
args <- commandArgs(TRUE)
## Read the input data
a<-read.table(args[1])
## Set the output file name/type
pdf(file="output.pdf")
## Plot your data
plot(a$V2,a$V1,ylab="line number",xlab="value")
## Close the graphics device (write to the output file)
dev.off()

O script acima criará um arquivo chamado output.pdf. Eu testei da seguinte forma:

## Create a file with 100 random numbers and add line numbers (cat -n)
for i in {1..100}; do echo $RANDOM; done | cat -n > file 
## Run the R script
./foo.R file

Nos dados aleatórios que usei, isso produz:

insira a descrição da imagem aqui

Não tenho muita certeza do que você deseja traçar, mas isso deve pelo menos apontá-lo na direção certa.

terdon
fonte
Meu Rscript v3.4.4 gera plots.pdf por padrão, independentemente de estar usando ggplot ou plot.
Vorac 27/05
@Vorac, você quis comentar outra resposta? O que o ggplot tem a ver com isso? E por que o nome do arquivo de saída padrão é relevante?
terdon
No meu sistema debian, esse subconjunto do seu script é suficiente #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");para gerar um Rplots.pdf no mesmo diretório.
Vorac 27/05
1
@Vorac sim, é claro. Mas eu quero escolher o nome do arquivo de saída. E, mais importante, mostre como isso pode ser feito para que possa ser script. Caso contrário, sempre que você executar um RScript, ele usará o mesmo nome e substituirá a saída de uma execução preciosa.
terdon
11

Se for possível que uma impressão de terminal muito simples seja suficiente e você possa ser satisfeito com eixos invertidos, considere o seguinte:

seq 1000   |
grep -n 11 |
while IFS=: read -r n match
do  printf "%0$((n/10))s\n" "$match"
done

O gráfico acima apresenta uma tendência invertida em uma escala de 10% para cada ocorrência do padrão 11 na saída de seq 1000.

Como isso:

11
        110
        111
        112
        113
        114
        115
        116
        117
        118
        119
                  211
                            311
                                      411
                                                511
                                                          611
                                                                    711
                                                                              811
                                                                                        911

Com pontos e contagem de ocorrências, pode ser:

seq 1000    |
grep -n 11  | {
i=0
while IFS=: read -r n match
do    printf "%02d%0$((n/10))s\n" "$((i+=1))" .
done; }

... que imprime ...

01 .
02           .
03           .
04           .
05           .
06           .
07           .
08           .
09           .
10           .
11           .
12                     .
13                               .
14                                         .
15                                                   .
16                                                             .
17                                                                       .
18                                                                                 .
19                                                                                           .

Você pode obter os eixos como o seu exemplo com muito mais trabalho e tput- você precisaria fazer a \033[Afuga (ou seu equivalente, como é compatível com o seu emulador de terminal) para mover o cursor em uma linha para cada ocorrência.

Se awk's printfsuportes espaço-estofamento como o POSIX-shell printffaz, então você pode usá-lo para fazer o mesmo - e provavelmente muito mais eficiente também. Eu, no entanto, não sei usar awk.

mikeserv
fonte
1

Melhorar a resposta de Nate para obter saída em PDF e traçar linhas (requer o rsvg-convert):

| gnuplot -p -e 'set term svg; set output "|rsvg-convert -f pdf -o out.pdf /dev/stdin"; plot "/dev/stdin" with lines'
Feuerstein
fonte
0

Ou você pode redirecionar os dados stdout através do pipe para um script python personalizado. Isso permitirá uma imensa quantidade de personalização e flexibilidade na análise, pré-processamento e visualização dos dados.

Aqui está um tutorial sobre o que escrevi para fazer exatamente como você pretende. ligação

quartzfun
fonte