Permalink
Browse files

Fixed __array__ releated bug that I introduced.

  • Loading branch information...
1 parent 1b1b340 commit e9cc98e3ef1b23c359feacca7994de57677c7c0a Phil Elson committed with pelson May 1, 2012
Showing with 52 additions and 33 deletions.
  1. +0 −12 lib/matplotlib/collections.py
  2. +23 −17 lib/matplotlib/transforms.py
  3. +29 −4 src/agg_py_transforms.cpp
@@ -242,18 +242,6 @@ def draw(self, renderer):
self._set_gc_clip(gc)
gc.set_snap(self.get_snap())
- if self._hatch:
- gc.set_hatch(self._hatch)
-
- # XXX INVESTIGATE.
- print('transOffset: ', transOffset)
- print(transOffset.is_affine, transOffset.get_matrix())
- mtx = transOffset.get_matrix()
- import matplotlib.transforms as mtransforms
- transOffset = mtransforms.Affine2D()
- transOffset.set_matrix(mtx)
- # XXX end investigate
-
renderer.draw_path_collection(
gc, transform.frozen(), paths, self.get_transforms(),
offsets, transOffset, self.get_facecolor(), self.get_edgecolor(),
@@ -46,7 +46,7 @@
import cbook
from path import Path
-DEBUG = True
+DEBUG = False
if DEBUG:
import warnings
@@ -113,11 +113,14 @@ def _invalidate_internal(self, value, invalidating_node):
Called by :meth:`invalidate` and subsequently ascends the transform
stack calling each TransformNode's _invalidate_internal method.
"""
- # determine if this call will be an extension to the invalidation status
- # if not, then a shortcut means that we needn't invoke an invalidation
- # up the transform stack
- # XXX This makes the invalidation sticky, once a transform has been invalidated as NON_AFFINE
- # too, then it is always NON_AFFINE invalid, even when triggered with a AFFINE_ONLY invalidation.
+ # determine if this call will be an extension to the invalidation
+ # status if not, then a shortcut means that we needn't invoke an
+ # invalidation up the transform stack
+ # N.B This makes the invalidation sticky, once a transform has been
+ # invalidated as NON_AFFINE too, then it is always NON_AFFINE invalid,
+ # even when triggered with a AFFINE_ONLY invalidation. This will not
+ # be experienced, as in most cases the invalidation will by AFFINE_ONLY
+ # anyway.
status_changed = self._invalid < value
if self.pass_through or status_changed:
@@ -1067,9 +1070,13 @@ def __radd__(self, other):
def __array__(self, *args, **kwargs):
"""
- Used by C/C++ -based backends to get at the array matrix data.
+ Array interface to get at this Transform's matrix.
"""
- raise NotImplementedError
+ # note, this method is also used by C/C++ -based backends
+ if self.is_affine:
+ return self.get_matrix()
+ else:
+ raise ValueError('Cannot convert this transform to an array.')
def transform(self, values):
"""
@@ -1340,6 +1347,7 @@ def __init__(self):
self._inverted = None
def __array__(self, *args, **kwargs):
+ # optimises the access of the transform matrix vs the superclass
return self.get_matrix()
@staticmethod
@@ -1402,9 +1410,6 @@ def _get_is_separable(self):
return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
is_separable = property(_get_is_separable)
- def __array__(self, *args, **kwargs):
- return self.get_matrix()
-
def to_values(self):
"""
Return the values of the matrix as a sequence (a,b,c,d,e,f)
@@ -1924,11 +1929,12 @@ def _invalidate_internal(self, value, invalidating_node):
# (b) it is the left hand node which has triggered the invalidation
if value == Transform.INVALID_AFFINE \
and not self._b.is_affine \
- and (not self._a.is_affine or invalidating_node is self._a): # note use of is will break when using TransformWrapper
+ and (not self._a.is_affine or invalidating_node is self._a):
value = Transform.INVALID
- Transform._invalidate_internal(self, value=value, invalidating_node=invalidating_node)
+ Transform._invalidate_internal(self, value=value,
+ invalidating_node=invalidating_node)
def _get_is_affine(self):
return self._a.is_affine and self._b.is_affine
@@ -2048,10 +2054,10 @@ def composite_transform_factory(a, b):
c = a + b
"""
- # check to see if any of a or b are IdentityTransforms. Note we
- # do not use equality here since we may have wrapped transforms
- # which are currently equal to Identity, but since wrapped transforms
- # are mutable, they may not always be equal.
+ # check to see if any of a or b are IdentityTransforms. We use
+ # isinstance here to guarantee that the transforms will *always*
+ # be IdentityTransforms. Since TransformWrappers are mutable,
+ # use of equality here would be wrong.
if isinstance(a, IdentityTransform):
return b
elif isinstance(b, IdentityTransform):
@@ -9,20 +9,45 @@
#include "agg_trans_affine.h"
/** A helper function to convert from a Numpy affine transformation matrix
- * to an agg::trans_affine.
+ * to an agg::trans_affine. If errors = false then an Identity transform is returned.
*/
agg::trans_affine
py_to_agg_transformation_matrix(PyObject* obj, bool errors = true)
{
PyArrayObject* matrix = NULL;
+ /** If None either raise a TypeError or return an agg identity transform. */
+ if (obj == Py_None)
+ {
+ if (errors)
+ {
+ throw Py::TypeError("Cannot convert None to an affine transform.");
+ }
+
+ return agg::trans_affine();
+ }
+
+ /** Try turning the object into an affine transform matrix. */
try
{
- if (obj == Py_None)
- throw std::exception();
matrix = (PyArrayObject*) PyArray_FromObject(obj, PyArray_DOUBLE, 2, 2);
if (!matrix)
throw std::exception();
+ }
+ catch (...)
+ {
+ Py_XDECREF(matrix);
+ if (errors)
+ {
+ throw Py::TypeError("Unable to get an affine transform matrix from the given object.");
+ }
+
+ return agg::trans_affine();
+ }
+
+ /** Try turning the matrix into an agg transform. */
+ try
+ {
if (PyArray_NDIM(matrix) == 2 || PyArray_DIM(matrix, 0) == 3 || PyArray_DIM(matrix, 1) == 3)
{
size_t stride0 = PyArray_STRIDE(matrix, 0);
@@ -54,7 +79,7 @@ py_to_agg_transformation_matrix(PyObject* obj, bool errors = true)
if (errors)
{
Py_XDECREF(matrix);
- throw Py::TypeError("Invalid affine transformation matrix");
+ throw Py::TypeError("Invalid affine transformation matrix.");
}
}

0 comments on commit e9cc98e

Please sign in to comment.