Description
I was trying to plot something in matplotlib/pylab using
plot((1+np.array([0, 1.e-15]))*1.e27)
which would result in some error message. I use python 3.5.1, numpy 1.11.0, matplotlib 1.5.1
The error arise because somewhere in the matplotlib internals a large integer is added to an array of float64, the result, however is a numpy array of dtype numpy.object with python floats as members
In [1]: np.asarray([1.,2.,3.]) + 1000000000000000000000000000
with output
Out[1]: array([1e+27, 1e+27, 1e+27], dtype=object)
similar for multiplication. I assume this originates from conversion of the scalar to a np.ndarray before the mathematical operation, which seems reasonable at first, but has bad results in the end.
In [2]: np.asarray(1000000000000000000000000000)
Out[2]: array(1000000000000000000000000000, dtype=object)
Wouldn't it be better if the default behaviour for the first case was dtype of np.float64 by default, and if one wanted a non-native (numpy.object) type this has to be specified explicitly, such that
Out[1']: array([ 1.00000000e+27, 1.00000000e+27, 1.00000000e+27])
The currently resulting array now (with matplotlib) causes the crash when they try to apply some round operation
In [3]: np.round(Out[1])
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-5f7c8426121b> in <module>()
----> 1 np.round(Out[1])
[...]/lib/python3.5/site-packages/numpy/core/fromnumeric.py in round_(a, decimals, out)
2791 except AttributeError:
2792 return _wrapit(a, 'round', decimals, out)
-> 2793 return round(decimals, out)
2794
2795
AttributeError: 'float' object has no attribute 'rint'
The easiest fix at this point would be convert the array to a float array before applying round in round_, changing it to
def round_(a, decimals=0, out=None):
"""
Round an array to the given number of decimals.
Refer to `around` for full documentation.
See Also
--------
around : equivalent function
"""python
try:
if a.dtype == np.object:
a = np.array(a, dtype=np.float)
except AttributeError:
pass
try:
round = a.round
except AttributeError:
return _wrapit(a, 'round', decimals, out)
return round(decimals, out)
It probably should be fixed in matplotlib/ticker class in the first place (matplotlib/matplotlib#6301). Nevertheless, I think the proposed change is a reasonable behaviour for the round_ function instead of giving an error for the case when it is passed an array of python float or integer objects.