Структура цикла внутри gnuplot?

82

Есть ли способ итеративно извлекать данные из нескольких файлов и отображать их на одном графике в gnuplot. Предположим, у меня есть такие файлы, как data1.txt, data2.txt ...... data1000.txt; у каждого одинаковое количество столбцов. Теперь я мог написать что-нибудь вроде-

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"

Но это было бы действительно неудобно. Мне было интересно, есть ли способ пройти через сюжетную часть в gnuplot.

Убийца
источник
Действительно уютная bashфункция в ответе ниже
Hastur

Ответы:

96

Конечно, есть (в gnuplot 4.4+):

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

Переменную iможно интерпретировать как переменную или строку, поэтому вы можете сделать что-то вроде

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

если вы хотите, чтобы линии были смещены друг относительно друга.

Введите help iterationв командной строке Gnuplot для получения дополнительной информации.

Также не забудьте увидеть ответ @DarioP о do forсинтаксисе; это дает вам нечто более близкое к традиционному forциклу.

Andyras
источник
Спасибо за ваше решение "сюжет для [i = 1: 1000] 'data'.i.'. Txt 'с использованием 1: 2 заголовка' Flow '.i" работал у меня .. Я использую gnuplot 5.2 с C ++ в Windows .. ..
MasoodRehman
Но у меня есть другая проблема, я пишу программу, которая записывает K файлов на жесткий диск через fream K - глобальная переменная, поэтому я хочу построить K количество файлов на моем графике, используя gnuplot, который я пробовал для [i = 1 : K], но выдает ошибку неопределенной переменной. Я пробовал вне цикла for из gnuplot, но это тоже не сработало.
MasoodRehman
Я написал функцию на C ++ для gnuplot, которая работает с for [i = 1: 5], но когда я использую for for [i = 1: K], она выдает ошибку ...
MasoodRehman
@MasoodUrRehman похоже, что вы пытаетесь использовать переменную из вашего кода C ++ в вашем скрипте gnuplot; убедитесь, что вы печатаете значение переменной K, когда отправляете команды в gnuplot. Gnuplot говорит «неопределенная переменная», потому что C ++ знает, что такое K, а gnuplot - нет. Если вы все еще застряли, было бы неплохо опубликовать свою проблему как отдельный вопрос C ++.
Andyras
83

Взгляните также на do { ... }команду, начиная с gnuplot 4.6, поскольку она очень мощная:

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
источник
1
Могу ли я также использовать итератор t для ссылки на индекс в массиве, например, имен файлов или цветов?
tommy.carstensen 03
1
Я никогда не пробовал, но не вижу в этом проблем. В конце концов, другая возможность - указать элементы массива (цвета, имена и т. Д.) Непосредственно в квадратных скобках, как показано на help do.
DarioP 03
1
Я задал новый вопрос здесь stackoverflow.com/questions/18591986/loop-over-array-in-gnuplot , потому что для меня не очевидно, как этого можно достичь.
tommy.carstensen 03
10

У меня есть скрипт all.p

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

Здесь две последние строки буквальные, а не эвристические. Тогда я бегу

$ gnuplot -p all.p

Измените *.datтип файла, который у вас есть, или добавьте типы файлов.

Следующий шаг: добавьте в ~ / .bashrc эту строку

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

и поместите файл в all.pдомашний каталог и вуаля. Вы можете отобразить все файлы в любом каталоге, набрав p и введите.

ИЗМЕНИТЬ Я изменил команду, потому что она не сработала. Ранее он содержал list(i)=word(system(ls -1B *.dat),i).

Джонатан Остром
источник
Для меня ваш код не работает. list=system(ls -1B *.dat)Вместо этого мне пришлось писать .
Jaxan
Хм, ладно. Я был на Linux версии 4.6.
Jonatan Öström
1
Я попробовал еще раз, но, как вы говорите, не работает. Мне пришлось использовать одинарные кавычки внутри системного вызова, чтобы ваша команда работала:list=system('ls -1B *.dat')
Jonatan Öström
у меня это не работает. с кавычками или без них. Почему?
Самира 07
@samira Я не знаю.
Jonatan Öström
5

Используйте следующее, если у вас есть отдельные столбцы для построения графика

do for [indx in "2 3 7 8"] {
  column = indx + 0
  plot ifile using 1:column ;  
}
Амит Рухела
источник
1
Здесь представлен только пример, показывающий, как перебирать непоследовательные числа.
rehctawrats
2

Я хотел использовать подстановочные знаки для отображения нескольких файлов, часто помещаемых в разные каталоги, при работе из любого каталога. Решение, которое я нашел, заключалось в создании следующей функции в~/.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
}

и используйте его, например, как plo *.dat ../../dir2/*.out, чтобы отобразить все .datфайлы в текущем каталоге и все .outфайлы в каталоге, который находится на уровень выше и называется dir2.

Джонатан Остром
источник
Вы можете добавить, plo() { [[ $# -eq 0 ]] && echo "Usage plo file1 file2 ..." || { .... } }чтобы не звонить gnuplotбез файлов.
Hastur
0

Вот альтернативная команда:

gnuplot -p -e 'plot for [file in system("find . -name \\*.txt -depth 1")] file using 1:2 title file with lines'
Kenorb
источник