Come posso creare un diagramma grafico di una sequenza di numeri dall'input standard?


38

Se ho un file di testo lungo e voglio visualizzare tutte le righe in cui si verifica un determinato modello, faccio:

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

Ora ho una sequenza di numeri (un numero per riga)

Vorrei fare una rappresentazione grafica 2D con la ricorrenza sull'asse xe il numero di linea sull'asse y. Come posso raggiungere questo obiettivo?

inserisci qui la descrizione dell'immagine


1
Potresti spiegare cosa intendi per caso? Vuoi dire quante volte viene trovato un determinato numero nel file? Oppure vuoi solo il valore effettivo del numero sull'asse xe il numero di riga su cui quel numero è stato trovato sull'asse y?
terdon

Intendo per caso semplicemente in quale ordine è stato trovato uno schema. ad es .: prima volta nella linea 400, seconda volta nella linea 410, terza volta nella linea 412 ...
Abdul Al Hazred

Risposte:


44

Puoi usare gnuplotper questo:

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

produce qualcosa di simile

inserisci qui la descrizione dell'immagine

È possibile configurare l'aspetto del grafico per il piacere del tuo cuore, l'output in vari formati di immagine, ecc.


2
Ho scaricato gnuplot e ho provato a provarlo inserendo: seq 100 | gnuplot -p -e 'plot "/ dev / stdin"'. stranamente non è apparso alcun grafico, ma il codice di uscita (echo $?) era 0, quindi non è apparso alcun errore.
Abdul Al Hazred,

@AbdulAlHazred hai installato gnuploto gnuplot-x11? Nel primo caso, per quanto ne so fornisce solo output di file (cioè la generazione pdf, png ecc file ), piuttosto che trame interattive direttamente sullo schermo.
Steeldriver,

@AbdulAlHazred: cosa succede se lo fai seq 100 >seq.dat, quindi esegui in modo gnuplotinterattivo e al prompt prompt plot "seq.dat"?
Nate Eldredge,

@steeldriver Ho un errore Failed to initialize wxWidgets.con gnuplot-x11 ... Devo avere l'uno o l'altro? o possono entrambi gnuploted gnuplot-x11essere installati?
3kstc,

1
Molto bella; aggiungere notitlealla trama senza il titolo.
Victoria Stuart,

13

Lo farei dentro R. Dovrai installarlo ma sarà disponibile nei repository delle tue distribuzioni. Per i sistemi basati su Debian, eseguire

sudo apt-get install r-base

Ciò dovrebbe anche portare, r-base-corema in caso contrario, eseguire sudo apt-get install r-base-coreanche. Una volta Rinstallato, è possibile scrivere un semplice script R per questo:

#!/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()

Lo script sopra creerà un file chiamato output.pdf. Ho testato come segue:

## 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

Sui dati casuali che ho usato, che produce:

inserisci qui la descrizione dell'immagine

Non sono del tutto sicuro di ciò che vuoi tracciare, ma questo dovrebbe almeno indirizzarti nella giusta direzione.


My Rscript v3.4.4 genera plots.pdf per impostazione predefinita, indipendentemente dall'utilizzo di ggplot o plot.
Vorac,

@Vorac intendevi commentare un'altra risposta? Cosa c'entra ggplot con esso? E perché è rilevante il nome file di output predefinito?
terdon

Sul mio sistema debian questo sottoinsieme del tuo script è sufficiente #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");per generare un Rplots.pdf nella stessa directory.
Vorac,

1
@Vorac sì, certo. Ma voglio scegliere il nome del file di output. E, soprattutto, mostra come può essere fatto in modo che possa essere scritto. Altrimenti, ogni volta che esegui un RScript, userà lo stesso nome e sovrascriverà l'output di una preziosa corsa.
terdon

11

Se è possibile che sia sufficiente una stampa terminale molto semplice e che si possa essere soddisfatti da assi invertiti, considerare quanto segue:

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

Quanto sopra mostra una tendenza invertita su una scala del 10% per ogni occorrenza del modello 11 nell'output di seq 1000.

Come questo:

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

Con i punti e il conteggio delle occorrenze potrebbe essere:

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

... che stampa ...

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

Potresti ottenere gli assi come il tuo esempio con molto più lavoro e tput- dovresti fare l' \033[Aescape (o il suo equivalente come è compatibile con il tuo emulatore di terminale) per spostare il cursore su una riga per ogni occorrenza.

Se awk's printfsupporti spazio-padding come il POSIX-shell printflo fa, allora si può utilizzare per fare lo stesso - e probabilmente molto più efficiente pure. Tuttavia, non so come usare awk.


1

Migliorare la risposta di Nate per avere l'output PDF e tracciare le linee (richiede rsvg-convert):

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

0

Oppure puoi reindirizzare i dati stdout tramite pipe a uno script python personalizzato. Ciò ti consentirà un'enorme quantità di personalizzazione e flessibilità nell'analisi, nella pre-elaborazione e nella visualizzazione dei dati.

Ecco un tutorial su questo che ho scritto per fare esattamente come intendi. collegamento

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.