Revision: 6018
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6018&view=rev
Author:   mdboom
Date:     2008-08-11 12:48:50 +0000 (Mon, 11 Aug 2008)

Log Message:
-----------
Does simplify paths when NaN/inf is present.

Modified Paths:
--------------
    trunk/matplotlib/CHANGELOG
    trunk/matplotlib/lib/matplotlib/path.py
    trunk/matplotlib/src/_backend_agg.cpp
    trunk/matplotlib/src/_path.cpp
    trunk/matplotlib/src/agg_py_path_iterator.h

Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG  2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/CHANGELOG  2008-08-11 12:48:50 UTC (rev 6018)
@@ -1,3 +1,9 @@
+2008-08-11 Fix more bugs in NaN/inf handling.  In particular, path 
simplification
+           (which does not handle NaNs or infs) will be turned off 
automatically
+           when infs or NaNs are present.  Also masked arrays are now converted
+           to arrays with NaNs for consistent handling of masks and NaNs
+            - MGD and EF
+
 =================================================================
 2008-08-03 Released 0.98.3 at svn r5947
 

Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py     2008-08-11 07:09:16 UTC (rev 
6017)
+++ trunk/matplotlib/lib/matplotlib/path.py     2008-08-11 12:48:50 UTC (rev 
6018)
@@ -56,6 +56,11 @@
     :class:`Path` objects, as an optimization, do not store a *codes*
     at all, but have a default one provided for them by
     :meth:`iter_segments`.
+
+    Note also that the vertices and codes arrays should be treated as
+    immutable -- there are a number of optimizations and assumptions
+    made up front in the constructor that will not change when the
+    data changes.
     """
 
     # Path codes
@@ -84,46 +89,29 @@
         dimension.
 
         If *codes* is None, *vertices* will be treated as a series of
-        line segments.  If *vertices* contains masked values, the
-        resulting path will be compressed, with ``MOVETO`` codes
-        inserted in the correct places to jump over the masked
-        regions.
+        line segments.
+
+        If *vertices* contains masked values, they will be converted
+        to NaNs which are then handled correctly by the Agg
+        PathIterator and other consumers of path data, such as
+        :meth:`iter_segments`.
         """
         if ma.isMaskedArray(vertices):
-            is_mask = True
-            mask = ma.getmask(vertices)
+            vertices = vertices.astype(np.float_).filled(np.nan)
         else:
-            is_mask = False
             vertices = np.asarray(vertices, np.float_)
-            mask = ma.nomask
 
         if codes is not None:
             codes = np.asarray(codes, self.code_type)
             assert codes.ndim == 1
             assert len(codes) == len(vertices)
 
-        # The path being passed in may have masked values.  However,
-        # the backends (and any affine transformations in matplotlib
-        # itself), are not expected to deal with masked arrays, so we
-        # must remove them from the array (using compressed), and add
-        # MOVETO commands to the codes array accordingly.
-        if is_mask:
-            if mask is not ma.nomask:
-                mask1d = np.logical_or.reduce(mask, axis=1)
-                gmask1d = np.invert(mask1d)
-                if codes is None:
-                    codes = np.empty((len(vertices)), self.code_type)
-                    codes.fill(self.LINETO)
-                    codes[0] = self.MOVETO
-                vertices = vertices[gmask1d].filled() # ndarray
-                codes[np.roll(mask1d, 1)] = self.MOVETO
-                codes = codes[gmask1d] # np.compress is much slower
-            else:
-                vertices = np.asarray(vertices, np.float_)
-
         assert vertices.ndim == 2
         assert vertices.shape[1] == 2
 
+        self.should_simplify = (codes is None and
+                                np.all(np.isfinite(vertices)) and
+                                len(vertices) >= 128)
         self.codes = codes
         self.vertices = vertices
 

Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp       2008-08-11 07:09:16 UTC (rev 
6017)
+++ trunk/matplotlib/src/_backend_agg.cpp       2008-08-11 12:48:50 UTC (rev 
6018)
@@ -387,7 +387,7 @@
   double x0, y0, x1, y1;
   unsigned code;
 
-  if (path.total_vertices() > 15)
+  if (!path.should_simplify() || path.total_vertices() > 15)
     return false;
 
   code = path.vertex(&x0, &y0);
@@ -420,11 +420,6 @@
   return true;
 }
 
-template<class Path>
-bool should_simplify(Path& path) {
-  return !path.has_curves() && path.total_vertices() >= 128;
-}
-
 Py::Object
 RendererAgg::copy_from_bbox(const Py::Tuple& args) {
   //copy region in bbox to buffer and return swig/agg buffer object
@@ -938,7 +933,7 @@
   trans *= agg::trans_affine_scaling(1.0, -1.0);
   trans *= agg::trans_affine_translation(0.0, (double)height);
   bool snap = should_snap(path, trans);
-  bool simplify = should_simplify(path) && !face.first;
+  bool simplify = path.should_simplify() && !face.first;
 
   transformed_path_t tpath(path, trans);
   simplify_t simplified(tpath, snap, simplify, width, height);
@@ -1236,6 +1231,10 @@
     inline unsigned total_vertices() {
       return 5;
     }
+
+    inline bool should_simplify() {
+      return false;
+    }
   };
 
 public:

Modified: trunk/matplotlib/src/_path.cpp
===================================================================
--- trunk/matplotlib/src/_path.cpp      2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/src/_path.cpp      2008-08-11 12:48:50 UTC (rev 6018)
@@ -1120,7 +1120,7 @@
     double width = Py::Float(args[2]);
     double height = Py::Float(args[3]);
 
-    bool simplify = !path.has_curves() && width != 0.0 && height != 0.0;
+    bool simplify = path.should_simplify() && width != 0.0 && height != 0.0;
 
     transformed_path_t tpath(path, trans);
     simplify_t simplified(tpath, false, simplify, width, height);

Modified: trunk/matplotlib/src/agg_py_path_iterator.h
===================================================================
--- trunk/matplotlib/src/agg_py_path_iterator.h 2008-08-11 07:09:16 UTC (rev 
6017)
+++ trunk/matplotlib/src/agg_py_path_iterator.h 2008-08-11 12:48:50 UTC (rev 
6018)
@@ -15,6 +15,7 @@
     PyArrayObject* m_codes;
     size_t m_iterator;
     size_t m_total_vertices;
+    bool m_should_simplify;
 
 public:
     PathIterator(const Py::Object& path_obj) :
@@ -22,6 +23,7 @@
     {
         Py::Object vertices_obj = path_obj.getAttr("vertices");
         Py::Object codes_obj = path_obj.getAttr("codes");
+        Py::Object should_simplify_obj = path_obj.getAttr("should_simplify");
 
         m_vertices = (PyArrayObject*)PyArray_FromObject
                      (vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
@@ -38,6 +40,7 @@
                 throw Py::ValueError("Invalid codes array.");
         }
 
+        m_should_simplify = bool(Py::Int(should_simplify_obj));
         m_total_vertices = m_vertices->dimensions[0];
     }
 
@@ -100,9 +103,9 @@
         return m_total_vertices;
     }
 
-    inline bool has_curves()
+    inline bool should_simplify()
     {
-        return m_codes;
+        return m_should_simplify;
     }
 };
 


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
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to