Skip to content

Commit efceb57

Browse files
committed
DOCS: @QuLogic's suggestions for stroked extents docs
1 parent a055b24 commit efceb57

File tree

1 file changed

+50
-33
lines changed

1 file changed

+50
-33
lines changed

lib/matplotlib/path.py

+50-33
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,16 @@
3030
----------
3131
apex : Tuple[float,float]
3232
The position of the vertex.
33-
incidence_angle : float, in
34-
For vertices with one incoming line, set to ``None``. For vertices that
35-
form a corner, the angle swept out by the two lines that meet at the
36-
vertex.
37-
corner_angle : float
38-
the internal angle of the corner, where np.pi is a straight line, and 0
33+
incidence_angle : float, in [-pi, pi]
34+
For vertices with one incoming line, the orientation of the tangent vector
35+
to the line at its tip (as returned by `np.arctan2`). For corners (vertices
36+
with two incoming lines) the orientation of the corner's bisector should be
37+
used instead. All orientation angles should be computed assuming the line
38+
or bisector "points" towards the corner's apex.
39+
corner_angle : float, in [0, pi]
40+
The internal angle of the corner, where np.pi is a straight line, and 0
3941
is retracing exactly the way you came. None can be used to signify that
4042
the line ends there (i.e. no corner).
41-
42-
Notes
43-
-----
44-
$\pi$ and 0 are equivalent for `corner_angle`. Both $\theta$ and $\pi - \theta$
45-
are equivalent for `incidence_angle` by symmetry.
4643
"""
4744

4845

@@ -726,7 +723,7 @@ def get_stroked_extents(self, markeredgewidth, transform, joinstyle,
726723
typically defined in points, so it doesn't usually make sense to
727724
request the stroked extents of a path without transforming it.
728725
joinstyle : {'miter', 'bevel', 'round'}
729-
How the corner is to be drawn.
726+
How line corners are to be drawn.
730727
capstyle : {'butt', 'round', 'projecting'}
731728
How line ends are to be drawn.
732729
**kwargs
@@ -742,7 +739,7 @@ def get_stroked_extents(self, markeredgewidth, transform, joinstyle,
742739
----
743740
The approach used is simply to notice that the bbox with no marker edge
744741
must be defined by a corner (control point of the linear parts of path)
745-
or a an extremal point on one of the curved parts of the path.
742+
or an extremal point on one of the curved parts of the path.
746743
747744
For a nonzero marker edge width, because the interior extrema will by
748745
definition be parallel to the bounding box, we need only check if the
@@ -1209,26 +1206,36 @@ def get_path_collection_extents(
12091206

12101207

12111208
def _vertex_info_from_angles(angle_1, angle_2):
1212-
"""
1213-
Gets VertexInfo from direction of lines making up a corner.
1214-
1215-
This function expects angle_1 and angle_2 (in radians) to be
1216-
the orientation of lines 1 and 2 (arbitrarily chosen to point
1217-
towards the corner where they meet) relative to the coordinate
1218-
system.
1209+
r"""
1210+
Gets `.VertexInfo` from direction of lines making up a corner.
12191211
12201212
Helper function for `.iter_angles`.
12211213
1214+
Parameters
1215+
----------
1216+
angle_1 : float in [-pi, pi]
1217+
Orientation of the tangent vector of the first line at the corner, if
1218+
the tangent vector is defined to be oriented pointing along the line
1219+
towards the corner's apex. See `Examples` for clarification.
1220+
angle_2 : float
1221+
Same as *angle_1* but for the other line forming the corner.
1222+
12221223
Returns
12231224
-------
12241225
incidence_angle : float in [-pi, pi]
1225-
as described in VertexInfo docs
1226+
as described in `.VertexInfo` docs
12261227
corner_angle : float in [0, pi]
1227-
as described in VertexInfo docs
1228+
as described in `.VertexInfo` docs
12281229
12291230
Notes
12301231
-----
12311232
Is necessarily ambiguous if corner_angle is pi.
1233+
1234+
Examples
1235+
--------
1236+
The only corner in ``Path([[0, 0], [1, 1], [0, 1]])`` would have two lines,
1237+
(``Path([[0, 0], [1, 1]])`` and ``Path([[1, 1], [0, 1]])``), with angles
1238+
:math:`\pi/4` and :math:`0`, respectively.
12321239
"""
12331240
# get "interior" angle between tangents to joined curves' tips
12341241
corner_angle = np.abs(angle_1 - angle_2)
@@ -1248,11 +1255,12 @@ def _vertex_info_from_angles(angle_1, angle_2):
12481255

12491256

