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