Skip to content

Commit 70e1b25

Browse files
committed
Merge pull request matplotlib#1340 from leejjoon/fix-simple-arrow2
fix drawing error of fancyarrow of simple style (v1.2.x)
2 parents 8de0712 + c76873c commit 70e1b25

File tree

6 files changed

+1667
-29
lines changed

6 files changed

+1667
-29
lines changed

lib/matplotlib/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,7 @@ def tk_window_focus():
10831083
'matplotlib.tests.test_tightlayout',
10841084
'matplotlib.tests.test_triangulation',
10851085
'matplotlib.tests.test_transforms',
1086+
'matplotlib.tests.test_arrow_patches',
10861087
]
10871088

10881089

lib/matplotlib/patches.py

+61-29
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,18 @@ def connect(self, posA, posB):
28412841
{"AvailableConnectorstyles": _pprint_styles(_style_list)}
28422842

28432843

2844+
def _point_along_a_line(x0, y0, x1, y1, d):
2845+
"""
2846+
find a point along a line connecting (x0, y0) -- (x1, y1) whose
2847+
distance from (x0, y0) is d.
2848+
"""
2849+
dx, dy = x0 - x1, y0 - y1
2850+
ff = d/(dx*dx+dy*dy)**.5
2851+
x2, y2 = x0 - ff*dx, y0 - ff*dy
2852+
2853+
return x2, y2
2854+
2855+
28442856
class ArrowStyle(_Style):
28452857
"""
28462858
:class:`ArrowStyle` is a container class which defines several
@@ -3460,35 +3472,57 @@ def transmute(self, path, mutation_size, linewidth):
34603472
head_length = self.head_length * mutation_size
34613473
in_f = inside_circle(x2, y2, head_length)
34623474
arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
3463-
arrow_out, arrow_in = \
3464-
split_bezier_intersecting_with_closedpath(arrow_path,
3465-
in_f,
3466-
tolerence=0.01)
3475+
3476+
from bezier import NonIntersectingPathException
3477+
3478+
try:
3479+
arrow_out, arrow_in = \
3480+
split_bezier_intersecting_with_closedpath(arrow_path,
3481+
in_f,
3482+
tolerence=0.01)
3483+
except NonIntersectingPathException:
3484+
# if this happens, make a straight line of the head_length long.
3485+
x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
3486+
x1n, y1n = 0.5*(x0+x2), 0.5*(y0+y2)
3487+
arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)]
3488+
arrow_out = None
34673489

34683490
# head
34693491
head_width = self.head_width * mutation_size
3470-
head_l, head_r = make_wedged_bezier2(arrow_in, head_width / 2.,
3471-
wm=.5)
3492+
head_left, head_right = \
3493+
make_wedged_bezier2(arrow_in, head_width/2.,
3494+
wm=.5)
3495+
34723496

34733497
# tail
3474-
tail_width = self.tail_width * mutation_size
3475-
tail_left, tail_right = get_parallels(arrow_out, tail_width / 2.)
3498+
if arrow_out is not None:
3499+
tail_width = self.tail_width * mutation_size
3500+
tail_left, tail_right = get_parallels(arrow_out, tail_width/2.)
3501+
3502+
#head_right, head_left = head_r, head_l
3503+
patch_path = [(Path.MOVETO, tail_right[0]),
3504+
(Path.CURVE3, tail_right[1]),
3505+
(Path.CURVE3, tail_right[2]),
3506+
(Path.LINETO, head_right[0]),
3507+
(Path.CURVE3, head_right[1]),
3508+
(Path.CURVE3, head_right[2]),
3509+
(Path.CURVE3, head_left[1]),
3510+
(Path.CURVE3, head_left[0]),
3511+
(Path.LINETO, tail_left[2]),
3512+
(Path.CURVE3, tail_left[1]),
3513+
(Path.CURVE3, tail_left[0]),
3514+
(Path.LINETO, tail_right[0]),
3515+
(Path.CLOSEPOLY, tail_right[0]),
3516+
]
3517+
else:
3518+
patch_path = [(Path.MOVETO, head_right[0]),
3519+
(Path.CURVE3, head_right[1]),
3520+
(Path.CURVE3, head_right[2]),
3521+
(Path.CURVE3, head_left[1]),
3522+
(Path.CURVE3, head_left[0]),
3523+
(Path.CLOSEPOLY, head_left[0]),
3524+
]
34763525

3477-
head_right, head_left = head_r, head_l
3478-
patch_path = [(Path.MOVETO, tail_right[0]),
3479-
(Path.CURVE3, tail_right[1]),
3480-
(Path.CURVE3, tail_right[2]),
3481-
(Path.LINETO, head_right[0]),
3482-
(Path.CURVE3, head_right[1]),
3483-
(Path.CURVE3, head_right[2]),
3484-
(Path.CURVE3, head_left[1]),
3485-
(Path.CURVE3, head_left[0]),
3486-
(Path.LINETO, tail_left[2]),
3487-
(Path.CURVE3, tail_left[1]),
3488-
(Path.CURVE3, tail_left[0]),
3489-
(Path.LINETO, tail_right[0]),
3490-
(Path.CLOSEPOLY, tail_right[0]),
3491-
]
34923526
path = Path([p for c, p in patch_path], [c for c, p in patch_path])
34933527

34943528
return path, True
@@ -3536,12 +3570,10 @@ def transmute(self, path, mutation_size, linewidth):
35363570
in_f,
35373571
tolerence=0.01)
35383572
except NonIntersectingPathException:
3539-
# if this happens, make a straight line of the head_length
3540-
# long.
3541-
dx, dy = x2 - x1, y2 - y1
3542-
ff = head_length / (dx * dx + dy * dy) ** .5
3543-
x0, y0 = x2 - ff * dx, y2 - ff * dy
3544-
arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
3573+
# if this happens, make a straight line of the head_length long.
3574+
x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
3575+
x1n, y1n = 0.5*(x0+x2), 0.5*(y0+y2)
3576+
arrow_path = [(x0, y0), (x1n, y1n), (x2, y2)]
35453577
path_head = arrow_path
35463578
else:
35473579
path_head = path_in
Binary file not shown.
Loading

0 commit comments

Comments
 (0)