Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c76873c

Browse files
committed
fix drawing error of fancyarrow of simple style when two points are too close. This addresses matplotlib#566. Initial patch submitted by Rolf Barinka.
1 parent 8de0712 commit c76873c

File tree

6 files changed

+1667
-29
lines changed

6 files changed

+1667
-29
lines changed

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
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

Lines changed: 61 additions & 29 deletions
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
3.96 KB
Binary file not shown.
9.94 KB
Loading

0 commit comments

Comments
 (0)