John Hunter wrote:
"Fernando" == Fernando Perez <Fernando.Perez@...76...> writes:
> planck[pylab]> cat tkbug.py from matplotlib import pylab
> pylab.plot(range(10)) pylab.show()
> # Now I try to run this with plain python, no ipython in
> sight:
This is the result of adding
if rcParams['tk.pythoninspect']:
os.environ['PYTHONINSPECT'] = '1'
to tkagg. Comment out the pythoninspect line (or set the rc param
accordingly) and see if makes a difference. The pythoninspect thing
appears to be required to make idle work in interactive mode, though
it was introduced for other reasons I won't go into now.
OK, to summarize things with respect to this bug. Indeed, commenting out the pythoninspect line solves the spurious prompt problem. But it does nothing to the close('all') bug. I managed to find a small test case to replicate the bug:
planck[pylab]> pylab
In [1]: 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
In [2]: run tkbug
*** 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.
Somehow, it seems that the Tk figure manager is messing with windows it shouldn't touch.
On a related note, I've been playing with some things in matplotlib which require looping through figure lists, making new figures with guaranteed new numbers, etc. I'd like to propose a change.
I'd like figure() to allow calling wit None as the num argument. If num is None, it would produce a guaranteed new figure window, with a number equal to the currently highest + 1. This would make it easy, amongst other things, to write code which displays arrays with a proper aspect ratio by wrapping imshow() or figimage(). I can currently make such a guaranteed new number by using the following as a patch to pylab.py:
if num==0:
error_msg('Figure number can not be 0.\n' + \
'Hey, give me a break, this is matlab(TM) compatability')
# NEW CODE
if num is None:
allnums = [f.num for f in _pylab_helpers.Gcf.get_all_fig_managers()]
if allnums:
num = max(allnums) + 1
else:
num = 1
# /NEW CODE
I also think the default value for num should be None instead of 1. This would allow you to make the following simple, clean use for building new plots:
planck[~]> pylab
In [1]: plot(range(10))
Out[1]: [<matplotlib.lines.Line2D instance at 0x412ccd8c>]
In [2]: figure()
Out[2]: <matplotlib.figure.Figure instance at 0x412ccd2c>
In [3]: plot(range(20))
Out[3]: [<matplotlib.lines.Line2D instance at 0x410d320c>]
In [4]: figure()
Out[4]: <matplotlib.figure.Figure instance at 0x410d32ac>
In [5]: plot(range(30))
Out[5]: [<matplotlib.lines.Line2D instance at 0x4115b02c>]
without never having to worry about manually managing figure number lists (unless you explicitly want to, which you still can).
Finally, is this really a close bug?
In [20]: fig=plot(range(10))
In [21]: close(fig)
ERROR: Unrecognized argument type to close
It sounds to me from reading the docstring like this should work, but maybe I just misunderstood things...
Regards,
f