Wie kann ich aus der Standardeingabe eine grafische Darstellung einer Folge von Zahlen erstellen?


38

Wenn Sie eine lange Textdatei haben und alle Zeilen anzeigen möchten, in denen ein bestimmtes Muster vorkommt, mache ich Folgendes:

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

Jetzt habe ich eine Folge von Zahlen (eine Zahl pro Zeile)

Ich möchte eine grafische 2D-Darstellung mit dem Vorkommen auf der x-Achse und der Liniennummer auf der y-Achse erstellen. Wie kann ich das erreichen?

Bildbeschreibung hier eingeben


1
Können Sie erklären, was Sie unter Auftreten verstehen? Meinen Sie damit, wie oft eine bestimmte Nummer in der Datei gefunden wurde? Oder möchten Sie nur den tatsächlichen Wert der Zahl auf der x-Achse und die Zeilennummer, auf der diese Zahl gefunden wurde, auf der y-Achse?
terdon

Ich meine mit Vorkommen einfach in welcher Reihenfolge ein Muster gefunden wurde. Beispiel:
Zum

Antworten:


44

Sie könnten dafür verwenden gnuplot:

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

produziert so etwas wie

Bildbeschreibung hier eingeben

Sie können die Darstellung des Diagramms nach Herzenslust konfigurieren und in verschiedenen Bildformaten usw. ausgeben.


2
Ich habe gnuplot heruntergeladen und versucht, es zu testen, indem ich Folgendes eingebe: seq 100 | gnuplot -p -e 'plot "/ dev / stdin"'. Seltsamerweise erschien kein Graph, aber der Exit-Code (echo $?) war 0, so dass auch kein Fehler auftrat.
Abdul Al Hazred

@AbdulAlHazred hast du installiert gnuplotoder gnuplot-x11? Wenn erstere vorhanden sind, werden nur Dateien ausgegeben (dh PDF-, PNG- usw. Dateien erstellt ) und keine interaktiven Zeichnungen direkt auf dem Bildschirm.
Steeldriver

@AbdulAlHazred: Was passiert, wenn Sie dies nur tun seq 100 >seq.datund dann gnuplotinteraktiv und an der Eingabeaufforderung ausführen plot "seq.dat"?
Nate Eldredge

@steeldriver Ich habe einen Fehler Failed to initialize wxWidgets.mit gnuplot-x11 ... Muss ich den einen oder anderen haben? oder können beide gnuplotund gnuplot-x11installiert werden?
3.

1
Sehr schön; anfügen notitle, ohne den Titel zu zeichnen.
Victoria Stuart

13

Ich würde dies in tun R. Sie müssen es installieren, aber es sollte in Ihren Distributions-Repositories verfügbar sein. Führen Sie für Debian-basierte Systeme

sudo apt-get install r-base

Das sollte auch einfließen, r-base-coreaber wenn nicht, läuft es sudo apt-get install r-base-coreauch. Nach der RInstallation können Sie ein einfaches R-Skript dafür schreiben:

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

Das obige Skript erstellt eine Datei mit dem Namen output.pdf. Ich habe wie folgt getestet:

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

Aus den Zufallsdaten, die ich verwendet habe, ergibt sich:

Bildbeschreibung hier eingeben

Ich bin mir nicht ganz sicher, was Sie zeichnen wollen, aber das sollte Sie zumindest in die richtige Richtung weisen.


Mein Rscript v3.4.4 generiert standardmäßig plots.pdf, unabhängig davon, ob ggplot oder plot verwendet wird.
Vorac

@Vorac wolltest du eine andere Antwort kommentieren? Was hat ggplot damit zu tun? Und warum ist der Standard-Ausgabedateiname relevant?
terdon

Auf meinem Debian-System reicht diese Teilmenge Ihres Skripts aus #!/usr/bin/env Rscript; args <- commandArgs(TRUE); a<-read.table(args[1]); plot(a$V2,a$V1,ylab="line number",xlab="value");, um eine Rplots.pdf im selben Verzeichnis zu erzeugen.
Vorac

1
@Vorac ja natürlich. Aber ich möchte den Namen der Ausgabedatei wählen. Und, was noch wichtiger ist, zeigen Sie, wie es gemacht werden kann, damit Skripte erstellt werden können. Andernfalls wird jedes Mal, wenn Sie ein RScript ausführen, derselbe Name verwendet und die Ausgabe eines wertvollen Laufs überschrieben.
terdon

11

Wenn es sein kann, dass ein sehr einfacher Terminalausdruck ausreicht und Sie mit invertierten Achsen zufrieden sind, sollten Sie Folgendes berücksichtigen:

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

Das obige Diagramm zeigt einen invertierten Trend auf einer 10% -Skala für jedes Auftreten des Musters 11 in der Ausgabe von seq 1000.

So was:

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

Mit Punkten und Vorkommensanzahl könnte es sein:

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

... was druckt ...

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

Sie könnten die Achsen wie in Ihrem Beispiel mit viel mehr Arbeit erhalten und tput- Sie müssten die \033[AEscape-Operation (oder die mit Ihrem Terminal-Emulator kompatible Entsprechung) ausführen , um den Cursor bei jedem Auftreten eine Zeile nach oben zu bewegen.

Wenn awk‚s printfunterstützt platz Polsterung wie die POSIX-Shell - printfFall ist, dann können Sie es verwenden , das gleiche zu tun - und wahrscheinlich weit effizienter als gut. Ich weiß jedoch nicht, wie man es benutzt awk.


1

Die Antwort von Nate für die PDF-Ausgabe und zum Plotten von Linien verbessern (erfordert die 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

Sie können die Standardausgabedaten auch über die Pipe an ein benutzerdefiniertes Python-Skript umleiten. Auf diese Weise können Sie die Daten immens individuell anpassen und flexibel analysieren, vorverarbeiten und visualisieren.

Hier ist ein Tutorial dazu, das ich geschrieben habe, um genau das zu tun, was Sie beabsichtigen. Verknüpfung

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.