我有一个脚本可以转换原始数据以便与 gnuplot 交互使用。scipt采用的参数让我对数据进行一些过滤。原则上,可以通过以下脚本来模拟它:
import time, sys
print('Generating data...', file=sys.stderr)
time.sleep(1)
print('x', '100*x', 'x**3', '2**x')
for x in range(*map(int, sys.argv[1:3])):
print(x, 100*x, x**3, 2**x)
我通过将 shell 命令管道到 gnuplot 并迭代列来在列中绘制一系列数据:
gnuplot> plot for [i=2:4] '< python3 pipe_data.py 1 11' u 1:i w l t columnhead(i)
Generating data...
Generating data...
Generating data...
gnuplot>
目前,当我注意到脚本需要很长时间才能多次运行它时,我会在 gnuplot 之外执行它并将输出保存到文件中。但是,每当我想将参数更改为脚本时,都必须这样做很麻烦。
我希望 gnuplot 只执行一次'< python3 pipe_data.py'
,这样屏幕上只打印一个Generating data...
。这可能吗?
理想情况下,gnuplot 会缓存以 <
开头的特殊文件名的内容。这样就可以在不重新生成数据的情况下调整图的外观,例如:
gnuplot> plot for [i=2:4] '< python3 pipe_data.py 1 11' u 1:i w l t columnhead(i)
Generating data...
gnuplot> plot for [i=2:4] '< python3 pipe_data.py 1 11' u 1:i w lp t columnhead(i)
gnuplot> plot for [i=2:4] '< python3 pipe_data.py 5 12' u 1:i w lp t columnhead(i)
Generating data...
gnuplot> plot for [i=2:4] '< python3 pipe_data.py 1 11' u 1:i w p t columnhead(i)
gnuplot>
当原始数据发生变化时,这可能会成为问题,gnuplot 无法知道这一点。但我仍然希望有一些方法可以达到这种效果。如果不是只使用 gnuplot,那么也许使用一些外部工具?
作为记录,我使用 gnuplot v4.6。
以下命令应该执行您想要的操作。我正在生成一个 ona 数据点文件,该文件采用两个参数,i
和 j
.该文件在调用 plot data(i,j)
时自动生成,然后每次重复使用。通过您的命令更改我的sleep 5; echo %i %i
。如果您不使用整数,则还需要更改格式。
data(i,j) = system(sprintf('name="temp_%i_%i"; if [ ! -s $name ]; then sleep 5; echo %i %i > $name; fi; echo $name', i, j, i, j))
用法示例:
# You'll notice a 5-second pause here while the command is running:
plot data(1,1)
# Now it will run at once because the file already exists:
plot data(1,1)
我想出了一个bash脚本,为我解决了所有问题:
- 循环访问列时,用于处理数据的脚本仅运行一次
- 调整剧情显示时,无需再等待脚本运行
- 我可以将其他参数传递给脚本并缓存结果
- 我可以回到以前的论点,而不必等待 它
- 适用于任何脚本,无论它可能需要什么参数和多少参数
- 如果任何文件(脚本或数据)发生更改,它将被拾取并重新运行
- 它是完全透明的,无需额外的设置或调整 我
- 不必担心清理,因为系统会为我完成清理
我将其命名为$
(用于现金/缓存),chmod u+x
将其命名,并将其放在PATH
中:
#!/bin/bash
# hash all arguments
KEY="$@"
# hash last modified dates of any files
for arg in "$@"
do
if [ -f $arg ]
then
KEY+=`date -r "$arg" + %s`
fi
done
# use the hash as a name for temporary file
FILE="/tmp/command_cache.`echo -n "$KEY" | md5sum | cut -c -10`"
# use cached file or execute the command and cache it
if [ -f $FILE ]
then
cat $FILE
else
$@ | tee $FILE
fi
现在我可以使用<$
而不是<
来利用它:
> plot for [i=2:4] '<$ python3 pipe_data.py 1 11' u 1:i w l t columnhead(i)
Generating data...
> plot for [i=2:4] '<$ python3 pipe_data.py 1 11' u 1:i w lp t columnhead(i)
> plot for [i=2:4] '<$ python3 pipe_data.py 5 12' u 1:i w lp t columnhead(i)
Generating data...
> plot for [i=2:4] '<$ python3 pipe_data.py 1 11' u 1:i w p t columnhead(i)
>