Revision: 5797
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5797&view=rev
Author:   efiring
Date:     2008-07-21 00:22:19 +0000 (Mon, 21 Jul 2008)

Log Message:
-----------
Expanded delete_masked_points to handle more types of argument

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/cbook.py
    trunk/matplotlib/lib/matplotlib/collections.py
    trunk/matplotlib/unit/cbook_unit.py

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2008-07-20 18:21:11 UTC (rev 5796)
+++ trunk/matplotlib/CHANGELOG  2008-07-21 00:22:19 UTC (rev 5797)
@@ -1,3 +1,6 @@
+2008-07-20 Rewrote cbook.delete_masked_points and corresponding
+           unit test to support rgb color array inputs, datetime
+           inputs, etc. - EF
 
 2008-07-20 Renamed unit/axes_unit.py to cbook_unit.py and modified
            in accord with Ryan's move of delete_masked_points from

Modified: trunk/matplotlib/lib/matplotlib/cbook.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/cbook.py    2008-07-20 18:21:11 UTC (rev 
5796)
+++ trunk/matplotlib/lib/matplotlib/cbook.py    2008-07-21 00:22:19 UTC (rev 
5797)
@@ -6,7 +6,7 @@
 import re, os, errno, sys, StringIO, traceback, locale, threading, types
 import time, datetime
 import numpy as np
-from numpy import ma
+import numpy.ma as ma
 from weakref import ref
 
 major, minor1, minor2, s, tmp = sys.version_info
@@ -1168,41 +1168,82 @@
 
 def delete_masked_points(*args):
     """
-    Find all masked points in a set of arguments, and return
-    the arguments with only the unmasked points remaining.
+    Find all masked and/or non-finite points in a set of arguments,
+    and return the arguments with only the unmasked points remaining.
 
-    This will also delete any points that are not finite (nan or inf).
+    Arguments can be in any of 5 categories:
 
-    The overall mask is calculated from any masks that are present.
-    If a mask is found, any argument that does not have the same
-    dimensions is left unchanged; therefore the argument list may
-    include arguments that can take string or array values, for
-    example.
+    1) 1-D masked arrays
+    2) 1-D ndarrays
+    3) ndarrays with more than one dimension
+    4) other non-string iterables
+    5) anything else
 
-    Array arguments must have the same length; masked arguments must
-    be one-dimensional.
+    The first argument must be in one of the first four categories;
+    any argument with a length differing from that of the first
+    argument (and hence anything in category 5) then will be
+    passed through unchanged.
 
-    Written as a helper for scatter, but may be more generally
-    useful.
+    Masks are obtained from all arguments of the correct length
+    in categories 1, 2, and 4; a point is bad if masked in a masked
+    array or if it is a nan or inf.  No attempt is made to
+    extract a mask from categories 2, 3, and 4 if *np.isfinite()*
+    does not yield a Boolean array.
+
+    All input arguments that are not passed unchanged are returned
+    as ndarrays after removing the points or rows corresponding to
+    masks in any of the arguments.
+
+    A vastly simpler version of this function was originally
+    written as a helper for Axes.scatter().
+
     """
-    masks = [ma.getmaskarray(x) for x in args if hasattr(x, 'mask')]
-    isfinite = [np.isfinite(x) for x in args]
-    masks.extend( [~x for x in isfinite if not 
isinstance(x,types.NotImplementedType)] )
-    if len(masks) == 0:
-        return args
-    mask = reduce(np.logical_or, masks)
+    if not len(args):
+        return ()
+    if (is_string_like(args[0]) or not iterable(args[0])):
+        raise ValueError("First argument must be a sequence")
+    nrecs = len(args[0])
     margs = []
-    for x in args:
-        if (not is_string_like(x)
-            and iterable(x)
-            and len(x) == len(mask)):
-            if (hasattr(x, 'get_compressed_copy')):
-                compressed_x = x.get_compressed_copy(mask)
+    seqlist = [False] * len(args)
+    for i, x in enumerate(args):
+        if (not is_string_like(x)) and iterable(x) and len(x) == nrecs:
+            seqlist[i] = True
+            if ma.isMA(x):
+                if x.ndim > 1:
+                    raise ValueError("Masked arrays must be 1-D")
             else:
-                compressed_x = ma.masked_array(x, mask=mask).compressed()
-            margs.append(compressed_x)
-        else:
-            margs.append(x)
+                x = np.asarray(x)
+        margs.append(x)
+    masks = []    # list of masks that are True where good
+    for i, x in enumerate(margs):
+        if seqlist[i]:
+            if x.ndim > 1:
+                continue  # Don't try to get nan locations unless 1-D.
+            if ma.isMA(x):
+                masks.append(~ma.getmaskarray(x))  # invert the mask
+                xd = x.data
+            else:
+                xd = x
+            try:
+                mask = np.isfinite(xd)
+                if isinstance(mask, np.ndarray):
+                    masks.append(mask)
+            except: #Fixme: put in tuple of possible exceptions?
+                pass
+    if len(masks):
+        mask = reduce(np.logical_and, masks)
+        igood = mask.nonzero()[0]
+        if len(igood) < nrecs:
+            for i, x in enumerate(margs):
+                if seqlist[i]:
+                    if (hasattr(x, 'get_compressed_copy')):
+                        compressed_x = x.get_compressed_copy(~mask)
+                    else:
+                        compressed_x = x.take(igood, axis=0)
+                    margs[i] = compressed_x
+    for i, x in enumerate(margs):
+        if seqlist[i] and ma.isMA(x):
+            margs[i] = x.filled()
     return margs
 
 

Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py      2008-07-20 18:21:11 UTC 
(rev 5796)
+++ trunk/matplotlib/lib/matplotlib/collections.py      2008-07-21 00:22:19 UTC 
(rev 5797)
@@ -90,7 +90,7 @@
         self._uniform_offsets = None
         self._offsets = np.array([], np.float_)
         if offsets is not None:
