Schleifenstruktur innerhalb des Gnuplots?

81

Gibt es eine Möglichkeit, Daten iterativ aus mehreren Dateien abzurufen und sie in demselben Diagramm in gnuplot zu zeichnen? Angenommen, ich habe Dateien wie data1.txt, data2.txt ...... data1000.txt; jede hat die gleiche Anzahl von Spalten. Jetzt könnte ich so etwas schreiben wie-

plot "data1.txt" using 1:2 title "Flow 1", \
     "data2.txt" using 1:2 title "Flow 2", \
      .
      .
      .
     "data1000.txt"  using 1:2 title "Flow 6"

Aber das wäre wirklich unpraktisch. Ich habe mich gefragt, ob es eine Möglichkeit gibt, den Handlungsteil in Gnuplot zu durchlaufen .

Jägerin
quelle
Wirklich gemütliche bashFunktion in der Antwort unten
Hastur

Antworten:

95

Es gibt sicher (in Gnuplot 4.4+):

plot for [i=1:1000] 'data'.i.'.txt' using 1:2 title 'Flow '.i

Die Variable ikann als Variable oder als Zeichenfolge interpretiert werden, sodass Sie so etwas tun können

plot for [i=1:1000] 'data'.i.'.txt' using 1:($2+i) title 'Flow '.i

wenn Sie möchten, dass Linien voneinander versetzt sind.

Geben Sie help iterationin die gnuplot-Befehlszeile ein, um weitere Informationen zu erhalten.

Lesen Sie auch die Antwort von @ DarioP zur do forSyntax. das gibt Ihnen etwas näher an einer traditionellen forSchleife.

Andyras
quelle
Vielen Dank, dass Ihre Lösung "Plot für [i = 1: 1000] 'data'.i.'. Txt 'mit dem 1: 2-Titel' Flow '.i" für mich funktioniert hat. Ich verwende Gnuplot 5.2 mit C ++ unter Windows. ..
MasoodUrRehman
Aber ich habe ein anderes Problem: Ich schreibe ein Programm, das K Anzahl der Dateien auf die Festplatte schreibt. Via fream K ist eine globale Variable. Daher möchte ich K Anzahl der Dateien in meinem Diagramm mit dem Gnuplot zeichnen, den ich für [i = 1 versucht habe : K] aber es gibt Fehler der undefinierten Variablen. Ich habe draußen nach einer Schleife von Gnuplot versucht, aber das funktioniert auch nicht.
MasoodUrRehman
Ich habe eine Funktion in C ++ für Gnuplot geschrieben, die für [i = 1: 5] funktioniert, aber wenn ich für [i = 1: K] verwende, gibt es einen Fehler ...
MasoodUrRehman
@MasoodUrRehman Es hört sich so an, als würden Sie versuchen, eine Variable aus Ihrem C ++ - Code in Ihrem Gnuplot-Skript zu verwenden. Stellen Sie sicher, dass Sie den Wert der Variablen K drucken, wenn Sie Befehle an gnuplot senden. Gnuplot sagt 'undefinierte Variable', weil C ++ weiß, was K ist, Gnuplot jedoch nicht. Wenn Sie immer noch nicht weiterkommen, ist es möglicherweise hilfreich, Ihr Problem als separate C ++ - Frage zu veröffentlichen.
Andyras
83

Schauen Sie sich auch den do { ... }Befehl seit Gnuplot 4.6 an, da er sehr mächtig ist:

do for [t=0:50] {
  outfile = sprintf('animation/bessel%03.0f.png',t)
  set output outfile
  splot u*sin(v),u*cos(v),bessel(u,t/50.0) w pm3d ls 1
}

http://www.gnuplotting.org/gnuplot-4-6-do/

