Comment faire un tracé graphique d'une séquence de nombres à partir de l'entrée standard?


38

Si j'ai un long fichier texte et que je veux afficher toutes les lignes dans lesquelles se produit un motif donné, je fais:

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

Maintenant, j'ai une séquence de chiffres (un numéro par ligne)

Je voudrais faire une représentation graphique 2D avec l'occurrence sur l'axe des x et le numéro de ligne sur l'axe des y. Comment puis-je atteindre cet objectif?

entrez la description de l'image ici


1
Pourriez-vous expliquer ce que vous entendez par événement? Voulez-vous dire combien de fois un nombre particulier est trouvé dans le fichier? Ou voulez-vous simplement que la valeur réelle du nombre sur l'axe des x et le numéro de la ligne que ce nombre a été trouvé sur l'axe des y?
terdon

Je veux dire par occurrence simplement dans quel ordre un motif a été trouvé. exemple: première fois dans la ligne 400, deuxième fois dans la ligne 410, troisième fois dans la ligne 412 ...
Abdul Al Hazred

Réponses:


44

Vous pouvez utiliser gnuplotpour cela:

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

produit quelque chose comme

entrez la description de l'image ici

Vous pouvez configurer l'apparence du graphique à votre guise, la sortie dans différents formats d'image, etc.


2
J'ai téléchargé gnuplot et essayé de le tester en entrant: seq 100 | gnuplot -p -e 'plot' / dev / stdin "'. étrangement aucun graphique n'est apparu, mais le code de sortie (echo $?) était 0, donc aucune erreur n'est apparue non plus.
Abdul Al Hazred

@AbdulAlHazred avez-vous installé gnuplotou gnuplot-x11? dans le premier cas, autant que je sache, il ne fournit que la sortie de fichier (c'est-à-dire la génération de fichiers pdf, png, etc. ) plutôt que des tracés interactifs directement à l'écran.
Steeldriver

@AbdulAlHazred: Que se passe-t-il si vous le faites simplement seq 100 >seq.dat, puis exécutez-le de manière gnuplotinteractive et à l'invite plot "seq.dat"?
Nate Eldredge

@steeldriver J'ai une erreur Failed to initialize wxWidgets.avec gnuplot-x11 ... Dois-je avoir l'un ou l'autre? ou peut gnuplot- gnuplot-x11on installer les deux?
3kstc

1
Très agréable; ajouter notitleà l'intrigue sans le titre.
Victoria Stuart

13

Je ferais ça en R. Vous devrez l’installer mais il doit être disponible dans vos dépôts de distributions. Pour les systèmes basés sur Debian, exécutez

sudo apt-get install r-base

Cela devrait également apporter, r-base-coremais sinon, lancez-vous sudo apt-get install r-base-coreaussi. Une fois que vous avez Rinstallé, vous pouvez écrire un script simple pour cela:

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

Le script ci-dessus va créer un fichier appelé output.pdf. J'ai testé comme suit:

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

Sur les données aléatoires que j'ai utilisées, cela produit:

entrez la description de l'image ici

Je ne suis pas tout à fait sûr de ce que vous voulez tracer mais cela devrait au moins vous orienter dans la bonne direction.


Mon Rscript v3.4.4 génère tracés.pdf par défaut, que vous utilisiez ggplot ou plot.
Vorac

@Vorac vouliez-vous commenter une autre réponse? Qu'est-ce que ggplot a à voir avec ça? Et pourquoi le nom de fichier par défaut est-il pertinent?
terdon

Sur mon système Debian, ce sous-ensemble de votre script suffit #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");pour générer un fichier Rplots.pdf dans le même répertoire.
Vorac

1
@Vorac oui, bien sûr. Mais je veux choisir le nom du fichier de sortie. Et surtout, montrez comment cela peut être fait pour qu’il puisse être scripté. Sinon, chaque fois que vous exécuterez un script RScript, celui-ci utilisera le même nom et écrasera la sortie d'un cycle précieux.
terdon

11

Si une impression de terminal très simple peut suffire et que les axes inversés vous satisfont, considérez les points suivants:

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

Les graphiques ci-dessus représentent une tendance inversée sur une échelle de 10% pour chaque occurrence du motif 11 dans la sortie de seq 1000.

Comme ça:

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

Avec les points et le nombre d'occurrences, cela pourrait être

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

... qui imprime ...

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

Vous pouvez obtenir les axes tels que votre exemple avec beaucoup plus de travail et tput- vous devez effectuer l' \033[Aéchappement (ou son équivalent compatible avec votre émulateur de terminal) pour déplacer le curseur d'une ligne vers le haut pour chaque occurrence.

Si awkde » l' printfespace-rembourrage des supports comme le shell POSIX printffait, vous pouvez l' utiliser pour faire la même chose - et probablement beaucoup plus efficace aussi bien. Cependant, je ne sais pas comment utiliser awk.


1

Améliorer la réponse de Nate pour avoir une sortie PDF et tracer des lignes (nécessite 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

Vous pouvez également rediriger les données stdout via un canal vers un script python personnalisé. Cela vous permettra une énorme quantité de personnalisation et de flexibilité pour l'analyse, le pré-traitement et la visualisation des données.

Voici un tutoriel sur ce que j'ai écrit pour faire exactement ce que vous souhaitez. lien

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.