In trying to track down a bug in matplotlib, I have come across tsome
very strange numpy behavior. Basically, whether or not I call
np.seterr('raise') or not in a matplotlib demo affects the behavior of
seterr in another (pure numpy) script, run in a separate process.
Something about the numpy state is persisting between python sessions.
This appears to be platform specific, because I have only been able
to verify it on 1 platform (quad code xeon 64 bit running fedora) but
not on another (solaris x86).
Here are the gory details. Below is a cut-and-paste from a single
xterm session, with some comments sprinkled in.
Some version info::
~> uname -a
Linux bic128.bic.berkeley.edu 2.6.25.10-47.fc8 #1 SMP Mon Jul 7
18:31:41 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux
~> python -V
Python 2.5.1
~> python -c 'import numpy; print numpy.__version__'
1.2.0.dev5564
~> python -c 'import matplotlib; print matplotlib.__version__'
0.98.3rc1
With mpl svn, head over to the examples directory and grab the data
file needed to show this bug::
~> cd mpl/examples/pylab_examples/
pylab_examples> wget http://matplotlib.sourceforge.net/tmp/alpha.npy
--11:22:08-- http://matplotlib.sourceforge.net/tmp/alpha.npy
=> `alpha.npy'
Resolving matplotlib.sourceforge.net... 66.35.250.209
Connecting to matplotlib.sourceforge.net|66.35.250.209|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 688 [text/plain]
100%[===================================================================>]
688 --.--K/s
11:22:08 (111.19 MB/s) - `alpha.npy' saved [688/688]
Run the geo_demo.py example. This has np.seterr set to "raise". It
will issue a
floating point error::
pylab_examples> head -5 geo_demo.py
import numpy as np
np.seterr("raise")
from pylab import *
pylab_examples> python geo_demo.py
Traceback (most recent call last):
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/backends/backend_gtk.py",
line 333, in expose_event
self._render_figure(self._pixmap, w, h)
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/backends/backend_gtkagg.py",
line 75, in _render_figure
FigureCanvasAgg.draw(self)
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/backends/backend_agg.py",
line 261, in draw self.figure.draw(self.renderer)
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/figure.py",
line 759, in draw
for a in self.axes: a.draw(renderer)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/axes.py",
line 1523, in draw
a.draw(renderer)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/axis.py",
line 718, in draw
tick.draw(renderer)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/axis.py",
line 186, in draw
self.gridline.draw(renderer)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/lines.py",
line 423, in draw
tpath, affine = self._transformed_path.get_transformed_path_and_affine()
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/transforms.py",
line 2089, in get_transformed_path_and_affine
self._transform.transform_path_non_affine(self._path)
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/transforms.py",
line 1828, in transform_path_non_affine
self._a.transform_path(path))
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/transforms.py",
line 1828, in transform_path_non_affine
self._a.transform_path(path))
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/transforms.py",
line 1816, in transform_path
self._a.transform_path(path))
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/projections/geo.py",
line 264, in transform_path
return Path(self.transform(ipath.vertices), ipath.codes)
File
"/home/jdhunter/dev/lib64/python2.5/site-packages/matplotlib/projections/geo.py",
line 249, in transform sinc_alpha = ma.sin(alpha) / alpha
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 1887, in __div__
return divide(self, other)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 638, in __call__
t = narray(self.domain(d1, d2), copy=False)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 413, in __call__
return umath.absolute(a) * self.tolerance >= umath.absolute(b)
FloatingPointError: underflow encountered in multiply
OK, now run the pure numpy test script in a separate python process.
It also has np.seterr set to raise, and
it raises the same error. Nothing too strange (yet)::
pylab_examples> cat test.py
import numpy as np
np.seterr("raise")
import numpy.ma as ma
alpha = np.load('alpha.npy')
alpham = ma.MaskedArray(alpha)
sinc_alpha_ma = ma.sin(alpham) / alpham
pylab_examples> python test.py
Traceback (most recent call last):
File "test.py", line 7, in <module>
sinc_alpha_ma = ma.sin(alpham) / alpham
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 1887, in __div__
return divide(self, other)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 638, in __call__
t = narray(self.domain(d1, d2), copy=False)
File "/home/jdhunter/dev/lib64/python2.5/site-packages/numpy/ma/core.py",
line 413, in __call__
return umath.absolute(a) * self.tolerance >= umath.absolute(b)
FloatingPointError: underflow encountered in multiply
OK, in your editor, comment out the np.seterr line from the
geo_demo.py script, and rerun it. The
demo runs fine w/o error this time and a figure window pops up.
Again, nothing surprising.
pylab_examples> head -5 geo_demo.py
import numpy as np
#np.seterr("raise")
from pylab import *
pylab_examples> python geo_demo.py
OK, now this is where it starts getting funky. Rerun the numpy test script,
with no changes (seterr is still set to raise)::
pylab_examples> cat test.py
import numpy as np
np.seterr("raise")
import numpy.ma as ma
alpha = np.load('alpha.npy')
alpham = ma.MaskedArray(alpha)
sinc_alpha_ma = ma.sin(alpham) / alpham
pylab_examples> python test.py
pylab_examples>
This time it ran w/o errors (and will continue to do so on successive runs).
Same script, same data, same error
codes. I can repeat this many times: if I turn errors back on in
geo_demo, the error is raised in subsequent runs of test.py. If I
turn it back off in
geo_demo.py, it is not raised in subsequent runs of test.py.
I tried this on a solaris x86 box and did not see this behavior.
In mostly unrelated news, I find the exception in the ma divide here a
bit confusing,
because using np sin and divide does not raise this error, and none of
the values are masked. I would expect the divides for the unmasked
portions to have the same floating point behavior. Eg, only the
second divide raises in the example below::
import numpy as np
np.seterr("raise")
import numpy.ma as ma
alpha = np.load('alpha.npy')
alpham = ma.MaskedArray(alpha)
sinc_alpha_ma = np.sin(alpham.data) / alpham.data
sinc_alpha_ma = ma.sin(alpham) / alpham
JDH
_______________________________________________
Numpy-discussion mailing list
[email protected]
http://projects.scipy.org/mailman/listinfo/numpy-discussion