我有以下代码生成带有gnuplot的图:
import sys, glob, subprocess, os, time
for file in glob.glob('comb_*.out'):
fNameParts = file[5:].split('.')[0].split('-')
gPlotCmd = []
gPlotCmd = 'unset border; set xl "rotation period #"; set yl "T [K]"\n'
gPlotCmd += 'set key above\n'
gPlotCmd += 'set grid xtics ytics\n'
gPlotCmd += 'set term post eps enh color solid\n'
gPlotCmd += 'set xrange [20:876]\n'
gPlotCmd += 'set output "fig_TestRelax-' + fNameParts[1] + '-' + fNameParts[2] + '-' + fNameParts[3] + '-' + fNameParts[4] + '.eps"\n'
conf = fNameParts[1] + '-' + fNameParts[2] + '-' + fNameParts[3]
gPlotCmd += 'plot "' + file + '" using ($1/36000):($9-$3) w l lw 5 title "OP3-OP1 ' + conf + '", "' + file + '" using ($1/36000):($6-$3) w l lw 3 title "OP2-OP1 ' + conf + '", "' + file + '" using ($1/36000):($9-$6) w l lw 1 title "OP3-OP2 ' + conf + '"'
fw = open('temp.plt','w+')
fw.writelines(gPlotCmd)
subprocess.call(["gnuplot","temp.plt"])
print(file)
在上一次循环执行中,似乎没有执行subprocess.call(["gnuplot","temp.plt"])
。在程序结束时,temp.plt与最后一次迭代的数据一起存在。在最后一个循环中也执行print(file)。此外,如果我在程序之后绘制temp.plt,我会得到最后一个图(因此数据侧没有问题)。仅执行行subprocess.call(["gnuplot","temp.plt"])
。我也试过popen并监视stdout和stderr,但两者都是空的(就像在所有其他迭代中一样)。
检查问题是在Linux和Windows以及版本3.3.5和2.7.3中发生的。
我的结论是脚本有问题,但我不知道是什么。
答案 0 :(得分:4)
@ lvc和你的回答是正确的;这是一个缓冲问题,fw.flush()
应该解决它。但是您不需要临时文件,您可以直接将输入命令传递给gnuplot
而无需将其写入磁盘:
from subprocess import Popen, PIPE
p = Popen('gnuplot', stdin=PIPE)
p.communicate(input=gPlotCmd.encode('ascii'))
答案 1 :(得分:3)
这里可能出现的一个错误是文件temp.plt
在您运行gnuplot时实际上并没有写入磁盘。 Python调用writelines后不必立即刷新缓冲区。这意味着当从脚本启动gnuplot时,它会看到一个空文件。它没有给出错误,因为空输入不是错误,并且它无法知道它对其他任何东西的期望。当你在脚本之外运行它时,Python已经退出,因此无法再在自己的缓冲区中保存任何内容。
使用with
语句确保fw在完成后关闭:
with open('temp.plt', 'w') as fw:
fw.writelines(gPlotCmd)
subprocess.call(["gnuplot","temp.plt"])
答案 2 :(得分:1)
好像我想出来了。我错过了fw.close()。最后一行代码应该是:
fw = open('temp.plt','w+')
fw.writelines(gPlotCmd)
fw.close()
subprocess.call(["gnuplot","temp.plt"])
print(file)
现在代码生成了预期的图。