Revision: 7340
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7340&view=rev
Author:   efiring
Date:     2009-08-04 06:52:24 +0000 (Tue, 04 Aug 2009)

Log Message:
-----------
Add PathCollection; reorganize collections.py
PathCollection is added to support complex paths in contourf.
Other changes are to improve readability and reduce redundancy.

Modified Paths:
--------------
    trunk/matplotlib/lib/matplotlib/collections.py

Modified: trunk/matplotlib/lib/matplotlib/collections.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/collections.py      2009-08-03 20:06:02 UTC 
(rev 7339)
+++ trunk/matplotlib/lib/matplotlib/collections.py      2009-08-04 06:52:24 UTC 
(rev 7340)
@@ -5,15 +5,15 @@
 
 The classes are not meant to be as flexible as their single element
 counterparts (e.g. you may not be able to select all line styles) but
-they are meant to be fast for common use cases (e.g. a bunch of solid
+they are meant to be fast for common use cases (e.g. a large set of solid
 line segemnts)
 """
-import copy, math, warnings
+import warnings
 import numpy as np
-from numpy import ma
+import numpy.ma as ma
 import matplotlib as mpl
 import matplotlib.cbook as cbook
-import matplotlib.colors as _colors # avoid conflict with kwarg
+import matplotlib.colors as mcolors
 import matplotlib.cm as cm
 import matplotlib.transforms as transforms
 import matplotlib.artist as artist
@@ -106,6 +106,7 @@
 
         self._pickradius = pickradius
         self.update(kwargs)
+        self._paths = None
 
 
     def _get_value(self, val):
@@ -131,6 +132,9 @@
 
 
     def get_paths(self):
+        return self._paths
+
+    def set_paths(self):
         raise NotImplementedError
 
     def get_transforms(self):
@@ -385,7 +389,7 @@
             pass
         if c is None: c = mpl.rcParams['patch.facecolor']
         self._facecolors_original = c
-        self._facecolors = _colors.colorConverter.to_rgba_array(c, self._alpha)
+        self._facecolors = mcolors.colorConverter.to_rgba_array(c, self._alpha)
 
     def set_facecolors(self, c):
         """alias for set_facecolor"""
@@ -427,7 +431,7 @@
         else:
             if c is None: c = mpl.rcParams['patch.edgecolor']
             self._edgecolors_original = c
-            self._edgecolors = _colors.colorConverter.to_rgba_array(c, 
self._alpha)
+            self._edgecolors = mcolors.colorConverter.to_rgba_array(c, 
self._alpha)
 
 
     def set_edgecolors(self, c):
@@ -446,13 +450,13 @@
         else:
             artist.Artist.set_alpha(self, alpha)
             try:
-                self._facecolors = _colors.colorConverter.to_rgba_array(
+                self._facecolors = mcolors.colorConverter.to_rgba_array(
                     self._facecolors_original, self._alpha)
             except (AttributeError, TypeError, IndexError):
                 pass
             try:
                 if self._edgecolors_original != 'face':
-                    self._edgecolors = _colors.colorConverter.to_rgba_array(
+                    self._edgecolors = mcolors.colorConverter.to_rgba_array(
                         self._edgecolors_original, self._alpha)
             except (AttributeError, TypeError, IndexError):
                 pass
@@ -516,133 +520,27 @@
     setting, in sequence form.
 """
 
-class QuadMesh(Collection):
+class PathCollection(Collection):
     """
-    Class for the efficient drawing of a quadrilateral mesh.
-
-    A quadrilateral mesh consists of a grid of vertices. The
-    dimensions of this array are (*meshWidth* + 1, *meshHeight* +
-    1). Each vertex in the mesh has a different set of "mesh
-    coordinates" representing its position in the topology of the
-    mesh. For any values (*m*, *n*) such that 0 <= *m* <= *meshWidth*
-    and 0 <= *n* <= *meshHeight*, the vertices at mesh coordinates
-    (*m*, *n*), (*m*, *n* + 1), (*m* + 1, *n* + 1), and (*m* + 1, *n*)
-    form one of the quadrilaterals in the mesh. There are thus
-    (*meshWidth* * *meshHeight*) quadrilaterals in the mesh.  The mesh
-    need not be regular and the polygons need not be convex.
-
-    A quadrilateral mesh is represented by a (2 x ((*meshWidth* + 1) *
-    (*meshHeight* + 1))) numpy array *coordinates*, where each row is
-    the *x* and *y* coordinates of one of the vertices.  To define the
-    function that maps from a data point to its corresponding color,
-    use the :meth:`set_cmap` method.  Each of these arrays is indexed in
-    row-major order by the mesh coordinates of the vertex (or the mesh
-    coordinates of the lower left vertex, in the case of the
-    colors).
-
-    For example, the first entry in *coordinates* is the
-    coordinates of the vertex at mesh coordinates (0, 0), then the one
-    at (0, 1), then at (0, 2) .. (0, meshWidth), (1, 0), (1, 1), and
-    so on.
+    This is the most basic :class:`Collection` subclass.
     """
-    def __init__(self, meshWidth, meshHeight, coordinates, showedges, 
antialiased=True):
-        Collection.__init__(self)
-        self._meshWidth = meshWidth
-        self._meshHeight = meshHeight
-        self._coordinates = coordinates
-        self._showedges = showedges
-        self._antialiased = antialiased
-
-        self._paths = None
-
-        self._bbox = transforms.Bbox.unit()
-        self._bbox.update_from_data_xy(coordinates.reshape(
-                ((meshWidth + 1) * (meshHeight + 1), 2)))
-
-        # By converting to floats now, we can avoid that on every draw.
-        self._coordinates = self._coordinates.reshape((meshHeight + 1, 
meshWidth + 1, 2))
-        self._coordinates = np.array(self._coordinates, np.float_)
-
-    def get_paths(self, dataTrans=None):
-        if self._paths is None:
-            self._paths = self.convert_mesh_to_paths(
-                self._meshWidth, self._meshHeight, self._coordinates)
-        return self._paths
-
-    @staticmethod
-    def convert_mesh_to_paths(meshWidth, meshHeight, coordinates):
+    def __init__(self, paths, **kwargs):
         """
-        Converts a given mesh into a sequence of
-        :class:`matplotlib.path.Path` objects for easier rendering by
-        backends that do not directly support quadmeshes.
+        *paths* is a sequence of :class:`matplotlib.path.Path`
+        instances.
 
-        This function is primarily of use to backend implementers.
+        %(Collection)s
         """
-        Path = mpath.Path
 
-        if ma.isMaskedArray(coordinates):
-            c = coordinates.data
-        else:
-            c = coordinates
+        Collection.__init__(self, **kwargs)
+        self.set_paths(paths)
+    __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
 
-        points = np.concatenate((
-                    c[0:-1, 0:-1],
-                    c[0:-1, 1:  ],
-                    c[1:  , 1:  ],
-                    c[1:  , 0:-1],
-                    c[0:-1, 0:-1]
-                    ), axis=2)
-        points = points.reshape((meshWidth * meshHeight, 5, 2))
-        return [Path(x) for x in points]
 
-    def get_datalim(self, transData):
-        return self._bbox
+    def set_paths(self, paths):
+        self._paths = paths
 
-    @allow_rasterization
-    def draw(self, renderer):
-        if not self.get_visible(): return
-        renderer.open_group(self.__class__.__name__)
-        transform = self.get_transform()
-        transOffset = self._transOffset
-        offsets = self._offsets
 
-        if self.have_units():
-            if len(self._offsets):
-                xs = self.convert_xunits(self._offsets[:0])
-                ys = self.convert_yunits(self._offsets[:1])
-                offsets = zip(xs, ys)
-
-        offsets = np.asarray(offsets, np.float_)
-
-        if self.check_update('array'):
-            self.update_scalarmappable()
-
-        clippath, clippath_trans = self.get_transformed_clip_path_and_affine()
-        if clippath_trans is not None:
-            clippath_trans = clippath_trans.frozen()
-
-        if not transform.is_affine:
-            coordinates = self._coordinates.reshape(
-                (self._coordinates.shape[0] *
-                 self._coordinates.shape[1],
-                 2))
-            coordinates = transform.transform(coordinates)
-            coordinates = coordinates.reshape(self._coordinates.shape)
-            transform = transforms.IdentityTransform()
-        else:
-            coordinates = self._coordinates
-
-        if not transOffset.is_affine:
-            offsets = transOffset.transform_non_affine(offsets)
-            transOffset = transOffset.get_affine()
-
-        renderer.draw_quad_mesh(
-            transform.frozen(), self.clipbox, clippath, clippath_trans,
-            self._meshWidth, self._meshHeight, coordinates,
-            offsets, transOffset, self.get_facecolor(), self._antialiased,
-            self._showedges)
-        renderer.close_group(self.__class__.__name__)
-
 class PolyCollection(Collection):
     def __init__(self, verts, sizes = None, closed = True, **kwargs):
         """
@@ -687,8 +585,7 @@
         else:
             self._paths = [mpath.Path(xy) for xy in verts]
 
-    def get_paths(self):
-        return self._paths
+    set_paths = set_verts
 
     def draw(self, renderer):
         if self._sizes is not None:
@@ -797,9 +694,6 @@
             for x in self._sizes]
         return Collection.draw(self, renderer)
 
-    def get_paths(self):
-        return self._paths
-
     def get_numsides(self):
         return self._numsides
 
@@ -907,7 +801,7 @@
         if antialiaseds is None: antialiaseds = 
(mpl.rcParams['lines.antialiased'],)
         self.set_linestyles(linestyles)
 
-        colors = _colors.colorConverter.to_rgba_array(colors)
+        colors = mcolors.colorConverter.to_rgba_array(colors)
 
         Collection.__init__(
             self,
@@ -925,9 +819,6 @@
 
         self.set_segments(segments)
 
-    def get_paths(self):
-        return self._paths
-
     def set_segments(self, segments):
         if segments is None: return
         _segments = []
@@ -940,6 +831,7 @@
         self._paths = [mpath.Path(seg) for seg in _segments]
 
     set_verts = set_segments # for compatibility with PolyCollection
+    set_paths = set_segments
 
     def _add_offsets(self, segs):
         offsets = self._uniform_offsets
@@ -963,7 +855,7 @@
 
         ACCEPTS: matplotlib color arg or sequence of rgba tuples
         """
-        self._edgecolors = _colors.colorConverter.to_rgba_array(c)
+        self._edgecolors = mcolors.colorConverter.to_rgba_array(c)
 
     def color(self, c):
         """
@@ -1011,8 +903,6 @@
             for x in self._sizes]
         return Collection.draw(self, renderer)
 
-    def get_paths(self):
-        return self._paths
 
 class EllipseCollection(Collection):
     """
@@ -1095,9 +985,6 @@
             self.set_transforms()
         return Collection.draw(self, renderer)
 
-    def get_paths(self):
-        return self._paths
-
 class PatchCollection(Collection):
     """
     A generic collection of patches.
@@ -1152,17 +1039,148 @@
         else:
             Collection.__init__(self, **kwargs)
 
-        paths        = [p.get_transform().transform_path(p.get_path())
+        self.set_paths(patches)
+
+    def set_paths(self, patches):
+        paths = [p.get_transform().transform_path(p.get_path())
                         for p in patches]
-
         self._paths = paths
 
+
+class QuadMesh(Collection):
+    """
+    Class for the efficient drawing of a quadrilateral mesh.
+
+    A quadrilateral mesh consists of a grid of vertices. The
+    dimensions of this array are (*meshWidth* + 1, *meshHeight* +
+    1). Each vertex in the mesh has a different set of "mesh
+    coordinates" representing its position in the topology of the
+    mesh. For any values (*m*, *n*) such that 0 <= *m* <= *meshWidth*
+    and 0 <= *n* <= *meshHeight*, the vertices at mesh coordinates
+    (*m*, *n*), (*m*, *n* + 1), (*m* + 1, *n* + 1), and (*m* + 1, *n*)
+    form one of the quadrilaterals in the mesh. There are thus
+    (*meshWidth* * *meshHeight*) quadrilaterals in the mesh.  The mesh
+    need not be regular and the polygons need not be convex.
+
+    A quadrilateral mesh is represented by a (2 x ((*meshWidth* + 1) *
+    (*meshHeight* + 1))) numpy array *coordinates*, where each row is
+    the *x* and *y* coordinates of one of the vertices.  To define the
+    function that maps from a data point to its corresponding color,
+    use the :meth:`set_cmap` method.  Each of these arrays is indexed in
+    row-major order by the mesh coordinates of the vertex (or the mesh
+    coordinates of the lower left vertex, in the case of the
+    colors).
+
+    For example, the first entry in *coordinates* is the
+    coordinates of the vertex at mesh coordinates (0, 0), then the one
+    at (0, 1), then at (0, 2) .. (0, meshWidth), (1, 0), (1, 1), and
+    so on.
+    """
+    def __init__(self, meshWidth, meshHeight, coordinates, showedges, 
antialiased=True):
+        Collection.__init__(self)
+        self._meshWidth = meshWidth
+        self._meshHeight = meshHeight
+        self._coordinates = coordinates
+        self._showedges = showedges
+        self._antialiased = antialiased
+
+        self._bbox = transforms.Bbox.unit()
+        self._bbox.update_from_data_xy(coordinates.reshape(
+                ((meshWidth + 1) * (meshHeight + 1), 2)))
+
+        # By converting to floats now, we can avoid that on every draw.
+        self._coordinates = self._coordinates.reshape((meshHeight + 1, 
meshWidth + 1, 2))
+        self._coordinates = np.array(self._coordinates, np.float_)
+
     def get_paths(self):
+        if self._paths is None:
+            self.set_paths()
         return self._paths
 
+    def set_paths(self):
+        self._paths = self.convert_mesh_to_paths(
+            self._meshWidth, self._meshHeight, self._coordinates)
 
+    @staticmethod
+    def convert_mesh_to_paths(meshWidth, meshHeight, coordinates):
+        """
+        Converts a given mesh into a sequence of
+        :class:`matplotlib.path.Path` objects for easier rendering by
+        backends that do not directly support quadmeshes.
+
+        This function is primarily of use to backend implementers.
+        """
+        Path = mpath.Path
+
+        if ma.isMaskedArray(coordinates):
+            c = coordinates.data
+        else:
+            c = coordinates
+
+        points = np.concatenate((
+                    c[0:-1, 0:-1],
+                    c[0:-1, 1:  ],
+                    c[1:  , 1:  ],
+                    c[1:  , 0:-1],
+                    c[0:-1, 0:-1]
+                    ), axis=2)
+        points = points.reshape((meshWidth * meshHeight, 5, 2))
+        return [Path(x) for x in points]
+
+    def get_datalim(self, transData):
+        return self._bbox
+
+    @allow_rasterization
+    def draw(self, renderer):
+        if not self.get_visible(): return
+        renderer.open_group(self.__class__.__name__)
+        transform = self.get_transform()
+        transOffset = self._transOffset
+        offsets = self._offsets
+
+        if self.have_units():
+            if len(self._offsets):
+                xs = self.convert_xunits(self._offsets[:0])
+                ys = self.convert_yunits(self._offsets[:1])
+                offsets = zip(xs, ys)
+
+        offsets = np.asarray(offsets, np.float_)
+
+        if self.check_update('array'):
+            self.update_scalarmappable()
+
+        clippath, clippath_trans = self.get_transformed_clip_path_and_affine()
+        if clippath_trans is not None:
+            clippath_trans = clippath_trans.frozen()
+
+        if not transform.is_affine:
+            coordinates = self._coordinates.reshape(
+                (self._coordinates.shape[0] *
+                 self._coordinates.shape[1],
+                 2))
+            coordinates = transform.transform(coordinates)
+            coordinates = coordinates.reshape(self._coordinates.shape)
+            transform = transforms.IdentityTransform()
+        else:
+            coordinates = self._coordinates
+
+        if not transOffset.is_affine:
+            offsets = transOffset.transform_non_affine(offsets)
+            transOffset = transOffset.get_affine()
+
+        renderer.draw_quad_mesh(
+            transform.frozen(), self.clipbox, clippath, clippath_trans,
+            self._meshWidth, self._meshHeight, coordinates,
+            offsets, transOffset, self.get_facecolor(), self._antialiased,
+            self._showedges)
+        renderer.close_group(self.__class__.__name__)
+
+
+
+
 artist.kwdocd['Collection'] = patchstr = artist.kwdoc(Collection)
-for k in ('QuadMesh', 'PolyCollection', 'BrokenBarHCollection', 
'RegularPolyCollection',
+for k in ('QuadMesh', 'PolyCollection', 'BrokenBarHCollection',
+           'RegularPolyCollection', 'PathCollection',
           'StarPolygonCollection', 'PatchCollection', 'CircleCollection'):
     artist.kwdocd[k] = patchstr
 artist.kwdocd['LineCollection'] = artist.kwdoc(LineCollection)


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

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to