@@ -177,7 +177,7 @@ def get_patch_transform(self):
177
177
"""
178
178
Return the :class:`~matplotlib.transforms.Transform` instance which
179
179
takes patch coordinates to data coordinates.
180
-
180
+
181
181
For example, one may define a patch of a circle which represents a
182
182
radius of 5 by providing coordinates for a unit circle, and a
183
183
transform which scales the coordinates (the patch coordinate) by 5.
@@ -2783,6 +2783,17 @@ def connect(self, posA, posB):
2783
2783
{"AvailableConnectorstyles" : _pprint_styles (_style_list )}
2784
2784
2785
2785
2786
+ def _point_along_a_line (x0 , y0 , x1 , y1 , d ):
2787
+ """
2788
+ find a point along a line connecting (x0, y0) -- (x1, y1) whose
2789
+ distance from (x0, y0) is d.
2790
+ """
2791
+ dx , dy = x0 - x1 , y0 - y1
2792
+ ff = d / (dx * dx + dy * dy )** .5
2793
+ x2 , y2 = x0 - ff * dx , y0 - ff * dy
2794
+
2795
+ return x2 , y2
2796
+
2786
2797
2787
2798
class ArrowStyle (_Style ):
2788
2799
"""
@@ -3419,37 +3430,57 @@ def transmute(self, path, mutation_size, linewidth):
3419
3430
head_length = self .head_length * mutation_size
3420
3431
in_f = inside_circle (x2 , y2 , head_length )
3421
3432
arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3422
- arrow_out , arrow_in = \
3423
- split_bezier_intersecting_with_closedpath (arrow_path ,
3424
- in_f ,
3425
- tolerence = 0.01 )
3433
+
3434
+ from bezier import NonIntersectingPathException
3435
+
3436
+ try :
3437
+ arrow_out , arrow_in = \
3438
+ split_bezier_intersecting_with_closedpath (arrow_path ,
3439
+ in_f ,
3440
+ tolerence = 0.01 )
3441
+ except NonIntersectingPathException :
3442
+ # if this happens, make a straight line of the head_length long.
3443
+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3444
+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3445
+ arrow_in = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
3446
+ arrow_out = None
3426
3447
3427
3448
# head
3428
3449
head_width = self .head_width * mutation_size
3429
- head_l , head_r = make_wedged_bezier2 ( arrow_in , head_width / 2. ,
3430
- wm = .5 )
3431
-
3450
+ head_left , head_right = \
3451
+ make_wedged_bezier2 ( arrow_in , head_width / 2. ,
3452
+ wm = .5 )
3432
3453
3433
3454
3434
3455
# tail
3435
- tail_width = self .tail_width * mutation_size
3436
- tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3456
+ if arrow_out is not None :
3457
+ tail_width = self .tail_width * mutation_size
3458
+ tail_left , tail_right = get_parallels (arrow_out , tail_width / 2. )
3459
+
3460
+ #head_right, head_left = head_r, head_l
3461
+ patch_path = [(Path .MOVETO , tail_right [0 ]),
3462
+ (Path .CURVE3 , tail_right [1 ]),
3463
+ (Path .CURVE3 , tail_right [2 ]),
3464
+ (Path .LINETO , head_right [0 ]),
3465
+ (Path .CURVE3 , head_right [1 ]),
3466
+ (Path .CURVE3 , head_right [2 ]),
3467
+ (Path .CURVE3 , head_left [1 ]),
3468
+ (Path .CURVE3 , head_left [0 ]),
3469
+ (Path .LINETO , tail_left [2 ]),
3470
+ (Path .CURVE3 , tail_left [1 ]),
3471
+ (Path .CURVE3 , tail_left [0 ]),
3472
+ (Path .LINETO , tail_right [0 ]),
3473
+ (Path .CLOSEPOLY , tail_right [0 ]),
3474
+ ]
3475
+ else :
3476
+ patch_path = [(Path .MOVETO , head_right [0 ]),
3477
+ (Path .CURVE3 , head_right [1 ]),
3478
+ (Path .CURVE3 , head_right [2 ]),
3479
+ (Path .CURVE3 , head_left [1 ]),
3480
+ (Path .CURVE3 , head_left [0 ]),
3481
+ (Path .CLOSEPOLY , head_left [0 ]),
3482
+ ]
3437
3483
3438
- head_right , head_left = head_r , head_l
3439
- patch_path = [(Path .MOVETO , tail_right [0 ]),
3440
- (Path .CURVE3 , tail_right [1 ]),
3441
- (Path .CURVE3 , tail_right [2 ]),
3442
- (Path .LINETO , head_right [0 ]),
3443
- (Path .CURVE3 , head_right [1 ]),
3444
- (Path .CURVE3 , head_right [2 ]),
3445
- (Path .CURVE3 , head_left [1 ]),
3446
- (Path .CURVE3 , head_left [0 ]),
3447
- (Path .LINETO , tail_left [2 ]),
3448
- (Path .CURVE3 , tail_left [1 ]),
3449
- (Path .CURVE3 , tail_left [0 ]),
3450
- (Path .LINETO , tail_right [0 ]),
3451
- (Path .CLOSEPOLY , tail_right [0 ]),
3452
- ]
3453
3484
path = Path ([p for c , p in patch_path ], [c for c , p in patch_path ])
3454
3485
3455
3486
return path , True
@@ -3498,10 +3529,9 @@ def transmute(self, path, mutation_size, linewidth):
3498
3529
tolerence = 0.01 )
3499
3530
except NonIntersectingPathException :
3500
3531
# if this happens, make a straight line of the head_length long.
3501
- dx , dy = x2 - x1 , y2 - y1
3502
- ff = head_length / (dx * dx + dy * dy )** .5
3503
- x0 , y0 = x2 - ff * dx , y2 - ff * dy
3504
- arrow_path = [(x0 , y0 ), (x1 , y1 ), (x2 , y2 )]
3532
+ x0 , y0 = _point_along_a_line (x2 , y2 , x1 , y1 , head_length )
3533
+ x1n , y1n = 0.5 * (x0 + x2 ), 0.5 * (y0 + y2 )
3534
+ arrow_path = [(x0 , y0 ), (x1n , y1n ), (x2 , y2 )]
3505
3535
path_head = arrow_path
3506
3536
else :
3507
3537
path_head = path_in
0 commit comments