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

Commit1a7b35b

Browse files
committed
refactor Bezier so it doesn't depend on Path
1 parent757fb24 commit1a7b35b

File tree

6 files changed

+172
-154
lines changed

6 files changed

+172
-154
lines changed

‎doc/api/next_api_changes/deprecations.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,19 +227,9 @@ The following validators, defined in `.rcsetup`, are deprecated:
227227
``validate_axes_titlelocation``, ``validate_toolbar``,
228228
``validate_ps_papersize``, ``validate_legend_loc``,
229229
``validate_bool_maybe_none``, ``validate_hinting``,
230-
``validate_movie_writers``.
230+
``validate_movie_writers``, ``validate_webagg_address``.
231231
To test whether an rcParam value would be acceptable, one can test e.g. ``rc =
232232
RcParams(); rc[k] = v`` raises an exception.
233-
||||||| constructed merge base
234-
``validate_ps_papersize``, ``validate_legend_log``. To test whether an rcParam
235-
value would be acceptable, one can test e.g. ``rc = RcParams(); rc[k] = v``
236-
raises an exception.
237-
=======
238-
``validate_ps_papersize``, ``validate_legend_loc``,
239-
``validate_webagg_address``.
240-
To test whether an rcParam value would be acceptable, one can test e.g. ``rc =
241-
RcParams(); rc[k] = v`` raises an exception.
242-
>>>>>>> Deprecate validate_webagg_address.
243233

244234
Stricter rcParam validation
245235
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -370,3 +360,13 @@ mathtext ``Glue`` helper classes
370360
The ``Fil``, ``Fill``, ``Filll``, ``NegFil``, ``NegFill``, ``NegFilll``, and
371361
``SsGlue`` classes in the:mod:`matplotlib.mathtext` module are deprecated.
372362
As an alternative, directly construct glue instances with ``Glue("fil")``, etc.
363+
364+
Path helpers in:mod:`.bezier`
365+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
366+
- ``bezier.make_path_regular`` is deprecated. Use ``Path.cleaned()`` (or
367+
``Path.cleaned(curves=True)``, etc.) instead (but note that these methods add
368+
a ``STOP`` code at the end of the path).
369+
- ``bezier.concatenate_paths`` is deprecated. Use ``Path.make_compound_path()``
370+
instead.
371+
- ``bezier.split_path_inout`` (use ``Path.split_path_inout`` instead)
372+
- ``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
@@ -84,7 +84,7 @@ Classes and methods
8484

8585
- ``image.BboxImage.interp_at_native`` property (no replacement)
8686
- ``lines.Line2D.verticalOffset`` property (no replacement)
87-
- ``bezier.find_r_to_boundary_of_closedpath()`` (norelacement)
87+
- ``bezier.find_r_to_boundary_of_closedpath()`` (noreplacement)
8888

8989
- ``quiver.Quiver.color()`` (use ``Quiver.get_facecolor()`` instead)
9090
- ``quiver.Quiver.keyvec`` property (no replacement)

‎lib/matplotlib/bezier.py

Lines changed: 57 additions & 111 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,54 @@ def get_normal_points(cx, cy, cos_t, sin_t, length):
6868
returnx1,y1,x2,y2
6969

7070

71+
# deprecated routines (moved to `.Path`)
72+
73+
74+
@cbook.deprecated("3.3")
75+
definside_circle(cx,cy,r):
76+
"""
77+
Return a function that checks whether a point is in a circle with center
78+
(*cx*, *cy*) and radius *r*.
79+
80+
The returned function has the signature::
81+
82+
f(xy: Tuple[float, float]) -> bool
83+
"""
84+
r2=r**2
85+
86+
def_f(xy):
87+
x,y=xy
88+
return (x-cx)**2+ (y-cy)**2<r2
89+
return_f
90+
91+
92+
@cbook.deprecated("3.3",alternative="Path.make_compound_path()")
93+
defsplit_path_inout(path,inside,tolerance=0.01,reorder_inout=False):
94+
"""
95+
Divide a path into two segments at the point where ``inside(x, y)``
96+
becomes False.
97+
"""
98+
returnpath.split_path_inout(inside,tolerance,reorder_inout)
99+
100+
101+
@cbook.deprecated(
102+
"3.3",alternative="Path.cleaned() and remove the final STOP if needed")
103+
defmake_path_regular(path):
104+
"""
105+
If the ``codes`` attribute of `.Path` *p* is None, return a copy of *p*
106+
with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise
107+
return *p* itself.
108+
"""
109+
returnpath.make_path_regular()
110+
111+
112+
@cbook.deprecated("3.3",alternative="Path.make_compound_path()")
113+
defconcatenate_paths(paths):
114+
"""Concatenate a list of paths into a single path."""
115+
from .pathimportPath
116+
returnPath.make_compound_path(*paths)
117+
118+
71119
# BEZIER routines
72120

73121
# subdividing bezier curve
@@ -177,12 +225,13 @@ class BezierSegment:
177225
"""
178226

179227
def__init__(self,control_points):
180-
n=len(control_points)
181-
self._orders=np.arange(n)
182-
coeff= [math.factorial(n-1)
183-
// (math.factorial(i)*math.factorial(n-1-i))
184-
foriinrange(n)]
185-
self._px=np.asarray(control_points).T*coeff
228+
self.cpoints=np.asarray(control_points)
229+
self.n,self.d=self.cpoints.shape
230+
self._orders=np.arange(self.n)
231+
coeff= [math.factorial(self.n-1)
232+
// (math.factorial(i)*math.factorial(self.n-1-i))
233+
foriinrange(self.n)]
234+
self._px=self.cpoints.T*coeff
186235

187236
defpoint_at_t(self,t):
188237
"""Return the point on the Bezier curve for parameter *t*."""
@@ -222,90 +271,9 @@ def split_bezier_intersecting_with_closedpath(
222271
return_left,_right
223272

224273

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-
concat=np.concatenate
241-
242-
iold=0
243-
i=1
244-
245-
forctl_points,commandinpath_iter:
246-
iold=i
247-
i+=len(ctl_points)//2
248-
ifinside(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-
raiseValueError("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-
iflen(left)==2:
259-
codes_left= [Path.LINETO]
260-
codes_right= [Path.MOVETO,Path.LINETO]
261-
eliflen(left)==3:
262-
codes_left= [Path.CURVE3,Path.CURVE3]
263-
codes_right= [Path.MOVETO,Path.CURVE3,Path.CURVE3]
264-
eliflen(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-
raiseAssertionError("This should never be reached")
269-
270-
verts_left=left[1:]
271-
verts_right=right[:]
272-
273-
ifpath.codesisNone:
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-
ifreorder_inoutandnotbegin_inside:
285-
path_in,path_out=path_out,path_in
286-
287-
returnpath_in,path_out
288-
289-
290-
definside_circle(cx,cy,r):
291-
"""
292-
Return a function that checks whether a point is in a circle with center
293-
(*cx*, *cy*) and radius *r*.
294-
295-
The returned function has the signature::
296-
297-
f(xy: Tuple[float, float]) -> bool
298-
"""
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
305-
306-
307274
# quadratic Bezier lines
308275

276+
309277
defget_cos_sin(x0,y0,x1,y1):
310278
dx,dy=x1-x0,y1-y0
311279
d= (dx*dx+dy*dy)**.5
@@ -478,25 +446,3 @@ def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
478446
c3x_right,c3y_right)
479447

480448
returnpath_left,path_right
481-
482-
483-
defmake_path_regular(p):
484-
"""
485-
If the ``codes`` attribute of `.Path` *p* is None, return a copy of *p*
486-
with ``codes`` set to (MOVETO, LINETO, LINETO, ..., LINETO); otherwise
487-
return *p* itself.
488-
"""
489-
c=p.codes
490-
ifcisNone:
491-
c=np.full(len(p.vertices),Path.LINETO,dtype=Path.code_type)
492-
c[0]=Path.MOVETO
493-
returnPath(p.vertices,c)
494-
else:
495-
returnp
496-
497-
498-
defconcatenate_paths(paths):
499-
"""Concatenate a list of paths into a single path."""
500-
vertices=np.concatenate([p.verticesforpinpaths])
501-
codes=np.concatenate([make_path_regular(p).codesforpinpaths])
502-
returnPath(vertices,codes)

‎lib/matplotlib/patches.py

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,28 @@
1010
importmatplotlibasmpl
1111
from .importartist,cbook,colors,docstring,linesasmlines,transforms
1212
from .bezierimport (
13-
NonIntersectingPathException,concatenate_paths,get_cos_sin,
14-
get_intersection,get_parallels,inside_circle,make_path_regular,
15-
make_wedged_bezier2,split_bezier_intersecting_with_closedpath,
16-
split_path_inout)
13+
NonIntersectingPathException,get_cos_sin,get_intersection,get_parallels,
14+
make_wedged_bezier2,split_bezier_intersecting_with_closedpath)
1715
from .pathimportPath
1816

1917

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+
2035
@cbook._define_aliases({
2136
"antialiased": ["aa"],
2237
"edgecolor": ["ec"],
@@ -2414,7 +2429,7 @@ def insideA(xy_display):
24142429
returnpatchA.contains(xy_event)[0]
24152430

24162431
try:
2417-
left,right=split_path_inout(path,insideA)
2432+
left,right=path.split_path_inout(insideA)
24182433
exceptValueError:
24192434
right=path
24202435

@@ -2426,7 +2441,7 @@ def insideB(xy_display):
24262441
returnpatchB.contains(xy_event)[0]
24272442

24282443
try:
2429-
left,right=split_path_inout(path,insideB)
2444+
left,right=path.split_path_inout(insideB)
24302445
exceptValueError:
24312446
left=path
24322447

@@ -2439,15 +2454,15 @@ def _shrink(self, path, shrinkA, shrinkB):
24392454
Shrink the path by fixed size (in points) with shrinkA and shrinkB.
24402455
"""
24412456
ifshrinkA:
2442-
insideA=inside_circle(*path.vertices[0],shrinkA)
2457+
insideA=_inside_circle(*path.vertices[0],shrinkA)
24432458
try:
2444-
left,path=split_path_inout(path,insideA)
2459+
left,path=path.split_path_inout(insideA)
24452460
exceptValueError:
24462461
pass
24472462
ifshrinkB:
2448-
insideB=inside_circle(*path.vertices[-1],shrinkB)
2463+
insideB=_inside_circle(*path.vertices[-1],shrinkB)
24492464
try:
2450-
path,right=split_path_inout(path,insideB)
2465+
path,right=path.split_path_inout(insideB)
24512466
exceptValueError:
24522467
pass
24532468
returnpath
@@ -2872,9 +2887,6 @@ def __call__(self, path, mutation_size, linewidth,
28722887
The __call__ method is a thin wrapper around the transmute method
28732888
and takes care of the aspect ratio.
28742889
"""
2875-
2876-
path=make_path_regular(path)
2877-
28782890
ifaspect_ratioisnotNone:
28792891
# Squeeze the given height by the aspect_ratio
28802892
vertices=path.vertices/ [1,aspect_ratio]
@@ -2886,10 +2898,9 @@ def __call__(self, path, mutation_size, linewidth,
28862898
ifnp.iterable(fillable):
28872899
path_list= []
28882900
forpinzip(path_mutated):
2889-
v,c=p.vertices,p.codes
28902901
# Restore the height
2891-
v[:,1]=v[:,1]*aspect_ratio
2892-
path_list.append(Path(v,c))
2902+
path_list.append(
2903+
Path(p.vertices* [1,aspect_ratio],p.codes))
28932904
returnpath_list,fillable
28942905
else:
28952906
returnpath_mutated,fillable
@@ -3340,7 +3351,7 @@ def transmute(self, path, mutation_size, linewidth):
33403351

33413352
# divide the path into a head and a tail
33423353
head_length=self.head_length*mutation_size
3343-
in_f=inside_circle(x2,y2,head_length)
3354+
in_f=_inside_circle(x2,y2,head_length)
33443355
arrow_path= [(x0,y0), (x1,y1), (x2,y2)]
33453356

33463357
try:
@@ -3423,7 +3434,7 @@ def transmute(self, path, mutation_size, linewidth):
34233434
arrow_path= [(x0,y0), (x1,y1), (x2,y2)]
34243435

34253436
# path for head
3426-
in_f=inside_circle(x2,y2,head_length)
3437+
in_f=_inside_circle(x2,y2,head_length)
34273438
try:
34283439
path_out,path_in=split_bezier_intersecting_with_closedpath(
34293440
arrow_path,in_f,tolerance=0.01)
@@ -3438,7 +3449,7 @@ def transmute(self, path, mutation_size, linewidth):
34383449
path_head=path_in
34393450

34403451
# path for head
3441-
in_f=inside_circle(x2,y2,head_length*.8)
3452+
in_f=_inside_circle(x2,y2,head_length*.8)
34423453
path_out,path_in=split_bezier_intersecting_with_closedpath(
34433454
arrow_path,in_f,tolerance=0.01)
34443455
path_tail=path_out
@@ -3456,7 +3467,7 @@ def transmute(self, path, mutation_size, linewidth):
34563467
w1=1.,wm=0.6,w2=0.3)
34573468

34583469
# path for head
3459-
in_f=inside_circle(x0,y0,tail_width*.3)
3470+
in_f=_inside_circle(x0,y0,tail_width*.3)
34603471
path_in,path_out=split_bezier_intersecting_with_closedpath(
34613472
arrow_path,in_f,tolerance=0.01)
34623473
tail_start=path_in[-1]
@@ -4125,7 +4136,7 @@ def get_path(self):
41254136
"""
41264137
_path,fillable=self.get_path_in_displaycoord()
41274138
ifnp.iterable(fillable):
4128-
_path=concatenate_paths(_path)
4139+
_path=Path.make_compound_path(*_path)
41294140
returnself.get_transform().inverted().transform_path(_path)
41304141

41314142
defget_path_in_displaycoord(self):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp