Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit6fe8b98

Browse files
committed
refactor Bezier so it doesn't depend on Path
1 parentdb55918 commit6fe8b98

File tree

5 files changed

+116
-96
lines changed

5 files changed

+116
-96
lines changed

‎doc/api/next_api_changes/deprecations.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,10 @@ also be accessible as ``toolbar.parent()``.
374374

375375
Path helpers in:mod:`.bezier`
376376
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
377-
378-
``bezier.make_path_regular`` is deprecated. Use``Path.cleaned()`` (or
379-
``Path.cleaned(curves=True)``, etc.) instead (but note that these methods add a
380-
``STOP``code at the end of the path).
381-
382-
``bezier.concatenate_paths``is deprecated. Use``Path.make_compound_path()``
383-
instead.
377+
- ``bezier.make_path_regular`` is deprecated. Use ``Path.cleaned()`` (or
378+
``Path.cleaned(curves=True)``, etc.) instead (but note that these methods add
379+
a ``STOP`` code at the end of the path).
380+
- ``bezier.concatenate_paths``is deprecated. Use ``Path.make_compound_path()``
381+
instead.
382+
-``bezier.split_path_inout``(use``Path.split_path_inout`` instead)
383+
- ``bezier.inside_circle()`` (no replacement)

‎doc/api/next_api_changes/removals.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ Classes, methods and attributes
103103

104104
- ``image.BboxImage.interp_at_native`` property (no replacement)
105105
- ``lines.Line2D.verticalOffset`` property (no replacement)
106-
- ``bezier.find_r_to_boundary_of_closedpath()`` (norelacement)
106+
- ``bezier.find_r_to_boundary_of_closedpath()`` (noreplacement)
107107

108108
- ``quiver.Quiver.color()`` (use ``Quiver.get_facecolor()`` instead)
109109
- ``quiver.Quiver.keyvec`` property (no replacement)

‎lib/matplotlib/bezier.py

Lines changed: 17 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
importnumpyasnp
88

99
importmatplotlib.cbookascbook
10-
frommatplotlib.pathimportPath
1110

1211

1312
classNonIntersectingPathException(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
returnx1,y1,x2,y2
6969

7070

71+
@cbook.deprecated("3.3",alternative="Path.split_path_inout()")
72+
defsplit_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+
returnpath.split_path_inout(inside,tolerance,reorder_inout)
78+
79+
7180
# BEZIER routines
7281

7382
# subdividing bezier curve
@@ -222,69 +231,7 @@ def split_bezier_intersecting_with_closedpath(
222231
return_left,_right
223232

224233

225-
# matplotlib specific
226-
227-
228-
defsplit_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-
iold=0
241-
i=1
242-
243-
forctl_points,commandinpath_iter:
244-
iold=i
245-
i+=len(ctl_points)//2
246-
ifinside(ctl_points[-2:])!=begin_inside:
247-
bezier_path=np.concatenate([ctl_points_old[-2:],ctl_points])
248-
break
249-
ctl_points_old=ctl_points
250-
else:
251-
raiseValueError("The path does not intersect with the patch")
252-
253-
bp=bezier_path.reshape((-1,2))
254-
left,right=split_bezier_intersecting_with_closedpath(
255-
bp,inside,tolerance)
256-
iflen(left)==2:
257-
codes_left= [Path.LINETO]
258-
codes_right= [Path.MOVETO,Path.LINETO]
259-
eliflen(left)==3:
260-
codes_left= [Path.CURVE3,Path.CURVE3]
261-
codes_right= [Path.MOVETO,Path.CURVE3,Path.CURVE3]
262-
eliflen(left)==4:
263-
codes_left= [Path.CURVE4,Path.CURVE4,Path.CURVE4]
264-
codes_right= [Path.MOVETO,Path.CURVE4,Path.CURVE4,Path.CURVE4]
265-
else:
266-
raiseAssertionError("This should never be reached")
267-
268-
verts_left=left[1:]
269-
verts_right=right[:]
270-
271-
ifpath.codesisNone:
272-
path_in=Path(np.concatenate([path.vertices[:i],verts_left]))
273-
path_out=Path(np.concatenate([verts_right,path.vertices[i:]]))
274-
275-
else:
276-
path_in=Path(np.concatenate([path.vertices[:iold],verts_left]),
277-
np.concatenate([path.codes[:iold],codes_left]))
278-
279-
path_out=Path(np.concatenate([verts_right,path.vertices[i:]]),
280-
np.concatenate([codes_right,path.codes[i:]]))
281-
282-
ifreorder_inoutandnotbegin_inside:
283-
path_in,path_out=path_out,path_in
284-
285-
returnpath_in,path_out
286-
287-
234+
@cbook.deprecated("3.3")
288235
definside_circle(cx,cy,r):
289236
"""
290237
Return a function that checks whether a point is in a circle with center
@@ -294,16 +241,13 @@ def inside_circle(cx, cy, r):
294241
295242
f(xy: Tuple[float, float]) -> bool
296243
"""
297-
r2=r**2
298-
299-
def_f(xy):
300-
x,y=xy
301-
return (x-cx)**2+ (y-cy)**2<r2
302-
return_f
244+
from .patchesimport_inside_circle
245+
return_inside_circle(cx,cy,r)
303246

304247

305248
# quadratic Bezier lines
306249

250+
307251
defget_cos_sin(x0,y0,x1,y1):
308252
dx,dy=x1-x0,y1-y0
309253
d= (dx*dx+dy*dy)**.5
@@ -486,6 +430,7 @@ def make_path_regular(p):
486430
with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise
487431
return *p* itself.
488432
"""
433+
from .pathimportPath
489434
c=p.codes
490435
ifcisNone:
491436
c=np.full(len(p.vertices),Path.LINETO,dtype=Path.code_type)
@@ -498,6 +443,5 @@ def make_path_regular(p):
498443
@cbook.deprecated("3.3",alternative="Path.make_compound_path()")
499444
defconcatenate_paths(paths):
500445
"""Concatenate a list of paths into a single path."""
501-
vertices=np.concatenate([p.verticesforpinpaths])
502-
codes=np.concatenate([make_path_regular(p).codesforpinpaths])
503-
returnPath(vertices,codes)
446+
from .pathimportPath
447+
returnPath.make_compound_path(*paths)

‎lib/matplotlib/patches.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,28 @@
1010
importmatplotlibasmpl
1111
from .importartist,cbook,colors,docstring,linesasmlines,transforms
1212
from .bezierimport (
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 .pathimportPath
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"],
@@ -2428,7 +2444,7 @@ def insideA(xy_display):
24282444
returnpatchA.contains(xy_event)[0]
24292445

24302446
try:
2431-
left,right=split_path_inout(path,insideA)
2447+
left,right=path.split_path_inout(insideA)
24322448
exceptValueError:
24332449
right=path
24342450

@@ -2440,7 +2456,7 @@ def insideB(xy_display):
24402456
returnpatchB.contains(xy_event)[0]
24412457

24422458
try:
2443-
left,right=split_path_inout(path,insideB)
2459+
left,right=path.split_path_inout(insideB)
24442460
exceptValueError:
24452461
left=path
24462462

@@ -2453,15 +2469,15 @@ def _shrink(self, path, shrinkA, shrinkB):
24532469
Shrink the path by fixed size (in points) with shrinkA and shrinkB.
24542470
"""
24552471
ifshrinkA:
2456-
insideA=inside_circle(*path.vertices[0],shrinkA)
2472+
insideA=_inside_circle(*path.vertices[0],shrinkA)
24572473
try:
2458-
left,path=split_path_inout(path,insideA)
2474+
left,path=path.split_path_inout(insideA)
24592475
exceptValueError:
24602476
pass
24612477
ifshrinkB:
2462-
insideB=inside_circle(*path.vertices[-1],shrinkB)
2478+
insideB=_inside_circle(*path.vertices[-1],shrinkB)
24632479
try:
2464-
path,right=split_path_inout(path,insideB)
2480+
path,right=path.split_path_inout(insideB)
24652481
exceptValueError:
24662482
pass
24672483
returnpath
@@ -2886,7 +2902,6 @@ def __call__(self, path, mutation_size, linewidth,
28862902
The __call__ method is a thin wrapper around the transmute method
28872903
and takes care of the aspect ratio.
28882904
"""
2889-
28902905
ifaspect_ratioisnotNone:
28912906
# Squeeze the given height by the aspect_ratio
28922907
vertices=path.vertices/ [1,aspect_ratio]
@@ -3351,7 +3366,7 @@ def transmute(self, path, mutation_size, linewidth):
33513366

33523367
# divide the path into a head and a tail
33533368
head_length=self.head_length*mutation_size
3354-
in_f=inside_circle(x2,y2,head_length)
3369+
in_f=_inside_circle(x2,y2,head_length)
33553370
arrow_path= [(x0,y0), (x1,y1), (x2,y2)]
33563371

33573372
try:
@@ -3434,7 +3449,7 @@ def transmute(self, path, mutation_size, linewidth):
34343449
arrow_path= [(x0,y0), (x1,y1), (x2,y2)]
34353450

34363451
# path for head
3437-
in_f=inside_circle(x2,y2,head_length)
3452+
in_f=_inside_circle(x2,y2,head_length)
34383453
try:
34393454
path_out,path_in=split_bezier_intersecting_with_closedpath(
34403455
arrow_path,in_f,tolerance=0.01)
@@ -3449,7 +3464,7 @@ def transmute(self, path, mutation_size, linewidth):
34493464
path_head=path_in
34503465

34513466
# path for head
3452-
in_f=inside_circle(x2,y2,head_length*.8)
3467+
in_f=_inside_circle(x2,y2,head_length*.8)
34533468
path_out,path_in=split_bezier_intersecting_with_closedpath(
34543469
arrow_path,in_f,tolerance=0.01)
34553470
path_tail=path_out
@@ -3467,7 +3482,7 @@ def transmute(self, path, mutation_size, linewidth):
34673482
w1=1.,wm=0.6,w2=0.3)
34683483

34693484
# path for head
3470-
in_f=inside_circle(x0,y0,tail_width*.3)
3485+
in_f=_inside_circle(x0,y0,tail_width*.3)
34713486
path_in,path_out=split_bezier_intersecting_with_closedpath(
34723487
arrow_path,in_f,tolerance=0.01)
34733488
tail_start=path_in[-1]

‎lib/matplotlib/path.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
importmatplotlibasmpl
1818
from .import_path,cbook
1919
from .cbookimport_to_unmasked_float_array,simple_linear_interpolation
20+
from .bezierimportsplit_bezier_intersecting_with_closedpath
2021

2122

2223
classPath:
@@ -586,6 +587,65 @@ def interpolated(self, steps):
586587
new_codes=None
587588
returnPath(vertices,new_codes)
588589

590+
defsplit_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+
iold=0
603+
i=1
604+
605+
forctl_points,commandinpath_iter:
606+
iold=i
607+
i+=len(ctl_points)//2
608+
ifinside(ctl_points[-2:])!=begin_inside:
609+
bezier_path=np.concatenate([ctl_points_old[-2:],ctl_points])
610+
break
611+
ctl_points_old=ctl_points
612+
else:
613+
raiseValueError("The path does not intersect with the patch")
614+
615+
bp=bezier_path.reshape((-1,2))
616+
left,right=split_bezier_intersecting_with_closedpath(
617+
bp,inside,tolerance)
618+
iflen(left)==2:
619+
codes_left= [Path.LINETO]
620+
codes_right= [Path.MOVETO,Path.LINETO]
621+
eliflen(left)==3:
622+
codes_left= [Path.CURVE3,Path.CURVE3]
623+
codes_right= [Path.MOVETO,Path.CURVE3,Path.CURVE3]
624+
eliflen(left)==4:
625+
codes_left= [Path.CURVE4,Path.CURVE4,Path.CURVE4]
626+
codes_right= [Path.MOVETO,Path.CURVE4,Path.CURVE4,Path.CURVE4]
627+
else:
628+
raiseAssertionError("This should never be reached")
629+
630+
verts_left=left[1:]
631+
verts_right=right[:]
632+
633+
ifself.codesisNone:
634+
path_in=Path(np.concatenate([self.vertices[:i],verts_left]))
635+
path_out=Path(np.concatenate([verts_right,self.vertices[i:]]))
636+
637+
else:
638+
path_in=Path(np.concatenate([self.vertices[:iold],verts_left]),
639+
np.concatenate([self.codes[:iold],codes_left]))
640+
641+
path_out=Path(np.concatenate([verts_right,self.vertices[i:]]),
642+
np.concatenate([codes_right,self.codes[i:]]))
643+
644+
ifreorder_inoutandnotbegin_inside:
645+
path_in,path_out=path_out,path_in
646+
647+
returnpath_in,path_out
648+
589649
defto_polygons(self,transform=None,width=0,height=0,closed_only=True):
590650
"""
591651
Convert this path to a list of polygons or polylines. Each
@@ -648,7 +708,8 @@ def unit_rectangle(cls):
648708
defunit_regular_polygon(cls,numVertices):
649709
"""
650710
Return a :class:`Path` instance for a unit regular polygon with the
651-
given *numVertices* and radius of 1.0, centered at (0, 0).
711+
given *numVertices* such that the circumscribing circle has radius 1.0,
712+
centered at (0, 0).
652713
"""
653714
ifnumVertices<=16:
654715
path=cls._unit_regular_polygons.get(numVertices)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp