用gnuplot设置变量用于循环

时间:2012-06-21 13:00:46

标签: bash variables for-loop gnuplot

我正在尝试使用 set for cycle 命令为gnuplot环境设置变量。 我使用的是4.6版本,根据gnuplot documention (page 70)语法如下:

for [intvar = start:end{:increment}]
for [stringvar in "A B C D"]
Examples:
set for [i = 1:10] style line i lc rgb "blue"

但是我收到了这个错误:

gnuplot> set for [var in gpvars] replace(var,'#_#',' ')
                                 ^
         line 0: Unrecognized option.  See 'help set'.

我的剧本:

#!/bin/bash

OUTDIRNAME="out"
TIMEFORMAT='%d.%m.%y'
GPPARS=( "xlabel "Time"" "ylabel "value1"" "y2label "value2"" "format x "%H:%M"")
GPPARS_MOD=()

for (( i=0; i < ${#GPPARS[@]}; i++)); do 
  FILE=${GPPARS[${i}]}
  echo "arg=${FILE}"
  GPPARS_MOD+=( "`echo "${FILE}" | sed -e 's/ /#_#/g'`" )
done

gnuplot << EOF
reset

replace(S,C,R)=(strstrt(S,C)) ? \
    replace( S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] ,C,R) : S

set terminal png
set output "${OUTDIRNAME}/graph.png"
set timefmt "${TIMEFORMAT}"
set xdata time

gpvars="${GPPARS_MOD[@]}"

set for [var in gpvars] {
   replace(var,'#_#',' ')
}

...

EOF

...

exit 0 

我也在使用函数替换,因为空格(gnuplot忽略转义序列)该函数可以完美地用于循环绘图。 我已尝试使用和不使用函数以及没有空格的变量,但结果是相同的。

1 个答案:

答案 0 :(得分:1)

作为旁注 - 我不确定我相信你的bash阵列会按照你想要的方式对事物进行分组......对我来说,你的报价会被剥夺。尝试:

GPPARS=( "xlabel 'Time'" "ylabel 'value1'" "y2label 'value2'" "format x '%H:%M'")

代替。 (内部双引号替换为单引号)

这是一个棘手的问题 - 你使用gnuplot 4.6是一件好事,否则我不确定如何解决它。 (编辑 - 使用gnuplot 4.4,您可以使用wordwordsifrereadexists和宏的组合,但这是一个非常混乱的解决方案)

请注意,您拥有的内容不起作用,因为它类似于:

MYLABEL='xlabel "foo"'
set MYLABEL

在执行set命令之前,Gnuplot不会扩展MYLABEL,以便您可以执行以下操作:

MYLABEL="totally cool X label here!"
set xlabel MYLABEL

你想要可以使用宏完成什么(但是唉,不是迭代):

set macro 
MYLABEL='xlabel "foo"'
set @MYLABEL

但这在这里并不常用,因为宏扩展发生在其他任何事情之前(例如功能评估)。你需要的是gnuplot在4.6中引入的更一般的迭代结合eval

do for [ var in gpvars ] {
    eval( 'set '.replace(var,'#_#',' ') )
}

编辑 - gnuplot 4.2+解决方案

#top of script -- Nothing should go here.
replace(S,C,R)=(strstrt(S,C)) ? \
     replace( S[:strstrt(S,C)-1].R.S[strstrt(S,C)+strlen(C):] ,C,R) : S
if( ! exists("N") ) N=1
TODO="${GPPARS_MOD[@]}"
set macro
do_set=replace(word(TODO,N),'#_#',' ')
set @do_set
N=N+1
if( N <= words(TODO) ) reread
#rest of script here ...