From: <md...@us...> - 2007-11-15 21:14:03
|
Revision: 4324 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4324&view=rev Author: mdboom Date: 2007-11-15 13:13:52 -0800 (Thu, 15 Nov 2007) Log Message: ----------- Speed up auto-legend. Modified Paths: -------------- branches/transforms/lib/matplotlib/legend.py branches/transforms/lib/matplotlib/patches.py branches/transforms/lib/matplotlib/transforms.py branches/transforms/src/_path.cpp Modified: branches/transforms/lib/matplotlib/legend.py =================================================================== --- branches/transforms/lib/matplotlib/legend.py 2007-11-15 21:12:54 UTC (rev 4323) +++ branches/transforms/lib/matplotlib/legend.py 2007-11-15 21:13:52 UTC (rev 4324) @@ -340,29 +340,26 @@ bboxes = [] lines = [] - inv = ax.transAxes.inverted().transform + inverse_transform = ax.transAxes.inverted() for handle in ax.lines: assert isinstance(handle, Line2D) data = handle.get_xydata() trans = handle.get_transform() tdata = trans.transform(data) - averts = inv(tdata) + averts = inverse_transform.transform(tdata) lines.append(averts) for handle in ax.patches: assert isinstance(handle, Patch) - path = handle.get_path() - trans = handle.get_transform() - tpath = trans.transform_path(path) - tverts = tpath.vertices - averts = inv(tverts) + if isinstance(handle, Rectangle): + transform = handle.get_data_transform() + inverse_transform + bboxes.append(handle._bbox.transformed(transform)) + else: + transform = handle.get_transform() + inverse_transform + bboxes.append(handle.get_path().get_extents(transform)) - bbox = Bbox.unit() - bbox.update_from_data_xy(averts, True) - bboxes.append(bbox) - return [vertices, bboxes, lines] def draw_frame(self, b): Modified: branches/transforms/lib/matplotlib/patches.py =================================================================== --- branches/transforms/lib/matplotlib/patches.py 2007-11-15 21:12:54 UTC (rev 4323) +++ branches/transforms/lib/matplotlib/patches.py 2007-11-15 21:13:52 UTC (rev 4324) @@ -103,6 +103,9 @@ self.set_figure(other.get_figure()) self.set_alpha(other.get_alpha()) + def get_extents(self): + return self.get_path().get_extents(self.get_transform()) + def get_transform(self): return self._combined_transform Modified: branches/transforms/lib/matplotlib/transforms.py =================================================================== --- branches/transforms/lib/matplotlib/transforms.py 2007-11-15 21:12:54 UTC (rev 4323) +++ branches/transforms/lib/matplotlib/transforms.py 2007-11-15 21:13:52 UTC (rev 4324) @@ -32,6 +32,7 @@ import cbook from path import Path +from _path import count_bboxes_overlapping_bbox DEBUG = False if DEBUG: @@ -93,16 +94,16 @@ Invalidate this transform node and all of its parents. Should be called anytime the transform changes. """ - # Shortcut: If self is already invalid, that means its parents - # are as well, so we don't need to do anything. - if self._invalid or not len(self._parents): - return - # If we are an affine transform being changed, we can set the # flag to INVALID_AFFINE_ONLY value = ((self.is_affine or self.is_bbox) and self.INVALID_AFFINE or self.INVALID) + + # Shortcut: If self is already invalid, that means its parents + # are as well, so we don't need to do anything. + if self._invalid == value or not len(self._parents): + return # Invalidate all ancestors of self using pseudo-recursion. parent = None @@ -194,10 +195,12 @@ read-only access to its data. """ is_bbox = True - - def __init__(self): - TransformNode.__init__(self) + #* Redundant: Removed for performance + # + # def __init__(self): + # TransformNode.__init__(self) + if DEBUG: def _check(points): if ma.isMaskedArray(points): @@ -896,10 +899,12 @@ # True if this transform is separable in the x- and y- dimensions. is_separable = False - - def __init__(self): - TransformNode.__init__(self) + #* Redundant: Removed for performance + # + # def __init__(self): + # TransformNode.__init__(self) + def __add__(self, other): """ Composes two transforms together such that self is followed by other. @@ -1171,8 +1176,10 @@ input_dims = 2 output_dims = 2 - def __init__(self): - AffineBase.__init__(self) + #* Redundant: Removed for performance + # + # def __init__(self): + # Affine2DBase.__init__(self) def frozen(self): return Affine2D(self.get_matrix().copy()) Modified: branches/transforms/src/_path.cpp =================================================================== --- branches/transforms/src/_path.cpp 2007-11-15 21:12:54 UTC (rev 4323) +++ branches/transforms/src/_path.cpp 2007-11-15 21:13:52 UTC (rev 4324) @@ -41,6 +41,8 @@ "clip_path_to_rect(path, bbox, inside)"); add_varargs_method("affine_transform", &_path_module::affine_transform, "affine_transform(vertices, transform)"); + add_varargs_method("count_bboxes_overlapping_bbox", &_path_module::count_bboxes_overlapping_bbox, + "count_bboxes_overlapping_bbox(bbox, bboxes)"); initialize("Helper functions for paths"); } @@ -57,6 +59,7 @@ Py::Object path_in_path(const Py::Tuple& args); Py::Object clip_path_to_rect(const Py::Tuple& args); Py::Object affine_transform(const Py::Tuple& args); + Py::Object count_bboxes_overlapping_bbox(const Py::Tuple& args); }; // @@ -736,6 +739,46 @@ return Py::Object((PyObject*)result, true); } +Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args) { + args.verify_length(2); + + Py::Object bbox = args[0]; + Py::SeqBase<Py::Object> bboxes = args[1]; + + double ax0, ay0, ax1, ay1; + double bx0, by0, bx1, by1; + long count = 0; + + if (py_convert_bbox(bbox.ptr(), ax0, ay0, ax1, ay1)) { + if (ax1 < ax0) + std::swap(ax0, ax1); + if (ay1 < ay0) + std::swap(ay0, ay1); + + size_t num_bboxes = bboxes.size(); + for (size_t i = 0; i < num_bboxes; ++i) { + Py::Object bbox_b = bboxes[i]; + if (py_convert_bbox(bbox_b.ptr(), bx0, by0, bx1, by1)) { + if (bx1 < bx0) + std::swap(bx0, bx1); + if (by1 < by0) + std::swap(by0, by1); + if (not ((bx1 <= ax0) or + (by1 <= ay0) or + (bx0 >= ax1) or + (by0 >= ay1))) + ++count; + } else { + throw Py::ValueError("Non-bbox object in bboxes list"); + } + } + } else { + throw Py::ValueError("First argument to count_bboxes_overlapping_bbox must be a Bbox object."); + } + + return Py::Int(count); +} + extern "C" DL_EXPORT(void) init_path(void) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |