2010-12-07 2 views
11

У меня есть 500 файлов для построения, и я хочу сделать это автоматически. У меня есть сценарий gnuplot , который делает строчку с именем файла жестко закодированным. Я хотел бы иметь цикл, который вызывает gnuplot на каждой итерации с другим именем файла, но, похоже, gnuplot не поддерживает аргументы командной строки.Может ли Gnuplot принимать разные аргументы во время выполнения? возможно, с Python?

Есть ли простой способ? Я также установил пакет gnuplot-python в случае, если я могу сделать это с помощью скрипта python. Однако я не мог найти api, так что это немного сложно понять.

Спасибо!

ответ

22

Вы можете превратить ваш GNUPLOT сценарий в сценарий оболочки, предваряя линий

#!/bin/sh 
gnuplot << EOF 

Добавляя линии

EOF 

и заменяя каждый $ на \$. Затем вы можете заменить каждое появление имени файла на $1 и вызвать сценарий оболочки с именем файла в качестве параметра.

0

Вот один из способов сделать это. Ваш входной файл Gnuplot, скажем plot.gp, содержит строку

plot "data" 

или что-то подобное. Сохраните строки перед этой строкой в ​​plot1.gp и линии после этой строки в plot2.gp. Теперь называют Gnuplot, как

gnuplot plot1.gp -e `plot "data"` plot2.gp 

, которая облегчает передачу имени data в командной строке.

+0

Спасибо, это работает, но одна небольшая проблема. У меня есть строки сценария gnuplot, которые используют имя файла, например: set output 'data.png'. Мне нужно также заменить его аргументом командной строки. – user431336 2010-12-07 18:02:25

+0

Конечно, вы могли бы разделить скрипт на еще больше файлов, но, возможно, взгляните на мой другой ответ. – 2010-12-07 18:26:23

1

Простой способ заключается в создании 500 GNUPLOT скриптов, как так:

for filename in list_of_files: 
    outfile = open(filename + '-script', 'w') 
    outfile.write(script_text % (filename,)) 

script_text где текст вашего GNUPLOT сценария с именем файла заменена на %s.

+1

Итак, ваше решение состоит в том, чтобы автоматически создавать 500 сценариев, а затем писать сценарий, который вызывает gnuplot 500 раз. Не самое элегантное решение, но это будет работать. Благодаря! – user431336 2010-12-07 18:11:30

+0

Да, элегантность для людей, которые знают, что они делают. Я очень мало знаю о gnuplot, несмотря на то, что написал http://www.nmichaels.org/graph/graphinator.py – nmichaels 2011-01-26 19:06:05

0

создать файл с именем test.txt, содержащего plot [0:20] x;

Я бегом gnuplot test.txt и я вижу, что Gnuplot действительно прочитать содержимое моего файла, поэтому он делает аргументы поддержки во время выполнения.

6

Что касается $ s в решении Sven Marnach (строки между EOF называются «здесь скриптом» в языке оболочки): по моему опыту, как обычно, используются переменные оболочки, но $ s, предназначенные для самого gnuplot должны быть экранированы.

Вот пример:

for distrib in "uniform" "correlated" "clustered" 
do 
    gnuplot << EOF 
    # gnuplot preamble omitted for brevity 

    set output "../plots/$distrib-$eps-$points.pdf" 
    set title "$distrib distribution, eps = $eps, #points = $points" 

    plot "../plots/dat/$distrib-$eps-$points.dat" using 1:(\$2/$points) title "exact NN" 
EOF 

done 

Обратите внимание на обратный слэш спасаясь доллар, так что Gnuplot видит.

1

Я сделал это несколько раз. Но не используйте EOF, потому что вы не можете писать на bash внутри тегов EOF и EOF < <. В зависимости от имен файлов вы можете сделать это по-разному.

a) Если имена файлов являются петлями (например, 1.DAT 2.dat 3.dat и т.д.)

#!/bin/bash  
for((i=0;i<1;i++)) do 
    echo "plot '-' u 1:2" 
    for((j=1;j<=3;j++)) do 
    cat $i.dat 
    echo "e" 
    done 
done | gnuplot -persist 

Первый цикл является своего рода буфером, чтобы питать все это GNUPLOT.

b) Если имена файлов не являются петлями (например, ñlasjkd.dat ajñljd.mov añlsjkd.gif), сначала необходимо перенести их в новую папку. Затем сделайте

#!/bin/bash  

ffiles=$(ls | xargs)  # a list of the folder's files 
# Use the list to pipe all the data to gnuplot using cat 
for((i=0;i<1;i++)) do 
    echo "plot '-' u 1:2 w lp"; 
    cat $ffiles; 
    echo "e"; 
done | gnuplot -persist 

с) Если вы хотите еще немного, то есть: сохранить информацию о отделенных файлах только на одном файл ... но сохранил в Листки живых использовать «индекс» в Gnuplot (если Gnuplot читает две черные линии догадывается, что это еще одна спецификация)

#!/bin/bash 

ffiles=$(ls|xargs) 
ls $ffiles > ffiles.list # A file with the folder's files 
while read line 
do 
    cat $line; 
    echo -e; echo -e; 
done <ffiles.list> alldata.dat 
# ^-feeding ffiles.list to the while loop 
# and writing the file alldata.dat 

теперь вы можете пойти в GNUPLOT и Acces на одну таблицу

plot 'alldata.dat' index 1 u 1:2 

, и вы увидите, что первый файл появляется в списке «ffiles .список". Если вы хотите увидеть более одного, скажем, 4

plot 'alldata.dat' index 1:4 u 1:2 

сложно, но легко.

1

Если я не понимаю ваш вопрос, есть более простой способ.

В скрипте gnuplot замените все вхождения вашего имени файла на $0. Тогда в Баш, перебираем ваших сюжетных файлов (скажем, они .txt файлы в $ plotsDir) и вызовите Gnuplot:

for f in "$plotsDir/*.txt"; do 
    echo "call '$f'" | gnuplot 
done 
0

Различные способы решения этой проблемы также покрыты How to pass command line argument to gnuplot?:

  • Использование -e
  • Использование -c или call с ARG0 как переменные (Gnuplot> = 5)
  • Использование call с $0 как переменные (Gnuplot < = 4.6.6)
  • Использование переменных окружения и system()
  • конвейеру программу в Gnuplot