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

29

Se tiver um arquivo de texto longo e eu quiser exibir todas as linhas em que 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)

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

    
por Abdul Al Hazred 15.03.2015 / 20:54

5 respostas

37

Você pode usar gnuplot para isso:

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

produz algo como

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

    
por 15.03.2015 / 22:35
12

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

sudo apt-get install r-base

Isso também deve trazer r-base-core , mas se isso não acontecer, execute sudo apt-get install r-base-core também. Depois de ter o R instalado, 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:

Eu não tenho certeza do que você quer plotar, mas isso deve ao menos apontar você na direção certa.

    
por 15.03.2015 / 21:29
9

Se for possível que uma impressão de terminal muito simples seja suficiente e que você possa estar satisfeito com os 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 mostra uma tendência invertida em uma escala de 10% para cada ocorrência do padrão 11 na saída de seq 1000 .

Assim:

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ê poderia obter os eixos como o seu exemplo com muito mais trabalho e tput - você precisaria fazer o 3[A escape (ou seu equivalente como é compatível com seu emulador de terminal) para mover o cursor até uma linha para cada ocorrência.

Se awk printf suportar preenchimento de espaço como o POSIX-shell printf , você poderá usá-lo para fazer o mesmo - e provavelmente muito mais eficiente também. Eu, no entanto, não sei como usar awk .

    
por 15.03.2015 / 22:19
1

Aprimorando a resposta de Nate para ter saída de PDF e para 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'
    
por 23.04.2016 / 17:50
0

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

Aqui está um tutorial sobre isso que escrevi para fazer exatamente como você pretende. link

    
por 18.12.2017 / 15:32