通过shell命令加速输入管道上的gnuplot列迭代

时间:2016-03-18 13:36:41

标签: caching gnuplot

我有一个脚本,可以使用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。

2 个答案:

答案 0 :(得分:1)

以下命令应该执行您想要的操作。我正在生成一个ona-data-point文件,该文件包含两个参数ij。当您致电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)

答案 1 :(得分:1)

我提出了一个bash脚本,可以解决所有问题:

  • 在迭代列时,用于处理数据的脚本只运行一次
  • 调整情节显示时,无需等待脚本再次运行
  • 我可以将其他参数传递给脚本并将结果缓存
  • 我可以回到以前的论点,而不必等待
  • 它可以与任何脚本一起使用,无论它可能需要什么和多少参数
  • 如果任何文件(脚本或数据)发生更改,则会将其选中并重新运行
  • 它完全透明,无需额外设置或调整
  • 我不必担心清理,因为系统会为我做这件事

我将其命名为$(用于现金/缓存),chmod u+x&#39; d,并将其放在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)
>