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