Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 09f98da

Browse filesBrowse files
committed
refactor Bezier so it doesn't depend on Path
1 parent ef0f6e4 commit 09f98da
Copy full SHA for 09f98da

File tree

Expand file treeCollapse file tree

5 files changed

+118
-98
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+118
-98
lines changed

‎doc/api/next_api_changes/deprecations.rst

Copy file name to clipboardExpand all lines: doc/api/next_api_changes/deprecations.rst
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ also be accessible as ``toolbar.parent()``.
369369

370370
Path helpers in :mod:`.bezier`
371371
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
372-
373-
``bezier.make_path_regular`` is deprecated. Use ``Path.cleaned()`` (or
374-
``Path.cleaned(curves=True)``, etc.) instead (but note that these methods add a
375-
``STOP`` code at the end of the path).
376-
377-
``bezier.concatenate_paths`` is deprecated. Use ``Path.make_compound_path()``
378-
instead.
372+
- ``bezier.make_path_regular`` is deprecated. Use ``Path.cleaned()`` (or
373+
``Path.cleaned(curves=True)``, etc.) instead (but note that these methods add
374+
a ``STOP`` code at the end of the path).
375+
- ``bezier.concatenate_paths`` is deprecated. Use ``Path.make_compound_path()``
376+
instead.
377+
- ``bezier.split_path_inout`` (use ``Path.split_path_inout`` instead)
378+
- ``bezier.inside_circle()`` (no replacement)

‎doc/api/next_api_changes/removals.rst

Copy file name to clipboardExpand all lines: doc/api/next_api_changes/removals.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Classes and methods
9292

9393
- ``image.BboxImage.interp_at_native`` property (no replacement)
9494
- ``lines.Line2D.verticalOffset`` property (no replacement)
95-
- ``bezier.find_r_to_boundary_of_closedpath()`` (no relacement)
95+
- ``bezier.find_r_to_boundary_of_closedpath()`` (no replacement)
9696

9797
- ``quiver.Quiver.color()`` (use ``Quiver.get_facecolor()`` instead)
9898
- ``quiver.Quiver.keyvec`` property (no replacement)

‎lib/matplotlib/bezier.py

Copy file name to clipboardExpand all lines: lib/matplotlib/bezier.py
+17-75Lines changed: 17 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
import numpy as np
88

99
import matplotlib.cbook as cbook
10-
from matplotlib.path import Path
1110

1211

1312
class NonIntersectingPathException(ValueError):
1413
pass
1514

15+
1616
# some functions
1717

1818

@@ -68,6 +68,15 @@ def get_normal_points(cx, cy, cos_t, sin_t, length):
6868
return x1, y1, x2, y2
6969

7070

71+
@cbook.deprecated("3.3", alternative="Path.split_path_inout()")
72+
def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False):
73+
"""
74+
Divide a path into two segments at the point where ``inside(x, y)``
75+
becomes False.
76+
"""
77+
return path.split_path_inout(inside, tolerance, reorder_inout)
78+
79+
7180
# BEZIER routines
7281

7382
# subdividing bezier curve
@@ -222,71 +231,7 @@ def split_bezier_intersecting_with_closedpath(
222231
return _left, _right
223232

224233

225-
# matplotlib specific
226-
227-
228-
def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False):
229-
"""
230-
Divide a path into two segments at the point where ``inside(x, y)`` becomes
231-
False.
232-
"""
233-
path_iter = path.iter_segments()
234-
235-
ctl_points, command = next(path_iter)
236-
begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
237-
238-
ctl_points_old = ctl_points
239-
240-
concat = np.concatenate
241-
242-
iold = 0
243-
i = 1
244-
245-
for ctl_points, command in path_iter:
246-
iold = i
247-
i += len(ctl_points) // 2
248-
if inside(ctl_points[-2:]) != begin_inside:
249-
bezier_path = concat([ctl_points_old[-2:], ctl_points])
250-
break
251-
ctl_points_old = ctl_points
252-
else:
253-
raise ValueError("The path does not intersect with the patch")
254-
255-
bp = bezier_path.reshape((-1, 2))
256-
left, right = split_bezier_intersecting_with_closedpath(
257-
bp, inside, tolerance)
258-
if len(left) == 2:
259-
codes_left = [Path.LINETO]
260-
codes_right = [Path.MOVETO, Path.LINETO]
261-
elif len(left) == 3:
262-
codes_left = [Path.CURVE3, Path.CURVE3]
263-
codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
264-
elif len(left) == 4:
265-
codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
266-
codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
267-
else:
268-
raise AssertionError("This should never be reached")
269-
270-
verts_left = left[1:]
271-
verts_right = right[:]
272-
273-
if path.codes is None:
274-
path_in = Path(concat([path.vertices[:i], verts_left]))
275-
path_out = Path(concat([verts_right, path.vertices[i:]]))
276-
277-
else:
278-
path_in = Path(concat([path.vertices[:iold], verts_left]),
279-
concat([path.codes[:iold], codes_left]))
280-
281-
path_out = Path(concat([verts_right, path.vertices[i:]]),
282-
concat([codes_right, path.codes[i:]]))
283-
284-
if reorder_inout and not begin_inside:
285-
path_in, path_out = path_out, path_in
286-
287-
return path_in, path_out
288-
289-
234+
@cbook.deprecated("3.3")
290235
def inside_circle(cx, cy, r):
291236
"""
292237
Return a function that checks whether a point is in a circle with center
@@ -296,16 +241,13 @@ def inside_circle(cx, cy, r):
296241
297242
f(xy: Tuple[float, float]) -> bool
298243
"""
299-
r2 = r ** 2
300-
301-
def _f(xy):
302-
x, y = xy
303-
return (x - cx) ** 2 + (y - cy) ** 2 < r2
304-
return _f
244+
from .patches import _inside_circle
245+
return _inside_circle(cx, cy, r)
305246

