Вызов Gnuplot из скриптов GAWK и Bash, строит только первый график

Хорошо, вот в чем дело. Я начинаю писать бакалаврскую диссертацию по вычислительному материаловедению и пытаюсь составить несколько сценариев, которые помогут подготовиться к анализу данных.

Я готовил сценарий GAWK, который в основном берет некоторые данные (расположенные в 4 столбца), извлекает два из них и отображает их в GNUPLOT. Для достижения этой цели я читаю файл данных с несколькими временными шагами и связанные с ними данные в нем, разбиваю файл на отдельные файлы .dat для каждого временного шага.

Оттуда я просто генерирую базовый сценарий ввода для GNUPLOT и рисую каждый временной шаг в том виде, в каком они встречаются в файле данных.

Проблема в том, что по какой-то причине все сгенерированные графики представляют собой точно такие же графики (в данном случае всегда первый временной шаг), но они сохраняются как правильный временной шаг.

Я уже просмотрел и отслеживал каждую переменную / имя файла на протяжении всего сценария и, наконец, определил, что проблема так или иначе связана с вызовом GNUPLOT из сценария. Я взял свою системную команду и написал короткий сценарий bash, который вызывает gnuplot из цикла for:

#!/bin/bash
for file in ./*gnu
do
   gnuplot $file
done

И это по-прежнему вызывает ту же проблему, когда все графики одинаковы. Затем я просто запустил команду gnuplot * gnu из командной строки в каталоге, содержащем файлы .gnu, и это сработало.

Я думаю, мне просто интересно, есть ли какой-то буфер, который мне нужно очистить, или я просто что-то упускаю?

Скрипт GAWK представлен ниже. Я все еще новичок в этом, поэтому, если вы хотите прокомментировать сценарий с некоторой конструктивной критикой, я был бы очень признателен за это.

#!/opt/local/bin/gawk -v inputf=$1 -f                                                   

# Write gnuplot files and plot RDF data                                                 
function plot_rdf(timestep, Load_RDF_dat)
{
# Set number of digits in filenames to 6 so data is organized                           
    if (timestep < 10){
        pad_timestep="00000"timestep;
    }
    else if (timestep < 100){
        pad_timestep="0000"timestep;
    }
    else if (timestep < 1000){
        pad_timestep="000"timestep;
    }
    else if (timestep < 10000){
        pad_timestep="00"timestep;
    }
    else if (timestep < 100000){
        pad_timestep="0"timestep;
    }
    else{
        pad_timestep=timestep;
    }

# Give output filenames                                                                 
       gnu_file="plot_RDF_"pad_timestep".gnu";
       png_file="RDF_"pad_timestep".png";

# Create input files for gnuplot                                                        
       print "set output \""png_file"\"" >> gnu_file;
       print "set terminal png" >> gnu_file;
       print "plot './"Load_RDF_dat"' u 1:2" >> gnu_file;
       close(gnu_file);
       system("gnuplot "gnu_file);
}


# Main part of script                                                                   
{
# Parse the RDF data and save it to GNUPLOT readable files                              
    while(getline < inputf){
       if ($1 == "#"){
           # skips the three commented header lines                                     
           next;
       }
       else if (NF == 2){
           timestep=$1;
           bin_num=$2;
           print "Reading timestep "timestep;
           RDF_dat="RDF_"timestep".dat";
           next;
       }
       else if (NF == 4){
           print $2" "$3 >> RDF_dat;
           if ($1 == bin_num){
               plot_rdf(timestep, RDF_dat);
               close(RDF_dat);
           }
           next;
       }
    }
    close(inputf);
    close(RDF_dat);
 }

Фрагмент файла данных, который я читаю:

# Time-averaged data for fix rdf
# TimeStep Number-of-rows
# Row c_allrdf[1] c_allrdf[2] c_allrdf[3]
500 100
1 0.005 0 0
2 0.015 0 0
3 0.025 0 0
4 0.035 0 0
5 0.045 0 0
6 0.055 1.16597 0.00133333
7 0.065 2.08865 0.00466667
8 0.075 1.56958 0.008
9 0.085 0.733433 0.01
10 0.095 0.587288 0.012
600 100
1 0.005 0 0
2 0.015 0 0
3 0.025 2.79219 0.000666667
4 0.035 2.86766 0.002
5 0.045 0 0.002
6 0.055 0.582985 0.00266667
7 0.065 2.08865 0.006
8 0.075 0.62783 0.00733333
9 0.085 0.488955 0.00866667
10 0.095 1.17458 0.0126667

Обычно в каждом разделе временного шага содержится 100 наборов данных, но я решил сократить здесь, чтобы вы поняли идею.


person Steve    schedule 24.09.2012    source источник
comment
и, наконец, определили, что проблема каким-то образом связана с вызовом GNUPLOT из сценария - разве вы не чувствуете, насколько странным этот вывод? проблема в в вашем скрипте, а не в вызове gnuplot из скрипта.   -  person Karoly Horvath    schedule 25.09.2012


Ответы (2)


Как отмечает mgilson, вы могли не вызвать plot_rdf из-за отсутствия $1 == bin_num. Обратите внимание, что вызов awk с именем файла данных в командной строке упрощает использование встроенного в awk цикла чтения файлов. Это проиллюстрировано следующей перезаписью вашей awk-программы. Также обратите внимание:
• использование > вместо >> в двух местах
• закрытие RDF_dat перед запуском gnuplot вместо
• использование pad_timestep = sprintf("%06d", timestep); вместо неуклюжей серии if операторов

Для следующих целей я поместил программу в файл so-gnuplot-awk, данные как есть в файл data-so-gnuplot и вызвал программу через

awk -f so-gnuplot-awk data-so-gnuplot

Программа:

# Parse the RDF data and save it to GNUPLOT readable files
BEGIN { dopen=0 }

NF==2 {
    if (dopen) plot_rdf(timestep, RDF_dat);
    timestep = $1;
    print "Reading timestep "timestep;
    RDF_dat="RDF_"timestep".dat";
    printf "" > RDF_dat     # Init empty file
    dopen = 1;
}

NF == 4 {  if (dopen) print $2" "$3 >> RDF_dat; }

# Write gnuplot files and plot RDF data
function plot_rdf(timestep, Load_RDF_dat) {
# Set output filenames & create gnuplot command file
    pad_timestep = sprintf("%06d", timestep);
    gnu_file="plot_RDF_"pad_timestep".gnu";
    png_file="RDF_"pad_timestep".png";
    print "set output \""png_file"\"" > gnu_file; # Use > first
    print "set terminal png" >> gnu_file;
    print "plot './"Load_RDF_dat"' u 1:2" >> gnu_file;
    close(gnu_file);
    close(RDF_dat);
    print "Plotting with "RDF_dat" into "png_file
    system("gnuplot "gnu_file);
    dopen=0
}

END { if (dopen) plot_rdf(timestep, RDF_dat); }
person James Waldby - jwpat7    schedule 25.09.2012
comment
Ах, спасибо, это сработало для меня. То, что кто-то другой пишет сценарии gawk, определенно помогло мне лучше понять язык. Спасибо за помощь! - person Steve; 30.09.2012

Я не уверен, что смогу ответить на ваш вопрос - однако я скажу, что, когда я немного изменил ваш файл данных, он (казалось) работал отлично для меня.

Вот моя измененная версия вашего файла данных:

# Time-averaged data for fix rdf
# TimeStep Number-of-rows
# Row c_allrdf[1] c_allrdf[2] c_allrdf[3]
500 100
1 0.005 0 0
2 0.015 0 0
3 0.025 0 0
4 0.035 0 0
5 0.045 0 0
6 0.055 1.16597 0.00133333
7 0.065 2.08865 0.00466667
8 0.075 1.56958 0.008
9 0.085 0.733433 0.01
10 0.095 0.587288 0.012
100 0.095 0.56 0.014     #<-added this line
600 100
1 0.005 0 0
2 0.015 0 0
3 0.025 2.79219 0.000666667
4 0.035 2.86766 0.002
5 0.045 0 0.002
6 0.055 0.582985 0.00266667
7 0.065 2.08865 0.006
8 0.075 0.62783 0.00733333
9 0.085 0.488955 0.00866667
10 0.095 1.17458 0.0126667
100 0.095 1.179 0.12      #<-added this line

Эти строки были необходимы для "запуска" функции построения графика gnuplot из-за следующих строк:

   if ($1 == bin_num){
       plot_rdf(timestep, RDF_dat);
       close(RDF_dat);
   }

Поскольку bin_num берется из второго поля в «шапке». (например, 600 100).

Я не уверен, правильно ли вы настроили это в вашем полном файле данных или нет. Также я назвал сценарий так:

gawk -f test.awk -v inputf=test.dat test.dat

который вначале полностью игнорирует ваш шебанг, но я читал, что во многих системах возникают проблемы с их правильным разделением.

Наконец, какая у вас версия gnuplot? Если у вас 4.6, вы можете избавиться от этой боли, почти полностью пропустив gawk скрипт и заменив его более простым.

person mgilson    schedule 24.09.2012
comment
Да, я сожалею об этом, вы правы, для запуска следующего файла необходимо соответствие номера бункера в данных. Не думал об этом, когда размещал образцы данных. Я использую Gnuplot 4.6, но я не знал, что вы можете сделать это в Gnuplot. - person Steve; 25.09.2012