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