306247

307248
# quadratic Bezier lines
308249

250+
309251
def get_cos_sin(x0, y0, x1, y1):
310252
dx, dy = x1 - x0, y1 - y0
311253
d = (dx * dx + dy * dy) ** .5
@@ -488,6 +430,7 @@ def make_path_regular(p):
488430
with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise
489431
return *p* itself.
490432
"""
433+
from .path import Path
491434
c = p.codes
492435
if c is None:
493436
c = np.full(len(p.vertices), Path.LINETO, dtype=Path.code_type)
@@ -500,6 +443,5 @@ def make_path_regular(p):
500443
@cbook.deprecated("3.3", alternative="Path.make_compound_path()")
501444
def concatenate_paths(paths):
502445
"""Concatenate a list of paths into a single path."""
503-
vertices = np.concatenate([p.vertices for p in paths])
504-
codes = np.concatenate([make_path_regular(p).codes for p in paths])
505-
return Path(vertices, codes)
446+
from .path import Path
447+
return Path.make_compound_path(*paths)

‎lib/matplotlib/patches.py

Copy file name to clipboardExpand all lines: lib/matplotlib/patches.py
+29-14Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,28 @@
1010
import matplotlib as mpl
1111
from . import artist, cbook, colors, docstring, lines as mlines, transforms
1212
from .bezier import (
13-
NonIntersectingPathException, get_cos_sin, get_intersection,
14-
get_parallels, inside_circle, make_wedged_bezier2,
15-
split_bezier_intersecting_with_closedpath, split_path_inout)
13+
NonIntersectingPathException, get_cos_sin, get_intersection, get_parallels,
14+
make_wedged_bezier2, split_bezier_intersecting_with_closedpath)
1615
from .path import Path
1716

1817

18+
def _inside_circle(cx, cy, r):
19+
"""
20+
Return a function that checks whether a point is in a circle with center
21+
(*cx*, *cy*) and radius *r*.
22+
23+
The returned function has the signature::
24+
25+
f(xy: Tuple[float, float]) -> bool
26+
"""
27+
r2 = r ** 2
28+
29+
def _f(xy):
30+
x, y = xy
31+
return (x - cx) ** 2 + (y - cy) ** 2 < r2
32+
return _f
33+
34+
1935
@cbook._define_aliases({
2036
"antialiased": ["aa"],
2137
"edgecolor": ["ec"],
@@ -2411,7 +2427,7 @@ def insideA(xy_display):
24112427
return patchA.contains(xy_event)[0]
24122428

24132429
try:
2414-
left, right = split_path_inout(path, insideA)
2430+
left, right = path.split_path_inout(insideA)
24152431
except ValueError:
24162432
right = path
24172433

@@ -2423,7 +2439,7 @@ def insideB(xy_display):
24232439
return patchB.contains(xy_event)[0]
24242440

24252441
try:
2426-
left, right = split_path_inout(path, insideB)
2442+
left, right = path.split_path_inout(insideB)
24272443
except ValueError:
24282444
left = path
24292445

@@ -2436,15 +2452,15 @@ def _shrink(self, path, shrinkA, shrinkB):
24362452
Shrink the path by fixed size (in points) with shrinkA and shrinkB.
24372453
"""
24382454
if shrinkA:
2439-
insideA = inside_circle(*path.vertices[0], shrinkA)
2455+
insideA = _inside_circle(*path.vertices[0], shrinkA)
24402456
try:
2441-
left, path = split_path_inout(path, insideA)
2457+
left, path = path.split_path_inout(insideA)
24422458
except ValueError:
24432459
pass
24442460
if shrinkB:
2445-
insideB = inside_circle(*path.vertices[-1], shrinkB)
2461+
insideB = _inside_circle(*path.vertices[-1], shrinkB)
24462462
try:
2447-
path, right = split_path_inout(path, insideB)
2463+
path, right = path.split_path_inout(insideB)
24482464
except ValueError:
24492465
pass
24502466
return path
@@ -2869,7 +2885,6 @@ def __call__(self, path, mutation_size, linewidth,
28692885
The __call__ method is a thin wrapper around the transmute method
28702886
and takes care of the aspect ratio.
28712887
"""
2872-
28732888
if aspect_ratio is not None:
28742889
# Squeeze the given height by the aspect_ratio
28752890
vertices = path.vertices / [1, aspect_ratio]
@@ -3334,7 +3349,7 @@ def transmute(self, path, mutation_size, linewidth):
33343349

33353350
# divide the path into a head and a tail
33363351
head_length = self.head_length * mutation_size
3337-
in_f = inside_circle(x2, y2, head_length)
3352+
in_f = _inside_circle(x2, y2, head_length)
33383353
arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
33393354

33403355
try:
@@ -3417,7 +3432,7 @@ def transmute(self, path, mutation_size, linewidth):
34173432
arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
34183433

34193434
# path for head
3420-
in_f = inside_circle(x2, y2, head_length)
3435+
in_f = _inside_circle(x2, y2, head_length)
34213436
try:
34223437
path_out, path_in = split_bezier_intersecting_with_closedpath(
34233438
arrow_path, in_f, tolerance=0.01)
@@ -3432,7 +3447,7 @@ def transmute(self, path, mutation_size, linewidth):
34323447
path_head = path_in
34333448

34343449
# path for head
3435-
in_f = inside_circle(x2, y2, head_length * .8)
3450+
in_f = _inside_circle(x2, y2, head_length * .8)
34363451
path_out, path_in = split_bezier_intersecting_with_closedpath(
34373452
arrow_path, in_f, tolerance=0.01)
34383453
path_tail = path_out
@@ -3450,7 +3465,7 @@ def transmute(self, path, mutation_size, linewidth):
34503465
w1=1., wm=0.6, w2=0.3)
34513466

34523467
# path for head
3453-
in_f = inside_circle(x0, y0, tail_width * .3)
3468+
in_f = _inside_circle(x0, y0, tail_width * .3)
34543469
path_in, path_out = split_bezier_intersecting_with_closedpath(
34553470
arrow_path, in_f, tolerance=0.01)
34563471
tail_start = path_in[-1]

‎lib/matplotlib/path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/path.py
+64-1Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import matplotlib as mpl
1818
from . import _path, cbook
1919
from .cbook import _to_unmasked_float_array, simple_linear_interpolation
20+
from .bezier import split_bezier_intersecting_with_closedpath
2021

2122

2223
class Path:
@@ -586,6 +587,67 @@ def interpolated(self, steps):
586587
new_codes = None
587588
return Path(vertices, new_codes)
588589

590+
def split_path_inout(self, inside, tolerance=0.01, reorder_inout=False):
591+
"""
592+
Divide a path into two segments at the point where ``inside(x, y)``
593+
becomes False.
594+
"""
595+
path_iter = self.iter_segments()
596+
597+
ctl_points, command = next(path_iter)
598+
begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
599+
600+
ctl_points_old = ctl_points
601+
602+
concat = np.concatenate
603+
604+
iold = 0
605+
i = 1
606+
607+
for ctl_points, command in path_iter:
608+
iold = i
609+
i += len(ctl_points) // 2
610+
if inside(ctl_points[-2:]) != begin_inside:
611+
bezier_path = concat([ctl_points_old[-2:], ctl_points])
612+
break
613+
ctl_points_old = ctl_points
614+
else:
615+
raise ValueError("The path does not intersect with the patch")
616+
617+
bp = bezier_path.reshape((-1, 2))
618+
left, right = split_bezier_intersecting_with_closedpath(
619+
bp, inside, tolerance)
620+
if len(left) == 2:
621+
codes_left = [Path.LINETO]
622+
codes_right = [Path.MOVETO, Path.LINETO]
623+
elif len(left) == 3:
624+
codes_left = [Path.CURVE3, Path.CURVE3]
625+
codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
626+
elif len(left) == 4:
627+
codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
628+
codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
629+
else:
630+
raise AssertionError("This should never be reached")
631+
632+
verts_left = left[1:]
633+
verts_right = right[:]
634+
635+
if self.codes is None:
636+
path_in = Path(concat([self.vertices[:i], verts_left]))
637+
path_out = Path(concat([verts_right, self.vertices[i:]]))
638+
639+
else:
640+
path_in = Path(concat([self.vertices[:iold], verts_left]),
641+
concat([self.codes[:iold], codes_left]))
642+
643+
path_out = Path(concat([verts_right, self.vertices[i:]]),
644+
concat([codes_right, self.codes[i:]]))
645+
646+
if reorder_inout and not begin_inside:
647+
path_in, path_out = path_out, path_in
648+
649+
return path_in, path_out
650+
589651
def to_polygons(self, transform=None, width=0, height=0, closed_only=True):
590652
"""
591653
Convert this path to a list of polygons or polylines. Each
@@ -648,7 +710,8 @@ def unit_rectangle(cls):
648710
def unit_regular_polygon(cls, numVertices):
649711
"""
650712
Return a :class:`Path` instance for a unit regular polygon with the
651-
given *numVertices* and radius of 1.0, centered at (0, 0).
713+
given *numVertices* such that the circumscribing circle has radius 1.0,
714+
centered at (0, 0).
652715
"""
653716
if numVertices <= 16:
654717
path = cls._unit_regular_polygons.get(numVertices)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.