DarioP
quelle
1
Kann ich den Iterator t auch verwenden, um auf einen Index in einem Array von beispielsweise Dateinamen oder Farben zu verweisen?
Tommy.carstensen
1
Ich habe es nie versucht, aber ich sehe kein Problem damit. Schließlich besteht die andere Möglichkeit darin, die Elemente des Arrays (Farben, Namen oder was auch immer) direkt in den eckigen Klammern anzugeben, wie in gezeigt help do.
DarioP
1
Ich habe hier eine neue Frage gestellt. Stackoverflow.com/questions/18591986/loop-over-array-in-gnuplot , da mir nicht klar ist, wie dies erreicht werden kann.
Tommy.carstensen
10

Ich habe das Skript all.p.

set ...
...
list=system('ls -1B *.dat')
plot for [file in list] file w l u 1:2 t file

Hier sind die beiden letzten Zeilen wörtlich und nicht heuristisch. Dann renne ich

$ gnuplot -p all.p

Wechseln *.datSie zu Ihrem Dateityp oder fügen Sie Dateitypen hinzu.

Nächster Schritt: Fügen Sie diese Zeile zu ~ / .bashrc hinzu

alias p='gnuplot -p ~/./all.p'

und legen Sie Ihre Datei in all.pIhr Home-Verzeichnis und voila. Sie können alle Dateien in einem beliebigen Verzeichnis zeichnen, indem Sie p eingeben und eingeben.

BEARBEITEN Ich habe den Befehl geändert, weil er nicht funktioniert hat. Zuvor enthielt es list(i)=word(system(ls -1B *.dat),i).

Jonatan Öström
quelle
Bei mir funktioniert Ihr Code nicht. Ich musste list=system(ls -1B *.dat)stattdessen schreiben .
Jaxan
Hm, ok. Ich war auf Version 4.6 unter Linux.
Jonatan Öström
1
Also habe ich es noch einmal versucht und wie du sagst, es funktioniert nicht. Ich musste Anzeigen einfache Anführungszeichen innerhalb des Systemaufrufs verwenden, damit Ihr Befehl funktioniert:list=system('ls -1B *.dat')
Jonatan Öström
es funktioniert nicht bei mir. mit oder ohne Anführungszeichen. Warum?
Samira
@ Samira Ich weiß es nicht.
Jonatan Öström
4

Verwenden Sie Folgendes, wenn Sie diskrete Spalten zum Zeichnen in einem Diagramm haben

do for [indx in "2 3 7 8"] {
  column = indx + 0
  plot ifile using 1:column ;  
}
Amit Ruhela
quelle
Das einzige hier bereitgestellte Beispiel zeigt, wie nicht aufeinanderfolgende Nummern durchlaufen werden.
Rehctawrats
2

Ich wollte Platzhalter verwenden, um mehrere Dateien zu zeichnen, die sich oft in verschiedenen Verzeichnissen befinden, während ich von einem beliebigen Verzeichnis aus arbeite. Die Lösung, die ich gefunden habe, bestand darin, die folgende Funktion in zu erstellen~/.bashrc

plo () {
local arg="w l"
local str="set term wxt size 900,500 title 'wild plotting'
set format y '%g'
set logs
plot"
while [ $# -gt 0 ]
        do str="$str '$1' $arg,"
        shift
done
echo "$str" | gnuplot -persist
}

und verwenden Sie es zB wie plo *.dat ../../dir2/*.out, um alle .datDateien im aktuellen Verzeichnis und alle .outDateien in einem Verzeichnis zu zeichnen , das sich zufällig auf einer höheren Ebene befindet und aufgerufen wird dir2.

Jonatan Öström
quelle
Sie können hinzufügen plo() { [[ $# -eq 0 ]] && echo "Usage plo file1 file2 ..." || { .... } }, um zu vermeiden, gnuplotohne Dateien anzurufen .
Hastur
0

Hier ist der alternative Befehl:

gnuplot -p -e 'plot for [file in system("find . -name \\*.txt -depth 1")] file using 1:2 title file with lines'
Kenorb
quelle