12501257
def _stroke_x_overflow(width, phi, theta, joinstyle='miter', capstyle='butt'):
1251-
"""
1252-
Computes how far right a stroke of *width* extends past x coordinate of
1253-
vertex.
1258+
r"""
1259+
Compute distance a stroke of *width* extends past x coordinate of vertex.
12541260
1255-
Assumes the incident lines are both coming from the left.
1261+
The formulas here only work for corners which "point" in the positive x
1262+
direction. That is, we assume the incident lines are both coming from the
1263+
left, and extension is only measured to the right.
12561264
12571265
Parameters
12581266
----------
@@ -1269,14 +1277,23 @@ def _stroke_x_overflow(width, phi, theta, joinstyle='miter', capstyle='butt'):
12691277
form a corner, the interior angle swept out by the two lines that meet
12701278
at the vertex.
12711279
joinstyle : {'miter', 'bevel', 'round'}
1272-
How the corner is to be drawn.
1280+
How line corners are to be drawn.
12731281
capstyle : {'butt', 'round', 'projecting'}
12741282
How line ends are to be drawn.
12751283
12761284
Returns
12771285
-------
12781286
pad : float
12791287
Amount of bbox overflow.
1288+
1289+
Notes
1290+
-----
1291+
$\pi$ and 0 are equivalent for *theta*. Both $\phi$ and $\pi - \phi$
1292+
are equivalent for *phi* by symmetry.
1293+
1294+
If and only if `.VertexInfo.incidence_angle` is in :math:`[-\pi, \pi]`,
1295+
then *phi* corresponds to `.VertexInfo.incidence_angle`. *theta* always
1296+
corresponds to `.VertexInfo.corner_angle`.
12801297
"""
12811298
if theta is not None and (theta < 0 or theta > np.pi) \
12821299
or phi < 0 or phi > np.pi:
@@ -1309,16 +1326,16 @@ def _stroke_x_overflow(width, phi, theta, joinstyle='miter', capstyle='butt'):
13091326
else:
13101327
raise ValueError(f"Unknown capstyle: {capstyle}.")
13111328
# the two "same as straight line" cases are NaN limits in the miter formula
1312-
elif np.isclose(theta, 0) and np.isclose(phi, 0) \
1313-
or np.isclose(theta, np.pi) and np.isclose(phi, np.pi/2):
1329+
elif (np.isclose(theta, 0) and np.isclose(phi, 0)
1330+
or np.isclose(theta, np.pi) and np.isclose(phi, np.pi/2)):
13141331
return width/2
13151332
# to calculate the offset for _joinstyle == 'miter', imagine aligning the
13161333
# corner so that one line comes in along the negative x-axis, and another
13171334
# from above, making an angle $\theta$ with the negative x-axis. The tip of
13181335
# the new corner created by the markeredge stroke will be at the point
13191336
# where the two outer edge of the markeredge stroke intersect. in the
13201337
# orientation described above, the outer edge of the stroke aligned with
1321-
# the x axis will obviously have equation $y = -w/2$ where $w$ is the
1338+
# the x-axis will obviously have equation $y = -w/2$ where $w$ is the
13221339
# markeredgewidth. WLOG, the stroke coming in from above at an angle
13231340
# $\theta$ from the negative x-axis will have equation
13241341
# $$-(\tan(\theta) x + \frac{w}{2\cos(\theta)}.$$
@@ -1361,7 +1378,7 @@ def _pad_extents_stroked_vertex(extents, vinfo, markeredgewidth, joinstyle,
13611378
13621379
Parameters
13631380
----------
1364-
extents : 4*[float]
1381+
extents : (4,) array_like of float
13651382
The extents (xmin, ymin, xmax, ymax) of the `~.transforms.Bbox` of the
13661383
vertices. Modified in place so that the corner described by *vinfo*
13671384
fits into the extents when stroked with a width of *markeredgewidth*.
@@ -1370,13 +1387,13 @@ def _pad_extents_stroked_vertex(extents, vinfo, markeredgewidth, joinstyle,
13701387
markeredgewidth : `float`
13711388
The width of the stroke being drawn.
13721389
joinstyle : {'miter', 'bevel', 'round'}
1373-
How the corner is to be drawn.
1390+
How line corners are to be drawn.
13741391
capstyle : {'butt', 'round', 'projecting'}
13751392
How line ends are to be drawn.
13761393
13771394
Notes
13781395
-----
1379-
Implementing by wrapping `._stroke_x_overflow`. This function checks which
1396+
Implemented by wrapping `._stroke_x_overflow`. This function checks which
13801397
direction the corner (or cap) is pointing, then for each side of *extents*
13811398
that might need padding, it rotates the corner to point in the positive x
13821399
direction and calls `._stroke_x_overflow` to get the padding.

0 commit comments

Comments
 (0)