Gnuplot多语句函数

5

问题

是否可以定义内部包含多个语句的函数?

背景

我想通过定义函数来自动化创建堆积图所涉及的一些计算。特别的,我希望有像下面这样的代码:

mp_setup(bottom_margin, top_margin) = \
    set tmargin 0; \
    set bmargin 0; \
    mp_available_height = 1.0 - top_margin - bottom_margin; \
    mp_current_height = bottom_margin;
mp_plot(plot_height) = \
    mp_plot_size = plot_height * mp_available_height; \
    set origin 0,mp_current_height; \
    set size 1,mp_plot_size; \
    mp_current_height = mp_current_height + mp_plot_size;

预期使用目的是:

...
set multiplot
mp_setup(0.05, 0.05)

mp_plot(1.0/3.0)
plot ...

mp_plot(2.0/3.0)
plot ...

这样做可以自动将图形堆叠在一起,而不需要为每个图形计算原点和大小。

问题

上面定义函数的方式不可行,因为似乎函数定义的解析在第一个分号处结束;但是这些分号是必需的,以便分隔每个语句(否则,我们会得到无效的“set tmargin 0 set bmargin 0…”)。

似乎Gnuplot不支持任何分组语句的方法(如C/C++中的“{...}”);或者至少我从未遇到过。

可能的解决方案

我知道的唯一存储多个函数并评估它们的方法是使用宏:

mp_setup = "<as above>"
mp_plot = "<as above>"

然而,这里的问题在于宏不允许传递参数,相反,每个变量都必须事先声明,如下所示:

...
set multiplot
top_margin = 0.05
bottom_margin = 0.05
@mp_setup

plot_height = 1.0/3.0
@mp_plot
plot ...

 plot_height = 2.0/3.0
@mp_plot
plot ...

尽管这个解决方案应该可以运行,但并不那么优雅。

难道没有其他方法可以实现吗?


我在我的回答Removing blank gap in gnuplot multiplot中提出了两种解决方案。一种是使用类似于您的方法,但使用eval,另一种是使用语法set multiplot layout ... margins ... spacing ...,这是在5.0版本中新增的(在新年发布)。 - Christoph
@Christoph 谢谢,我会在这个多图的情况下看看它;不过,我仍然想知道是否有一种优雅的方式在 Gnuplot 中使用具有多个语句的函数。 - JP-Ellis
2个回答

3
不,无法定义此类函数。在gnuplot中,用户定义的函数不能包含“set”、“unset”或其他命令。只允许使用返回数值或字符串变量的表达式。在此处,您可以有多个用逗号分隔的表达式:
a = 0
f(x) = (a = a + 1, a + x)
print f(1)
print f(1)

除了使用宏(@var)的解决方案外,我更喜欢在函数内构建字符串并调用eval

set_margin(s, v) = sprintf('set %smargin at screen %f;', s, v)
set_margins(l, r, b, t) = set_margin('l', l).set_margin('r', r).set_margin('b', b).set_margin('t', t)

eval(set_margins(0.1, 0.95, 0.15, 0.98))

针对您的多图布局情况,您还可以参考在gnuplot多图中去除空白间隙


0

你可以这样做

mp_setup(bottom_margin, top_margin)=(tmargin=0,bmargin=0,mp_available_height=1.0 -top_margin-bottom_margin,mp_current_height=bottom_margin)

测试: 打印mp_setup(0.05,0.05) ==> 0.05

正如您所提到的,该函数中的分组语句尚未得到支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接