From: Michael H. <mh...@al...> - 2005-11-14 17:49:22
|
Noel O'Boyle wrote: > I have two questions relating to writing graphs to disk. The first is > whether it is possible to do so without first plotting the image on the > screen. On my gnuplot setup, I can accomplish this by typing Gnuplot.GnuplotOpts.default_term = 'unknown' before instantiating the Gnuplot.Gnuplot object. I don't know if that is a generic feature of Gnuplot, though. > The second is related to the following problem with using popen, with > which I think you are familiar: > > ************************************************* > import Gnuplot,os > > error = 0 > for i in range(50): > g = Gnuplot.Gnuplot() > d = Gnuplot.Func("sin(x)") > g.plot(d) > g.hardcopy("gnuplotpy.png",terminal="png") > try: > assert os.path.getsize("gnuplotpy.png")>0 > except AssertionError: > error += 1 > print error > ************************************************* Yes, I'm not surprised by this error (given the one-way communication between Gnuplot.py and gnuplot) but strangely enough, I can't reproduce it here (gnuplot 4.0p0, Debian Linux), even when plotting much larger datasets. > There seems to be no way around this using the popen family of commands > apart from waiting until the file is created: > ************************************************* > size = os.path.getsize("gnuplotpy.png") > while size==0: > time.sleep(0.2) > size = os.path.getsize("gnuplotpy.png") > ************************************************* Even this is not a solution, because the file could only be half-written when your loop is done. > If only Gnuplot returned an exit signal to the calling program, then you > could use popen3 or something and wait for stdout to be closed. > Unfortunately, this doesn't appear to be the case. The only ideas that occur to me are: 1. Use popen3 and look for gnuplot's "gnuplot> " prompt before continuing. But I'm not sure that would work 100%. 2. Have gnuplot write its output to a named pipe with a Python listener. Gnuplot.py should only proceeds after the listener detects the file close from the writer. The listener would have to dump whatever it read into the *real* file. (Yucky and unportable.) > On the other hand, the following approach addresses both of the problems > listed above, and I am afraid that it is difficult for me to convince > myself that using gnuplot-py would be better (for me): > > ************************************************* > import os > > errors = 0 > for i in range(50): > cmdfile = open("cmd.txt","w") > cmdfile.write('set terminal png\nset output "gnuplotpy.png"\n') > cmdfile.write("plot sin(x)\n") > cmdfile.close() > os.system("pgnuplot.exe cmd.txt") > try: > assert os.path.getsize("gnuplotpy.png")>0 > except AssertionError: > errors += 1 > > print errors > ************************************************* > > errors is always zero, as os.system does not return until the command is > completed. > > Would you consider including os.system in some way in gnuplot-py? Are you sure you are really solving the problem, and not just hiding it because your test script takes longer to run? Given that you only saw the problem 27/50 times with the original script (and I didn't see it at all), it seems that the timing of this error is just barely in the danger zone. Second, could you solve your problem more easily in the original script by inserting "g.close()" or "del g" after g.hardcopy()? It might be that the gnuplot process doesn't shut itself down until all commands are complete. Finally, if you want to do the cmd.txt approach, you can still construct the command file (if you prefer) using g = Gnuplot.Gnuplot(filename='cmd.txt') I only use Gnuplot.py myself very rarely now (my work doesn't call for it) and I don't have time to enhance Gnuplot.py properly anymore, so I won't be able to build other approaches into Gnuplot.py in the foreseeable future. Sorry. Michael |