-            offsets = np.asarray(offsets, np.float_)
+            offsets = np.asarray(offsets)
             if len(offsets.shape) == 1:
                 offsets = offsets[np.newaxis,:]  # Make it Nx2.
             if transOffset is not None:

Modified: trunk/matplotlib/unit/cbook_unit.py
===================================================================
--- trunk/matplotlib/unit/cbook_unit.py 2008-07-20 18:21:11 UTC (rev 5796)
+++ trunk/matplotlib/unit/cbook_unit.py 2008-07-21 00:22:19 UTC (rev 5797)
@@ -1,62 +1,52 @@
 import unittest
+from datetime import datetime
+
 import numpy as np
 import matplotlib.cbook as cbook
+import matplotlib.colors as mcolors
 
-class TestAxes(unittest.TestCase):
-    def test_delete_masked_points_arrays(self):
-        input = (   [1,2,3,np.nan,5],
-                    np.array((1,2,3,4,5)),
-                    )
-        expected = [np.array((1,2,3,5))]*2
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
+from matplotlib.cbook import delete_masked_points as dmp
 
-        input = (   np.ma.array( [1,2,3,4,5], 
mask=[False,False,False,True,False] ),
-                    np.array((1,2,3,4,5)),
-                    )
-        expected = [np.array((1,2,3,5))]*2
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
+class Test_delete_masked_points(unittest.TestCase):
+    def setUp(self):
+        self.mask1 = [False, False, True, True, False, False]
+        self.arr0 = np.arange(1.0,7.0)
+        self.arr1 = [1,2,3,np.nan,np.nan,6]
+        self.arr2 = np.array(self.arr1)
+        self.arr3 = np.ma.array(self.arr2, mask=self.mask1)
+        self.arr_s = ['a', 'b', 'c', 'd', 'e', 'f']
+        self.arr_s2 = np.array(self.arr_s)
+        self.arr_dt = [datetime(2008, 1, 1), datetime(2008, 1, 2),
+                       datetime(2008, 1, 3), datetime(2008, 1, 4),
+                       datetime(2008, 1, 5), datetime(2008, 1, 6)]
+        self.arr_dt2 = np.array(self.arr_dt)
+        self.arr_colors = ['r', 'g', 'b', 'c', 'm', 'y']
+        self.arr_rgba = mcolors.colorConverter.to_rgba_array(self.arr_colors)
 
-        input = (   [1,2,3,np.nan,5],
-                    np.ma.array( [1,2,3,4,5], 
mask=[False,False,False,True,False] ),
-                    np.array((1,2,3,4,5)),
-                    )
-        expected = [np.array((1,2,3,5))]*3
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
+    def test_bad_first_arg(self):
+        self.assertRaises(ValueError, dmp, 'a string', self.arr0)
 
-        input = ()
-        expected = ()
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
+    def test_string_seq(self):
+        actual = dmp(self.arr_s, self.arr1)
+        ind = [0, 1, 2, 5]
+        expected = (self.arr_s2.take(ind), self.arr2.take(ind))
 
+    def test_datetime(self):
+        actual = dmp(self.arr_dt, self.arr3)
+        ind = [0, 1,  5]
+        expected = (self.arr_dt2.take(ind),
+                    self.arr3.take(ind).compressed())
+        self.assert_(np.all(actual[0] == expected[0]) and
+                     np.all(actual[1] == expected[1]))
 
-        input = (   [1,2,3,np.nan,5],
-                    )
-        expected = [np.array((1,2,3,5))]*1
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
+    def test_rgba(self):
+        actual = dmp(self.arr3, self.arr_rgba)
+        ind = [0, 1, 5]
+        expected = (self.arr3.take(ind).compressed(),
+                    self.arr_rgba.take(ind, axis=0))
+        self.assert_(np.all(actual[0] == expected[0]) and
+                     np.all(actual[1] == expected[1]))
 
-        input = (   np.array((1,2,3,4,5)),
-                    )
-        expected = [np.array((1,2,3,4,5))]*1
-        actual = cbook.delete_masked_points(*input)
-        assert np.allclose(actual, expected)
 
-    def test_delete_masked_points_strings(self):
-        input = (   'hello',
-                    )
-        expected = ('hello',)
-        actual = cbook.delete_masked_points(*input)
-        assert actual == expected
-
-        input = (   u'hello',
-                    )
-        expected = (u'hello',)
-        actual = cbook.delete_masked_points(*input)
-        assert actual == expected
-
-
 if __name__=='__main__':
     unittest.main()


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to