Struktura pętli wewnątrz gnuplot?

82

Czy istnieje sposób na iteracyjne pobieranie danych z wielu plików i wykreślanie ich na tym samym wykresie w gnuplot? Załóżmy, że mam pliki takie jak data1.txt, data2.txt ...... data1000.txt; każda ma taką samą liczbę kolumn. Teraz mógłbym napisać coś takiego:

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"

Ale to byłoby naprawdę niewygodne. Zastanawiałem się, czy istnieje sposób na zapętlenie części fabularnej w gnuplot.

pogromca
źródło
Naprawdę przytulna bashfunkcja w odpowiedzi poniżej
Hastur

Odpowiedzi:

96

Na pewno jest (w gnuplot 4.4+):

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

Zmienna imoże być interpretowana jako zmienna lub ciąg, więc możesz zrobić coś takiego

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

jeśli chcesz, aby linie były odsunięte od siebie.

Wpisz help iterationw wierszu poleceń gnuplot, aby uzyskać więcej informacji.

Koniecznie zobacz również odpowiedź @ DarioP na temat do forskładni; to daje coś bliższego tradycyjnej forpętli.

andyras
źródło
Dziękuję za rozwiązanie "plot for [i = 1: 1000] 'data'.i.'. Txt 'przy użyciu tytułu 1: 2' Flow '.i" zadziałało dla mnie. Używam gnuplot 5.2 z C ++ w systemie Windows .. ..
MasoodRehman
Ale mam inny problem, piszę program, który zapisuje liczbę K plików na dysku twardym z za pośrednictwem fream K jest zmienną globalną, więc chcę wykreślić liczbę K plików na moim wykresie za pomocą gnuplot, dla którego próbowałem [i = 1 : K], ale daje błąd niezdefiniowanej zmiennej. Próbowałem na zewnątrz pętli for z gnuplot, ale to też nie działa.
MasoodRehman
Napisałem funkcję w C ++ dla gnuplot, która działa z for [i = 1: 5], ale kiedy używam for [i = 1: K], daje to błąd ...
MasoodRehman
@MasoodUrRehman wygląda na to, że próbujesz użyć zmiennej z kodu C ++ w swoim skrypcie gnuplot; upewnij się, że wypisujesz wartość zmiennej K, kiedy wysyłasz polecenia do gnuplot. Gnuplot mówi „nieokreślona zmienna”, ponieważ C ++ wie, czym jest K, ale gnuplot nie. Jeśli nadal utkniesz, dobrze byłoby opublikować swój problem jako osobne pytanie C ++.
andyras
83

Spójrz także na do { ... }polecenie od wersji gnuplot 4.6, ponieważ jest bardzo potężne:

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
źródło
1
Czy mogę również użyć iteratora t do odniesienia się do indeksu w tablicy zawierającej na przykład nazwy plików lub kolory?
tommy.carstensen
1
Nigdy nie próbowałem, ale nie widzę z tym żadnego problemu. Ostatecznie inną możliwością jest określenie elementów tablicy (kolorów, nazw itp.) Bezpośrednio w nawiasach kwadratowych, jak pokazano w help do.
DarioP,
1
Zadałem tutaj nowe pytanie stackoverflow.com/questions/18591986/loop-over-array-in-gnuplot , ponieważ nie jest dla mnie oczywiste, jak można to osiągnąć.
tommy.carstensen
10

Mam skrypt all.p

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

Tutaj dwa ostatnie wiersze są dosłowne, a nie heurystyczne. Potem biegnę

$ gnuplot -p all.p

Zmień *.datna typ posiadanego pliku lub dodaj typy plików.

Następny krok: Dodaj do ~ / .bashrc tę linię

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

i umieść plik w all.pswoim katalogu domowym i voila. Możesz wydrukować wszystkie pliki w dowolnym katalogu, wpisując p i Enter.

EDYCJA Zmieniłem polecenie, ponieważ nie działa. Wcześniej zawierał list(i)=word(system(ls -1B *.dat),i).

Jonatan Öström
źródło
U mnie twój kod nie działa. list=system(ls -1B *.dat)Zamiast tego musiałem napisać .
Jaxan
Hm ok. Korzystałem z wersji 4.6 na Linuksie.
Jonatan Öström
1
Więc spróbowałem ponownie i jak mówisz, nie działa. Musiałem użyć pojedynczych cudzysłowów w wywołaniu systemowym, aby Twoja komenda zadziałała:list=system('ls -1B *.dat')
Jonatan Öström
to nie działa dla mnie. z cudzysłowami lub bez. czemu?
samira,
@samira Nie wiem.
Jonatan Öström
5

Użyj poniższych, jeśli masz oddzielne kolumny do wykreślenia na wykresie

do for [indx in "2 3 7 8"] {
  column = indx + 0
  plot ifile using 1:column ;  
}
Amit Ruhela
źródło
1
Jedyny przykład podany tutaj, który pokazuje, jak przechodzić przez kolejne liczby.
rehctawrats
2

Chciałem użyć symboli wieloznacznych do wykreślenia wielu plików często umieszczanych w różnych katalogach, podczas pracy z dowolnego katalogu. Rozwiązaniem, które znalazłem, było utworzenie następującej funkcji w~/.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
}

i użyj go np. plo *.dat ../../dir2/*.outdo wykreślenia wszystkich .datplików w bieżącym katalogu i wszystkich .outplików w katalogu, który znajduje się na wyższym poziomie i jest nazywany dir2.

Jonatan Öström
źródło
Możesz dodać, plo() { [[ $# -eq 0 ]] && echo "Usage plo file1 file2 ..." || { .... } }aby uniknąć dzwonienia gnuplotbez plików.
Hastur
0

Oto alternatywne polecenie:

gnuplot -p -e 'plot for [file in system("find . -name \\*.txt -depth 1")] file using 1:2 title file with lines'
kenorb
źródło