【问题标题】:Python subprocess: how to pipe to gnuplot a command to plot a variable?Python子进程:如何通过管道向gnuplot命令绘制变量?
【发布时间】:2011-07-26 22:42:27
【问题描述】:

我不想在这里做任何花哨的事情。我正在尝试在以下脚本中自动绘制一些实验数据:

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 绘制文件名设置的任何名称。 我尝试使用转义字符,删除了 ambersand 但我显然使用了错误的语法。

有人可以帮忙吗?

编辑:

感谢 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

我打赌它与 ,\ 和换行符有关?

【问题讨论】:

标签: python escaping subprocess string-formatting gnuplot


【解决方案1】:

你想要的

    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()

因此它一次发送一行,但您不必硬编码某个数字。

【讨论】:

  • 你不会碰巧知道如何一次向 gnuplot 发送多行代码吗?在 gnuplot 中,我通常发送每个数据,它是每行的参数,以 ,\ 结尾,但这似乎在这里不起作用。
  • 用隐式字符串连接试试。
  • 感谢您的帮助,遗憾的是这也没有帮助。问题出在 gnuplot 方面,而不是 python。
  • 如何循环遍历行,并在其间刷新缓冲区?
  • 将试一试编辑:您的解决方案更简洁,循环并将命令放在文件中,我将不得不这样做,因为命令比上面发布的要多得多。但是,我不断收到的错误似乎来自“,\”部分。我不知道为什么我必须首先在控制台中发送“,\”。同样在控制台中我发送“,\ ENTER”所以我猜它实际上是一个“,\ n”?这似乎导致了我的错误
【解决方案2】:

正如 agf 所说,问题在于你如何格式化你的字符串。或者,您可以使用 + 运算符连接字符串,即使格式通常更好。

总的来说,我认为您应该将 gnuplot 代码与 python 代码分开。

在 gnuplot 代码plot.gp 中放置数据应该如何绘制。使用您的 python 脚本生成数据并以表格格式将它们写入文件,例如temp file。然后运行从文件中读取的 gnuplot 脚本,例如参见 here

【讨论】:

  • 或者只是让 Python 从文件中读取 gnuplot 指令并使用字符串格式来放入变量。这将事物分开,而无需写出数据并单独运行 gnuplot 脚本。
  • 谢谢两位的建议,我会调查的。可悲的是,我一直在寻找一个快速而肮脏的解决方案,但似乎这毕竟不会那么简单。
猜你喜欢
  • 2016-03-19
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 2010-11-05
  • 2015-07-18
  • 2023-02-01
  • 1970-01-01
相关资源
最近更新 更多