Python子进程:如何将命令通过管道传递给gnuplot以绘制变量?

1 投票
2 回答
2688 浏览
提问于 2025-04-16 22:19

我这里并不想做什么复杂的事情。我只是想在下面的脚本中自动绘制一些实验数据:

print "processing: ", filename

gnuplot = Popen(gnuplot_bin,stdin = PIPE).stdin

if state_plot:

        gnuplot.write( "set term x11\n".encode())
        gnuplot.write( "set term png size 1920,1010 \n".encode() )
        gnuplot.write( "set output \"acceleration.png\" \n".encode() )
        gnuplot.write( "set xlabel \"timesteps\" \n".encode() )
        gnuplot.write( "set ylabel \"acceleration\" \n".encode() )
        gnuplot.write( "plot " %filename " using 1 with lines lt -1 lw 0.5 title 'X axis' \n " .encode() )
        gnuplot.write( " " %filename " using 2 with lines lt 1 lw 0.5 title 'Y axis'  \n " .encode() )
        gnuplot.write( " " %filename " using 3 with lines lt 2 lw 0.5 title 'Z axis' \n " .encode() )

但是文件名被当作字面意思处理了。我从gnuplot那里得到了以下错误信息:

第0行:警告:跳过无法读取的文件 "" %filename "" 第0行:绘图中没有数据

我已经从sys.argv中解析出了文件名,并确保它是正确和安全的,现在我需要告诉gnuplot去绘制这个文件名所设置的内容。

我尝试过使用转义字符,去掉了&符号,但显然我用错了语法。

有人能帮帮我吗?

编辑:

感谢agf,我解决了python格式的问题:

gnuplot.write( "plot \"%s\" using 1 with lines lt -1 lw 0.5 title 'X axis' ,\ \n " %filename )
        gnuplot.write( "\"%s\" using 2 with lines lt 1 lw 0.5 title 'Y axis' ,\ \n " %filename )
        gnuplot.write( "\"%s\" using 3 with lines lt 2 lw 0.5 title 'Z axis' \n " %filename )

不过现在我在gnuplot上遇到了问题。通常直接使用gnuplot时,我会输入:

gnuplot> plot "state_log_6548032.data" using 4 with lines lt -1 lw 0.5 title "X axis" ,\
>"state_log_6548032.data" using 5 with lines lt 1 lw 0.5 title "Y axis" ,\
>"state_log_6548032.data" using 6 with lines lt 2 lw 0.5 title "Z axis"

但是,通过python发送这些命令到gnuplot似乎会导致错误:

gnuplot> plot "state_log_6548032.data" using 1 with lines lt -1 lw 0.5 title 'X axis' ,\ 
                                                                                       ^
         line 0: invalid character \

gnuplot> "state_log_6548032.data" using 2 with lines lt 1 lw 0.5 title 'Y axis' ,\ 
                                                                                 ^
         line 0: invalid character \

gnuplot> "state_log_6548032.data" using 3 with lines lt 2 lw 0.5 title 'Z axis' 
         ^
         line 0: invalid command

我猜这可能和\,和换行符有关?

2 个回答

1

正如agf所说,问题在于你如何格式化你的字符串。你也可以用+运算符把字符串连接起来,虽然格式化通常会更好。

一般来说,我觉得你应该把gnuplot的代码和python的代码分开。

在gnuplot代码plot.gp中,写明数据应该如何绘制。用你的python脚本生成数据,并把它们以表格的形式写入一个文件,比如一个临时文件。然后运行你的gnuplot脚本,从这个文件中读取数据,具体可以参考这里

6

你想要

    gnuplot.write("plot %s using 1 with lines lt -1 lw 0.5 title 'X axis' \n " % filename1)

可以查看 http://docs.python.org/library/string.html#formatstrings 了解新的格式化方式,以及 http://docs.python.org/library/stdtypes.html#string-formatting 了解旧的格式化方式,这看起来就是你想要做的。

编辑2:我也喜欢wiso的建议的一部分。把gnuplot的命令保存到一个文件里(里面包含你需要插入的变量的格式代码),然后用Python读取这个文件并进行格式化。这样可以把gnuplot的内容分开,你就不用担心引号或换行符的问题了。

如果你想发送很多命令,我建议把所有的字符串放在一个列表里(最好是通过用 file.readlines() 从文件中读取),然后:

for line in lines:
    gnuplot.write(lines)
    gnuplot.flush()

这样每次只发送一行,但你不需要硬编码一个特定的行数。

撰写回答