49
49
50
50
MaskedArray = ma .MaskedArray
51
51
52
+
52
53
class TransformNode (object ):
53
54
"""
54
55
:class:`TransformNode` is the base class for anything that
@@ -63,13 +64,13 @@ class TransformNode(object):
63
64
# invalidation was "affine-only", the _invalid member is set to
64
65
# INVALID_AFFINE_ONLY
65
66
INVALID_NON_AFFINE = 1
66
- INVALID_AFFINE = 2
67
- INVALID = INVALID_NON_AFFINE | INVALID_AFFINE
67
+ INVALID_AFFINE = 2
68
+ INVALID = INVALID_NON_AFFINE | INVALID_AFFINE
68
69
69
70
# Some metadata about the transform, used to determine whether an
70
71
# invalidation is affine-only
71
72
is_affine = False
72
- is_bbox = False
73
+ is_bbox = False
73
74
74
75
pass_through = False
75
76
"""
@@ -150,7 +151,8 @@ def _invalidate_internal(self, value, invalidating_node):
150
151
self ._invalid = value
151
152
152
153
for parent in self ._parents .itervalues ():
153
- parent ._invalidate_internal (value = value , invalidating_node = self )
154
+ parent ._invalidate_internal (value = value ,
155
+ invalidating_node = self )
154
156
155
157
def set_children (self , * children ):
156
158
"""
@@ -164,6 +166,7 @@ def set_children(self, *children):
164
166
165
167
if DEBUG :
166
168
_set_children = set_children
169
+
167
170
def set_children (self , * children ):
168
171
self ._set_children (* children )
169
172
self ._children = children
@@ -212,7 +215,9 @@ def recurse(root):
212
215
props ['style' ] = 'bold'
213
216
props ['shape' ] = 'box'
214
217
props ['label' ] = '"%s"' % label
215
- props = ' ' .join (['%s=%s' % (key , val ) for key , val in props .iteritems ()])
218
+ props = ' ' .join (['%s=%s' % (key , val )
219
+ for key , val
220
+ in props .iteritems ()])
216
221
217
222
fobj .write ('%s [%s];\n ' %
218
223
(hash (root ), props ))
@@ -224,10 +229,10 @@ def recurse(root):
224
229
if val is child :
225
230
name = key
226
231
break
227
- fobj .write ('"%s" -> "%s" [label="%s", fontsize=10];\n ' % (
228
- hash (root ),
229
- hash (child ),
230
- name ))
232
+ fobj .write ('"%s" -> "%s" [label="%s", fontsize=10];\n '
233
+ % ( hash (root ),
234
+ hash (child ),
235
+ name ))
231
236
recurse (child )
232
237
233
238
fobj .write ("digraph G {\n " )
@@ -259,8 +264,8 @@ def _check(points):
259
264
if ma .isMaskedArray (points ):
260
265
warnings .warn ("Bbox bounds are a masked array." )
261
266
points = np .asarray (points )
262
- if (points [1 ,0 ] - points [0 ,0 ] == 0 or
263
- points [1 ,1 ] - points [0 ,1 ] == 0 ):
267
+ if (points [1 , 0 ] - points [0 , 0 ] == 0 or
268
+ points [1 , 1 ] - points [0 , 1 ] == 0 ):
264
269
warnings .warn ("Singular Bbox." )
265
270
_check = staticmethod (_check )
266
271
@@ -295,30 +300,30 @@ def _get_y0(self):
295
300
def _get_x1 (self ):
296
301
return self .get_points ()[1 , 0 ]
297
302
x1 = property (_get_x1 , None , None , """
298
- (property) :attr:`x1` is the second of the pair of *x* coordinates that
299
- define the bounding box. :attr:`x1` is not guaranteed to be
303
+ (property) :attr:`x1` is the second of the pair of *x* coordinates
304
+ that define the bounding box. :attr:`x1` is not guaranteed to be
300
305
greater than :attr:`x0`. If you require that, use :attr:`xmax`.""" )
301
306
302
307
def _get_y1 (self ):
303
308
return self .get_points ()[1 , 1 ]
304
309
y1 = property (_get_y1 , None , None , """
305
- (property) :attr:`y1` is the second of the pair of *y* coordinates that
306
- define the bounding box. :attr:`y1` is not guaranteed to be
310
+ (property) :attr:`y1` is the second of the pair of *y* coordinates
311
+ that define the bounding box. :attr:`y1` is not guaranteed to be
307
312
greater than :attr:`y0`. If you require that, use :attr:`ymax`.""" )
308
313
309
314
def _get_p0 (self ):
310
315
return self .get_points ()[0 ]
311
316
p0 = property (_get_p0 , None , None , """
312
- (property) :attr:`p0` is the first pair of (*x*, *y*) coordinates that
313
- define the bounding box. It is not guaranteed to be the bottom-left
314
- corner. For that, use :attr:`min`.""" )
317
+ (property) :attr:`p0` is the first pair of (*x*, *y*) coordinates
318
+ that define the bounding box. It is not guaranteed to be the
319
+ bottom-left corner. For that, use :attr:`min`.""" )
315
320
316
321
def _get_p1 (self ):
317
322
return self .get_points ()[1 ]
318
323
p1 = property (_get_p1 , None , None , """
319
- (property) :attr:`p1` is the second pair of (*x*, *y*) coordinates that
320
- define the bounding box. It is not guaranteed to be the top-right
321
- corner. For that, use :attr:`max`.""" )
324
+ (property) :attr:`p1` is the second pair of (*x*, *y*) coordinates
325
+ that define the bounding box. It is not guaranteed to be the
326
+ top-right corner. For that, use :attr:`max`.""" )
322
327
323
328
def _get_xmin (self ):
324
329
return min (self .get_points ()[:, 0 ])
@@ -398,7 +403,8 @@ def _get_bounds(self):
398
403
def _get_extents (self ):
399
404
return self .get_points ().flatten ().copy ()
400
405
extents = property (_get_extents , None , None , """
401
- (property) Returns (:attr:`x0`, :attr:`y0`, :attr:`x1`, :attr:`y1`).""" )
406
+ (property) Returns (:attr:`x0`, :attr:`y0`, :attr:`x1`,
407
+ :attr:`y1`).""" )
402
408
403
409
def get_points (self ):
404
410
return NotImplementedError ()
@@ -468,6 +474,7 @@ def fully_containsy(self, y):
468
474
:attr:`y1`.
469
475
"""
470
476
y0 , y1 = self .intervaly
477
+ # FIXME x is not define. This method probably doesn't work.
471
478
return ((y0 < y1
472
479
and (x > y0 and x < y1 ))
473
480
or (x > y1 and x < y0 ))
@@ -517,15 +524,16 @@ def inverse_transformed(self, transform):
517
524
return Bbox (transform .inverted ().transform (self .get_points ()))
518
525
519
526
coefs = {'C' : (0.5 , 0.5 ),
520
- 'SW' : (0 ,0 ),
527
+ 'SW' : (0 , 0 ),
521
528
'S' : (0.5 , 0 ),
522
529
'SE' : (1.0 , 0 ),
523
530
'E' : (1.0 , 0.5 ),
524
531
'NE' : (1.0 , 1.0 ),
525
532
'N' : (0.5 , 1.0 ),
526
533
'NW' : (0 , 1.0 ),
527
534
'W' : (0 , 0.5 )}
528
- def anchored (self , c , container = None ):
535
+
536
+ def anchored (self , c , container = None ):
529
537
"""
530
538
Return a copy of the :class:`Bbox`, shifted to position *c*
531
539
within a container.
@@ -555,8 +563,8 @@ def anchored(self, c, container = None):
555
563
cx , cy = c
556
564
L , B , W , H = self .bounds
557
565
return Bbox (self ._points +
558
- [(l + cx * (w - W )) - L ,
559
- (b + cy * (h - H )) - B ])
566
+ [(l + cx * (w - W )) - L ,
567
+ (b + cy * (h - H )) - B ])
560
568
561
569
def shrunk (self , mx , my ):
562
570
"""
@@ -569,7 +577,7 @@ def shrunk(self, mx, my):
569
577
return Bbox ([self ._points [0 ],
570
578
self ._points [0 ] + [mx * w , my * h ]])
571
579
572
- def shrunk_to_aspect (self , box_aspect , container = None , fig_aspect = 1.0 ):
580
+ def shrunk_to_aspect (self , box_aspect , container = None , fig_aspect = 1.0 ):
573
581
"""
574
582
Return a copy of the :class:`Bbox`, shrunk so that it is as
575
583
large as it can be while having the desired aspect ratio,
@@ -583,11 +591,11 @@ def shrunk_to_aspect(self, box_aspect, container = None, fig_aspect = 1.0):
583
591
if container is None :
584
592
container = self
585
593
w , h = container .size
586
- H = w * box_aspect / fig_aspect
594
+ H = w * box_aspect / fig_aspect
587
595
if H <= h :
588
596
W = w
589
597
else :
590
- W = h * fig_aspect / box_aspect
598
+ W = h * fig_aspect / box_aspect
591
599
H = h
592
600
return Bbox ([self ._points [0 ],
593
601
self ._points [0 ] + (W , H )])
@@ -749,6 +757,7 @@ def __init__(self, points, **kwargs):
749
757
self ._points_orig = self ._points .copy ()
750
758
if DEBUG :
751
759
___init__ = __init__
760
+
752
761
def __init__ (self , points , ** kwargs ):
753
762
self ._check (points )
754
763
self .___init__ (points , ** kwargs )
@@ -758,6 +767,7 @@ def invalidate(self):
758
767
TransformNode .invalidate (self )
759
768
760
769
_unit_values = np .array ([[0.0 , 0.0 ], [1.0 , 1.0 ]], np .float_ )
770
+
761
771
@staticmethod
762
772
def unit ():
763
773
"""
@@ -822,7 +832,9 @@ def update_from_data(self, x, y, ignore=None):
822
832
- when None, use the last value passed to :meth:`ignore`.
823
833
"""
824
834
warnings .warn (
825
- "update_from_data requires a memory copy -- please replace with update_from_data_xy" )
835
+ "update_from_data requires a memory copy -- please replace with "
836
+ "update_from_data_xy" )
837
+
826
838
xy = np .hstack ((x .reshape ((len (x ), 1 )), y .reshape ((len (y ), 1 ))))
827
839
return self .update_from_data_xy (xy , ignore )
828
840
@@ -856,13 +868,12 @@ def update_from_path(self, path, ignore=None, updatex=True, updatey=True):
856
868
if changed :
857
869
self .invalidate ()
858
870
if updatex :
859
- self ._points [:,0 ] = points [:,0 ]
871
+ self ._points [:, 0 ] = points [:, 0 ]
860
872
self ._minpos [0 ] = minpos [0 ]
861
873
if updatey :
862
- self ._points [:,1 ] = points [:,1 ]
874
+ self ._points [:, 1 ] = points [:, 1 ]
863
875
self ._minpos [1 ] = minpos [1 ]
864
876
865
-
866
877
def update_from_data_xy (self , xy , ignore = None , updatex = True , updatey = True ):
867
878
"""
868
879
Update the bounds of the :class:`Bbox` based on the passed in
@@ -929,7 +940,7 @@ def _set_intervaly(self, interval):
929
940
930
941
def _set_bounds (self , bounds ):
931
942
l , b , w , h = bounds
932
- points = np .array ([[l , b ], [l + w , b + h ]], np .float_ )
943
+ points = np .array ([[l , b ], [l + w , b + h ]], np .float_ )
933
944
if np .any (self ._points != points ):
934
945
self ._points = points
935
946
self .invalidate ()
@@ -980,12 +991,13 @@ def mutated(self):
980
991
981
992
def mutatedx (self ):
982
993
'return whether the x-limits have changed since init'
983
- return (self ._points [0 ,0 ]!= self ._points_orig [0 ,0 ] or
984
- self ._points [1 ,0 ]!= self ._points_orig [1 ,0 ])
994
+ return (self ._points [0 , 0 ] != self ._points_orig [0 , 0 ] or
995
+ self ._points [1 , 0 ] != self ._points_orig [1 , 0 ])
996
+
985
997
def mutatedy (self ):
986
998
'return whether the y-limits have changed since init'
987
- return (self ._points [0 ,1 ] != self ._points_orig [0 ,1 ] or
988
- self ._points [1 ,1 ] != self ._points_orig [1 ,1 ])
999
+ return (self ._points [0 , 1 ] != self ._points_orig [0 , 1 ] or
1000
+ self ._points [1 , 1 ] != self ._points_orig [1 , 1 ])
989
1001
990
1002
991
1003
class TransformedBbox (BboxBase ):
@@ -1025,6 +1037,7 @@ def get_points(self):
1025
1037
1026
1038
if DEBUG :
1027
1039
_get_points = get_points
1040
+
1028
1041
def get_points (self ):
1029
1042
points = self ._get_points ()
1030
1043
self ._check (points )
@@ -1161,24 +1174,27 @@ def contains_branch_seperately(self, other_transform):
1161
1174
if self .output_dims != 2 :
1162
1175
raise ValueError ('contains_branch_seperately only supports '
1163
1176
'transforms with 2 output dimensions' )
1164
- # for a non-blended transform each seperate dimension is the same, so just
1165
- # return the appropriate shape.
1177
+ # for a non-blended transform each seperate dimension is the same, so
1178
+ # just return the appropriate shape.
1166
1179
return [self .contains_branch (other_transform )] * 2
1167
1180
1168
1181
def __sub__ (self , other ):
1169
1182
"""
1170
1183
Returns a transform stack which goes all the way down self's transform
1171
- stack, and then ascends back up other's stack. If it can, this is optimised::
1184
+ stack, and then ascends back up other's stack. If it can, this is
1185
+ optimised::
1172
1186
1173
1187
# normally
1174
1188
A - B == a + b.inverted()
1175
1189
1176
- # sometimes, when A contains the tree B there is no need to descend all the way down
1177
- # to the base of A (via B), instead we can just stop at B.
1190
+ # sometimes, when A contains the tree B there is no need to
1191
+ # descend all the way down to the base of A (via B), instead we
1192
+ # can just stop at B.
1178
1193
1179
1194
(A + B) - (B)^-1 == A
1180
1195
1181
- # similarly, when B contains tree A, we can avoid decending A at all, basically:
1196
+ # similarly, when B contains tree A, we can avoid decending A at
1197
+ # all, basically:
1182
1198
A - (A + B) == ((B + A) - A).inverted() or B^-1
1183
1199
1184
1200
For clarity, the result of ``(A + B) - B + B == (A + B)``.
@@ -1358,15 +1374,15 @@ def transform_angles(self, angles, pts, radians=False, pushoff=1e-5):
1358
1374
angles = angles / 180.0 * np .pi
1359
1375
1360
1376
# Move a short distance away
1361
- pts2 = pts + pushoff * np .c_ [ np .cos (angles ), np .sin (angles ) ]
1377
+ pts2 = pts + pushoff * np .c_ [np .cos (angles ), np .sin (angles )]
1362
1378
1363
1379
# Transform both sets of points
1364
- tpts = self .transform ( pts )
1365
- tpts2 = self .transform ( pts2 )
1380
+ tpts = self .transform (pts )
1381
+ tpts2 = self .transform (pts2 )
1366
1382
1367
1383
# Calculate transformed angles
1368
1384
d = tpts2 - tpts
1369
- a = np .arctan2 ( d [:,1 ], d [:,0 ] )
1385
+ a = np .arctan2 (d [:, 1 ], d [:, 0 ] )
1370
1386
1371
1387
# Convert back to degrees if desired
1372
1388
if not radians :
@@ -1419,6 +1435,7 @@ def __eq__(self, other):
1419
1435
return self ._child .__eq__ (other )
1420
1436
1421
1437
if DEBUG :
1438
+
1422
1439
def __str__ (self ):
1423
1440
return str (self ._child )
1424
1441
@@ -1441,15 +1458,15 @@ def _set(self, child):
1441
1458
self ._child = child
1442
1459
self .set_children (child )
1443
1460
1444
- self .transform = child .transform
1445
- self .transform_affine = child .transform_affine
1446
- self .transform_non_affine = child .transform_non_affine
1447
- self .transform_path = child .transform_path
1448
- self .transform_path_affine = child .transform_path_affine
1461
+ self .transform = child .transform
1462
+ self .transform_affine = child .transform_affine
1463
+ self .transform_non_affine = child .transform_non_affine
1464
+ self .transform_path = child .transform_path
1465
+ self .transform_path_affine = child .transform_path_affine
1449
1466
self .transform_path_non_affine = child .transform_path_non_affine
1450
- self .get_affine = child .get_affine
1451
- self .inverted = child .inverted
1452
- self .get_matrix = child .get_matrix
1467
+ self .get_affine = child .get_affine
1468
+ self .inverted = child .inverted
1469
+ self .get_matrix = child .get_matrix
1453
1470
1454
1471
# note we do not wrap other properties here since the transform's
1455
1472
# child can be changed with WrappedTransform.set and so checking
@@ -1517,7 +1534,8 @@ def transform(self, values):
1517
1534
transform .__doc__ = Transform .transform .__doc__
1518
1535
1519
1536
def transform_affine (self , values ):
1520
- raise NotImplementedError ('Affine subclasses should override this method.' )
1537
+ raise NotImplementedError ('Affine subclasses should override this '
1538
+ 'method.' )
1521
1539
transform_affine .__doc__ = Transform .transform_affine .__doc__
1522
1540
1523
1541
def transform_non_affine (self , points ):
@@ -1605,6 +1623,7 @@ def transform_point(self, point):
1605
1623
1606
1624
if DEBUG :
1607
1625
_transform_affine = transform_affine
1626
+
1608
1627
def transform_affine (self , points ):
1609
1628
# The major speed trap here is just converting to the
1610
1629
# points to an array in the first place. If we can use
@@ -1678,7 +1697,7 @@ def from_values(a, b, c, d, e, f):
1678
1697
"""
1679
1698
return Affine2D (
1680
1699
np .array ([a , c , e , b , d , f , 0.0 , 0.0 , 1.0 ], np .float_ )
1681
- .reshape ((3 ,3 )))
1700
+ .reshape ((3 , 3 )))
1682
1701
1683
1702
def get_matrix (self ):
1684
1703
"""
@@ -1759,7 +1778,7 @@ def rotate_deg(self, degrees):
1759
1778
calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
1760
1779
and :meth:`scale`.
1761
1780
"""
1762
- return self .rotate (degrees * np .pi / 180. )
1781
+ return self .rotate (degrees * np .pi / 180. )
1763
1782
1764
1783
def rotate_around (self , x , y , theta ):
1765
1784
"""
0 commit comments