Построение кривых на графике / графике / холсте итеративно - PullRequest
0 голосов
/ 08 января 2019

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

reset
PATH = 'XRP_'
nmin = 1
nmax = 20

f(x) = log10(x); h(x) = a*x + b 
name(i) = sprintf(PATH.'%04d/data_main_ddnls_twod_mlce.dat', i)
set xrange [0:7]
start = 0
set fit 
do for [i=nmin:nmax]{
    fit [4:] h(x) name(i) using (f($1)):(f($4)) via a, b 
    if (start==0){
        plot name(i) using (f($1)):(f($4)) w l title sprintf("%04d", i)
    } else {
    replot name(i) using (f($1)):(f($4)) w l title sprintf("%04d", i)
}
start = start + 1
pause -1
}
# Add the slope 
replot (1./5.)*x  + 0.5 lc 'black' lw 3 dt 2
unset fit 
# pause -1

Вместо того, чтобы складывать все предыдущие кривые + текущую, она отображает только текущую кривую i-times (см. Цикл кода). Например, после 10 итераций он строит только 10-й файл данных 10 раз (см. Условные обозначения на рисунке)

enter image description here

Как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Причина, по которой ваш график ведет себя так, как он есть, и пример (1) из theozh также делает то, что «replot f (x)» действует, прикрепляя «, f (x)» к концу предыдущей команды plot , Поместив его в цикл, вы в основном создаете последовательные команды

 plot f(x,i)
 plot f(x,i), f(x,i)
 plot f(x,i), f(x,i), f(x,i)
 ...

Да, значение i может меняться каждый раз, но, тем не менее, каждая команда plot создает несколько копий одной и той же вещи.

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

# force identical margins even if the range changes
set margins screen 0.1, screen 0.9, screen 0.1, screen 0.9

# ... same prelimary stuff as shown in the question

# revised loop using multiplot rather than replot
set multiplot
do for [i=nmin:nmax]{
    fit [4:] h(x) name(i) using (f($1)):(f($4)) via a, b 
    plot name(i) using (f($1)):(f($4)) w l \
        title sprintf("%04d", i) at screen 0.9, screen 1.0 - 0.02*i
    unset tics
}
unset multiplot

Обратите внимание, что вы не можете использовать автоматически сгенерированное размещение заголовка, поскольку каждая из многократных итераций поместит заголовок в одно и то же место. Поэтому вместо этого мы используем форму «title foo at». Точно так же лучше отключить генерацию тиков после первого прохода, чтобы не перерисовывать тики и метки каждый раз в цикле.

0 голосов
/ 08 января 2019

Действительно, странное поведение, которого я тоже не ожидал. См. Минимальные примеры ниже.

  • Версия 1: в основном ваша попытка. Не ожидаемый результат. Я тоже не знаю почему.
  • Версия 2: ожидаемый результат. В основном то же самое, но не в цикле.
  • Версия 3: ожидаемый результат, хотя и в цикле, но с использованием eval.

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

### plotting in a loop
reset session
set colorsequence classic

# Version 1
set title "Version 1"
do for [i=1:5] {
    if (i==1) { plot x**i }
    else { replot x**i noautoscale }
}
pause -1

# Version 2
set title "Version 2"
plot x**1
replot x**2 noautoscale
replot x**3 noautoscale
replot x**4 noautoscale
replot x**5 noautoscale
pause -1

# Version 3
set title "Version 3"
do for [i=1:5] {
    if (i==1) { cmd = sprintf("plot x**%d",i) }
    else { cmd = sprintf("replot x**%d noautoscale",i) }
    eval cmd
}
### end of code

enter image description here

...