Colormap byteorder bug #1095

Merged
merged 4 commits into from Aug 17, 2012
@@ -1008,6 +1008,7 @@ def tk_window_focus():
'matplotlib.tests.test_basic',
'matplotlib.tests.test_cbook',
'matplotlib.tests.test_colorbar',
+ 'matplotlib.tests.test_colors',
'matplotlib.tests.test_dates',
'matplotlib.tests.test_delaunay',
'matplotlib.tests.test_figure',
View
@@ -515,10 +515,17 @@ def __call__(self, X, alpha=None, bytes=False):
xa = xma.filled() # Fill to avoid infs, etc.
del xma
- if xa.dtype.char in np.typecodes['Float']:
+ # Calculations with native byteorder are faster, and avoid a
+ # bug that otherwise can occur with putmask when the last
+ # argument is a numpy scalar.
+ if not xa.dtype.isnative:
+ xa = xa.byteswap().newbyteorder()
+
+ if xa.dtype.kind == "f":
# Treat 1.0 as slightly less than 1.
- cbook._putmask(xa, xa==1.0, np.nextafter(xa.dtype.type(1),
- xa.dtype.type(0)))
+ vals = np.array([1, 0], dtype=xa.dtype)
+ almost_one = np.nextafter(*vals)
+ cbook._putmask(xa, xa==1.0, almost_one)
# The following clip is fast, and prevents possible
# conversion of large positive values to negative integers.
@@ -0,0 +1,26 @@
+"""
+Tests for the colors module.
+"""
+
+from __future__ import print_function
+import numpy as np
+from numpy.testing.utils import assert_array_equal
+import matplotlib.colors as mcolors
+import matplotlib.cm as cm
+
+def test_colormap_endian():
+ """
+ Github issue #1005: a bug in putmask caused erroneous
+ mapping of 1.0 when input from a non-native-byteorder
+ array.
+ """
+ cmap = cm.get_cmap("jet")
+ # Test under, over, and invalid along with values 0 and 1.
+ a = [-0.5, 0, 0.5, 1, 1.5, np.nan]
+ for dt in ["f2", "f4", "f8"]:
+ anative = np.ma.masked_invalid(np.array(a, dtype=dt))
+ aforeign = anative.byteswap().newbyteorder()
+ #print(anative.dtype.isnative, aforeign.dtype.isnative)
+ assert_array_equal(cmap(anative), cmap(aforeign))
+
+