|
From: Fernando P. <Fer...@co...> - 2005-02-01 19:48:44
|
Hi all,
I have a question: in interactive (ipython -pylab) mode, a call to
savefig('foo.eps') (either via %run or straight at the prompt) still pops up a
GUI plot window. If I run the same script from a system command line, the eps
is made, but no GUI opens (what I consider the correct behavior).
Is this something that should be fixed in ipython or in matplotlib?
Cheers,
f.
ps. Yes, John, I've finally started to use matplotlib for my own work. Brace
yourself, I'm compiling a pretty hefty list of things to do. I hope you don't
plan on sleeping much in the coming months ;)
|
|
From: John H. <jdh...@ac...> - 2005-02-01 20:39:20
|
>>>>> "Fernando" == Fernando Perez <Fer...@co...> writes:
Fernando> Hi all, I have a question: in interactive (ipython
Fernando> -pylab) mode, a call to savefig('foo.eps') (either via
Fernando> %run or straight at the prompt) still pops up a GUI plot
Fernando> window. If I run the same script from a system command
Fernando> line, the eps is made, but no GUI opens (what I consider
Fernando> the correct behavior).
Fernando> Is this something that should be fixed in ipython or in
Fernando> matplotlib?
For the sake of clarity, let's consider the canonical script
import matplotlib
matplotlib.use('PS')
from pylab import *
plot([1,2,3])
savefig('test.ps')
show()
When run from the shell, it does what you want -- makes a PS with no
popup. It fails in ipython (pops up a window) because you have
already selected a backend and all pylab commands are directed to that
backend.
How to fix it?
* ipython invokes an external python process to run each script. Of
course you pay a performance hit here, and this would likely change
the meaning of the way run is meant to work (eg, are local ipython
shell vars available in a "run" script.
* provide better support for backend switching in matplotlib. Eg,
allowing you at any time to call matplotlib.use. Currently, this
only works before the import of pylab. It may be possible to write
a pylab.use that simply rebinds the 4 backend functions:
new_figure_manager, error_msg, draw_if_interactive, show. At the
end of a "run", you could simply do a
matplotlib.pylab.use(defaultBackend) to rebind. run could be
enhanced to support backend switching
run somescript.py -dPS
much like one can do from the shell.
You know more about python module reloading than I do. How does one
force a module to reload, eg if I wanted to set the rc 'backend'
param and then do, eg
rcParams['backend'] = 'PS'
from backends import new_figure_manager, error_msg, draw_if_interactive, show
to get new symbols?
There may be another way, but those two come to mind. I'll mull it
over.
Fernando> ps. Yes, John, I've finally started to use matplotlib
Fernando> for my own work. Brace yourself, I'm compiling a pretty
Fernando> hefty list of things to do. I hope you don't plan on
Fernando> sleeping much in the coming months ;)
Well, I knew it was coming.... Stress tests are usually a good
thing. Plus, I'm sure you can't do anything to interrupt my sleep
that my 3 kids haven't already mastered!
JDH
|
|
From: Fernando P. <Fer...@co...> - 2005-02-01 21:58:57
|
John Hunter wrote:
>>>>>>"Fernando" == Fernando Perez <Fer...@co...> writes:
>
>
> Fernando> Hi all, I have a question: in interactive (ipython
> Fernando> -pylab) mode, a call to savefig('foo.eps') (either via
> Fernando> %run or straight at the prompt) still pops up a GUI plot
> Fernando> window. If I run the same script from a system command
> Fernando> line, the eps is made, but no GUI opens (what I consider
> Fernando> the correct behavior).
>
> Fernando> Is this something that should be fixed in ipython or in
> Fernando> matplotlib?
>
> For the sake of clarity, let's consider the canonical script
>
> import matplotlib
> matplotlib.use('PS')
> from pylab import *
> plot([1,2,3])
> savefig('test.ps')
> show()
>
> When run from the shell, it does what you want -- makes a PS with no
> popup. It fails in ipython (pops up a window) because you have
> already selected a backend and all pylab commands are directed to that
> backend.
>
> How to fix it?
>
> * ipython invokes an external python process to run each script. Of
> course you pay a performance hit here, and this would likely change
> the meaning of the way run is meant to work (eg, are local ipython
> shell vars available in a "run" script.
Not good. If users want this, they can always just call !python foo.py and be
done. The whole point of %run is to benefit from enhanced tracebacks, debug
hooks, variable access, etc. Doing that across processes is basically impossible.
> * provide better support for backend switching in matplotlib. Eg,
> allowing you at any time to call matplotlib.use. Currently, this
> only works before the import of pylab. It may be possible to write
> a pylab.use that simply rebinds the 4 backend functions:
> new_figure_manager, error_msg, draw_if_interactive, show. At the
> end of a "run", you could simply do a
> matplotlib.pylab.use(defaultBackend) to rebind. run could be
> enhanced to support backend switching
>
> run somescript.py -dPS
>
> much like one can do from the shell.
>
> You know more about python module reloading than I do. How does one
> force a module to reload, eg if I wanted to set the rc 'backend'
> param and then do, eg
>
>
> rcParams['backend'] = 'PS'
> from backends import new_figure_manager, error_msg, draw_if_interactive, show
>
>
> to get new symbols?
You have to carefully wire reload() calls into the proper backends. It's
doable, but doing it generically and with all the complex mpl backend
machinery would likely take a bit of effort.
> There may be another way, but those two come to mind. I'll mull it
> over.
It's not a big deal anyway, just something to think about. My concern is that
if I run from ipython (for testing/debugging) some big script which is wired
to dump hundreds of EPS figures to a plots directory (yes, I do stuff like
that with Gnuplot), my screen is going to be instantly flooded with hundreds
of windows.
But for now, I'd rather see the tk close bug fixed and the figure()
improvements I referred to in my other mail ;)
Cheers,
f
|
|
From: John H. <jdh...@ac...> - 2005-02-01 22:47:37
|
>>>>> "Fernando" == Fernando Perez <Fer...@co...> writes:
Fernando> You have to carefully wire reload() calls into the
Fernando> proper backends. It's doable, but doing it generically
Fernando> and with all the complex mpl backend machinery would
Fernando> likely take a bit of effort.
I have something in CVS that appears to work. You can interactively
switch backends in the pylab interface. The caveat is that you lose
all current figures when doing the switch (close('all') is called).
With some work I could probably patch the current figure manager to
work with multiple simultaneous backends but have no real interest in
doing this now. But it could serve as a basis for an ipython patch
that allowed you to run as ps, eg something like the following
def runps(fname):
curr = pylab.rcParams['backend']
pylab.switch_backend('PS')
reload(pylab)
run(fname)
pylab.switch_backend(curr)
reload(pylab)
or modify "run" to take a kwarg for the backend.
Fernando> But for now, I'd rather see the tk close bug fixed and
Fernando> the figure() improvements I referred to in my other mail
Fernando> ;)
Well, the tk close bug should be a non-issue with CVS matplotlib.
Just make sure you use the rc param (which is the default in CVS)
tk.pythoninspect : False # tk sets PYTHONINSEPCT
And your figure num patch is already in....
JDH
|
|
From: Fernando P. <Fer...@co...> - 2005-02-01 23:18:06
|
John Hunter wrote:
>>>>>>"Fernando" == Fernando Perez <Fer...@co...> writes:
>
>
> Fernando> You have to carefully wire reload() calls into the
> Fernando> proper backends. It's doable, but doing it generically
> Fernando> and with all the complex mpl backend machinery would
> Fernando> likely take a bit of effort.
>
> I have something in CVS that appears to work. You can interactively
> switch backends in the pylab interface. The caveat is that you lose
> all current figures when doing the switch (close('all') is called).
> With some work I could probably patch the current figure manager to
> work with multiple simultaneous backends but have no real interest in
> doing this now. But it could serve as a basis for an ipython patch
> that allowed you to run as ps, eg something like the following
>
>
> def runps(fname):
>
> curr = pylab.rcParams['backend']
> pylab.switch_backend('PS')
> reload(pylab)
> run(fname)
> pylab.switch_backend(curr)
> reload(pylab)
>
>
> or modify "run" to take a kwarg for the backend.
Modifying run is defitely easy. How would you like to have this done?
run -backend=BACKEND foo.py
?
I can't use '-d' because that's already used by %run for something else. Or
we can have a different run altogether
runb BACKEND foo.py
which would be specific to backend switching, modeled on your runps() above.
Please note that I'll only add this if you really see it as an issue, I
brought it up mostly for discussion, because I'm just getting my bearings
around mpl. If you feel it's best to leave things as they are, I'll go along.
> Fernando> But for now, I'd rather see the tk close bug fixed and
> Fernando> the figure() improvements I referred to in my other mail
> Fernando> ;)
>
> Well, the tk close bug should be a non-issue with CVS matplotlib.
> Just make sure you use the rc param (which is the default in CVS)
>
> tk.pythoninspect : False # tk sets PYTHONINSEPCT
Sorry, but no. I just updated CVS (and I did get my new patch, so it seems to
be pretty up to date), set this variable in my .matplolibrc, and I still get this:
In [1]: run tkbug.py
*** I'm about to close figure 1, this will crash VTK!!! ***
Generic Warning: In
/usr/local/installers/src/vtk/VTK/Rendering/vtkTkRenderWidget.cxx, line 633
A TkRenderWidget is being destroyed before it associated vtkRenderWindow is
destroyed. This is very bad and usually due to the order in which objects are
being destroyed. Always destroy the vtkRenderWindow before destroying the user
interface components.
So the Tk window destruction bug remains... Let me know if you make updates,
I'll gladly test. Or if you have TkAgg/Mayavi, this is again the simple test
case for reference:
planck[pylab]> cat tkbug.py
# This script crashes vtk, when run in an ipython -pylab session, with TkAgg
# as the default backend.
# The key is that the pylab.plot() call is made BEFORE the imv.surf call. If
# I call imv.surf() first, it works fine. Something in matplotlib is
# destroying windows it shouldn't.
from matplotlib import pylab
from mayavi.tools import imv
x= y = pylab.arange(256)
z= pylab.rand(256,256)
pylab.plot(range(10))
pylab.show()
imv.surf(x,y,z)
print "*** I'm about to close figure 1, this will crash VTK!!! *** \n"
pylab.close(1)
########################## EOF
> And your figure num patch is already in....
I saw that, great. Many thanks, I really like it better this way.
Best,
f
|
|
From: Fernando P. <Fer...@co...> - 2005-02-01 23:30:20
|
John Hunter wrote:
>And your figure num patch is already in....
Atop the docstring:
figure(num = 1, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')
should read
figure(num = None, figsize=(8, 6), dpi=80, facecolor='w', edgecolor='k')
since that is the real new default.
Cheers,
f
|