Skip to content

Commit 3c19b1f

Browse files
committed
DOCS: Centralize JoinStyle/CapStyle docs
1 parent 56f37c3 commit 3c19b1f

File tree

10 files changed

+168
-64
lines changed

10 files changed

+168
-64
lines changed

doc/_static/mpl.css

+18-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ table.highlighttable td {
8989
padding: 0 0.5em 0 0.5em;
9090
}
9191

92-
cite, code, tt {
92+
cite, code, tt, dl.value-list dt {
9393
font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
9494
font-size: 0.95em;
9595
letter-spacing: 0.01em;
@@ -730,7 +730,6 @@ td.field-body table.property-table tr:last-of-type td {
730730
border-bottom-color: #888;
731731
}
732732

733-
734733
/* function and class description */
735734
.descclassname {
736735
color: #aaa;
@@ -806,6 +805,22 @@ dl.class > dd {
806805
font-size: 14px;
807806
}
808807

808+
/* custom tables for lists of allowed values in "mpl._types" */
809+
dl.value-list {
810+
display: grid;
811+
}
812+
813+
dl.value-list dt {
814+
grid-column: 1;
815+
margin: 4px 0;
816+
}
817+
818+
dl.value-list dd {
819+
grid-column: 2;
820+
margin: 4px 0 4px 20px;
821+
padding: 0;
822+
}
823+
809824
/* parameter section table */
810825
table.docutils.field-list {
811826
width: 100%;
@@ -1257,4 +1272,4 @@ div.bullet-box li {
12571272

12581273
div#gallery.section .sphx-glr-clear:first-of-type, div#tutorials.section .sphx-glr-clear:first-of-type{
12591274
display: none;
1260-
}
1275+
}

doc/api/_types.rst

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33
**********************
44

55
.. automodule:: matplotlib._types
6-
:members:
7-
:undoc-members:
8-
:show-inheritance:
6+
:no-members:
7+
8+
.. autoclass:: JoinStyle
9+
:members: demo
10+
:exclude-members: bevel, miter, round, input_description
11+
12+
.. autoclass:: CapStyle
13+
:members: demo
14+
:exclude-members: butt, round, projecting, input_description
915

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
=========
3+
CapStyle
4+
=========
5+
6+
The `matplotlib._types.CapStyle` controls how Matplotlib draws the corners
7+
where two different line segments meet. For more details, see the
8+
`~matplotlib._types.CapStyle` docs.
9+
"""
10+
11+
import matplotlib.pyplot as plt
12+
from matplotlib._types import CapStyle
13+
14+
CapStyle.demo()
15+
plt.show()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
=========
3+
JoinStyle
4+
=========
5+
6+
The `matplotlib._types.JoinStyle` controls how Matplotlib draws the corners
7+
where two different line segments meet. For more details, see the
8+
`~matplotlib._types.JoinStyle` docs.
9+
"""
10+
11+
import matplotlib.pyplot as plt
12+
from matplotlib._types import JoinStyle
13+
14+
JoinStyle.demo()
15+
plt.show()

lib/matplotlib/_types.py

+77-39
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
"""
2-
Style description information that is shared across unrelated classses.
2+
Matplotlib API concepts that would not otherwise merit a dedicated class.
3+
4+
Matplotlib often uses simple data types like strings or tuples to define a
5+
concept; e.g. the line capstyle can be specified as one of 'butt', 'round',
6+
or 'projecting'. The classes in this module are used internally and serve to
7+
document these concepts formally.
8+
9+
As an end-user you will not use these classes directly, but only the values
10+
they define.
311
"""
412

513
from enum import Enum, auto
6-
from matplotlib import cbook
14+
from matplotlib import cbook, docstring
715

816

917
class _AutoStringNameEnum(Enum):
1018
"""Automate the ``name = 'name'`` part of making a (str, Enum)."""
19+
1120
def _generate_next_value_(name, start, count, last_values):
1221
return name
1322

23+
def __hash__(self):
24+
return str(self).__hash__()
25+
1426

1527
def _deprecate_case_insensitive_join_cap(s):
1628
s_low = s.lower()
@@ -34,13 +46,7 @@ class JoinStyle(str, _AutoStringNameEnum):
3446
Define how the connection between two line segments is drawn.
3547
3648
For a visual impression of each *JoinStyle*, `view these docs online
37-
<JoinStyle>`, or run `JoinStyle.demo`:
38-
39-
.. plot::
40-
:alt: Demo of possible JoinStyle's
41-
42-
from matplotlib._types import JoinStyle
43-
JoinStyle.demo()
49+
<JoinStyle>`, or run `JoinStyle.demo`.
4450
4551
Lines in Matplotlib are typically defined by a 1D `~.path.Path` and a
4652
finite ``linewidth``, where the underlying 1D `~.path.Path` represents the
@@ -52,32 +58,42 @@ class JoinStyle(str, _AutoStringNameEnum):
5258
results in corners appearing "rounded", which may not be the desired
5359
behavior if you are drawing, for example, a polygon or pointed star.
5460
55-
Matplotlib provides three options for drawing the corners between adjacent
56-
segments. In short:
61+
**Supported values:**
62+
63+
.. rst-class:: value-list
5764
58-
- *miter* is the "arrow-tip" style. Each boundary of the filled-in area
59-
will extend in a straight line parallel to the tangent vector of the
60-
centerline at the point it meets the corner, until they meet in a
61-
sharp point.
62-
- *round* stokes every point within a radius of ``linewidth/2`` of the
63-
center lines.
64-
- *bevel* is the "squared-off" style. It can be thought of as a rounded
65-
corner where the "circular" part of the corner has been cut off.
65+
'miter'
66+
the "arrow-tip" style. Each boundary of the filled-in area will
67+
extend in a straight line parallel to the tangent vector of the
68+
centerline at the point it meets the corner, until they meet in a
69+
sharp point.
70+
'round'
71+
stokes every point within a radius of ``linewidth/2`` of the center
72+
lines.
73+
'bevel'
74+
the "squared-off" style. It can be thought of as a rounded corner
75+
where the "circular" part of the corner has been cut off.
6676
6777
.. note::
6878
69-
The *miter* option can be controlled further by specifying a "miter
70-
limit", which specifies how long a miter tip can get before it is
71-
automatically "bevel"ed off. Matplotlib does not currently expose a
72-
``miterlimit`` parameter to the user, and most backends simply use the
73-
upstream default value. For example, the PDF backend assumes the
74-
default value of 10 specified by the PDF standard, while the SVG
75-
backend does not even specify the miter limit, resulting in a default
76-
value of 4 per the SVG specification.
79+
Very long miter tips are cut off (to form a *bevel*) after a
80+
backend-dependent limit called the "miter limit", which specifies the
81+
maximum allowed ratio of miter length to line width. For example, the
82+
PDF backend uses the default value of 10 specified by the PDF standard,
83+
while the SVG backend does not even specify the miter limit, resulting
84+
in a default value of 4 per the SVG specification. Matplotlib does not
85+
currently allow the user to adjust this parameter.
7786
7887
A more detailed description of the effect of a miter limit can be found
7988
in the `Mozilla Developer Docs
8089
<https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit>`_
90+
91+
.. plot::
92+
:alt: Demo of possible JoinStyle's
93+
94+
from matplotlib._types import JoinStyle
95+
JoinStyle.demo()
96+
8197
"""
8298

8399
miter = auto()
@@ -90,6 +106,7 @@ def __init__(self, s):
90106

91107
@staticmethod
92108
def demo():
109+
"""Demonstrate how each JoinStyle looks for various join angles."""
93110
import numpy as np
94111
import matplotlib.pyplot as plt
95112

@@ -101,7 +118,7 @@ def plot_angle(ax, x, y, angle, style):
101118
ax.plot(xx, yy, lw=1, color='black')
102119
ax.plot(xx[1], yy[1], 'o', color='tab:red', markersize=3)
103120

104-
fig, ax = plt.subplots(figsize=(8, 6))
121+
fig, ax = plt.subplots(figsize=(5, 4), constrained_layout=True)
105122
ax.set_title('Join style')
106123
for x, style in enumerate(['miter', 'round', 'bevel']):
107124
ax.text(x, 5, style)
@@ -115,6 +132,11 @@ def plot_angle(ax, x, y, angle, style):
115132
fig.show()
116133

117134

135+
JoinStyle.input_description = "{" \
136+
+ ", ".join([f"'{js.name}'" for js in JoinStyle]) \
137+
+ "}"
138+
139+
118140
class CapStyle(str, _AutoStringNameEnum):
119141
r"""
120142
Define how the two endpoints (caps) of an unclosed line are drawn.
@@ -125,21 +147,27 @@ class CapStyle(str, _AutoStringNameEnum):
125147
controlled by the *CapStyle*.
126148
127149
For a visual impression of each *CapStyle*, `view these docs online
128-
<CapStyle>` or run `CapStyle.demo`:
150+
<CapStyle>` or run `CapStyle.demo`.
151+
152+
**Supported values:**
153+
154+
.. rst-class:: value-list
155+
156+
'butt'
157+
the line is squared off at its endpoint.
158+
'projecting'
159+
the line is squared off as in *butt*, but the filled in area
160+
extends beyond the endpoint a distance of ``linewidth/2``.
161+
'round'
162+
like *butt*, but a semicircular cap is added to the end of the
163+
line, of radius ``linewidth/2``.
129164
130165
.. plot::
131166
:alt: Demo of possible CapStyle's
132167
133168
from matplotlib._types import CapStyle
134169
CapStyle.demo()
135170
136-
Available options:
137-
138-
- *butt*: the line is squared off at its endpoint.
139-
- *projecting*: the line is squared off as in *butt*, but the filled in
140-
area extends beyond the endpoint a distance of ``linewidth/2``.
141-
- *round*: like *butt*, but a semicircular cap is added to the end of
142-
the line, of radius ``linewidth/2``.
143171
"""
144172
butt = 'butt'
145173
projecting = 'projecting'
@@ -151,20 +179,30 @@ def __init__(self, s):
151179

152180
@staticmethod
153181
def demo():
182+
"""Demonstrate how each CapStyle looks for a thick line segment."""
154183
import matplotlib.pyplot as plt
155184

156-
fig, ax = plt.subplots(figsize=(8, 2))
185+
fig = plt.figure(figsize=(4, 1.2))
186+
ax = fig.add_axes([0, 0, 1, 0.8])
157187
ax.set_title('Cap style')
158188

159189
for x, style in enumerate(['butt', 'round', 'projecting']):
160-
ax.text(x+0.25, 1, style, ha='center')
190+
ax.text(x+0.25, 0.85, style, ha='center')
161191
xx = [x, x+0.5]
162192
yy = [0, 0]
163193
ax.plot(xx, yy, lw=12, color='tab:blue', solid_capstyle=style)
164194
ax.plot(xx, yy, lw=1, color='black')
165195
ax.plot(xx, yy, 'o', color='tab:red', markersize=3)
166-
ax.text(2.25, 0.7, '(default)', ha='center')
196+
ax.text(2.25, 0.55, '(default)', ha='center')
167197

168198
ax.set_ylim(-.5, 1.5)
169199
ax.set_axis_off()
170200
fig.show()
201+
202+
203+
CapStyle.input_description = "{" \
204+
+ ", ".join([f"'{cs.name}'" for cs in CapStyle]) \
205+
+ "}"
206+
207+
docstring.interpd.update({'JoinStyle': JoinStyle.input_description,
208+
'CapStyle': CapStyle.input_description})

lib/matplotlib/backend_bases.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444

4545
import matplotlib as mpl
4646
from matplotlib import (
47-
_api, backend_tools as tools, cbook, colors, textpath, tight_bbox,
48-
transforms, widgets, get_backend, is_interactive, rcParams)
47+
_api, backend_tools as tools, cbook, colors, docstring, textpath,
48+
tight_bbox, transforms, widgets, get_backend, is_interactive, rcParams)
4949
from matplotlib._pylab_helpers import Gcf
5050
from matplotlib.backend_managers import ToolManager
5151
from matplotlib.cbook import _setattr_cm
@@ -917,13 +917,14 @@ def set_antialiased(self, b):
917917
# Use ints to make life easier on extension code trying to read the gc.
918918
self._antialiased = int(bool(b))
919919

920+
@docstring.interpd
920921
def set_capstyle(self, cs):
921922
"""
922923
Set how to draw endpoints of lines.
923924
924925
Parameters
925926
----------
926-
cs : `.CapStyle` or {'butt', 'round', 'projecting'}
927+
cs : `.CapStyle` or %(CapStyle)s
927928
"""
928929
self._capstyle = CapStyle(cs)
929930

@@ -982,13 +983,14 @@ def set_foreground(self, fg, isRGBA=False):
982983
else:
983984
self._rgb = colors.to_rgba(fg)
984985

986+
@docstring.interpd
985987
def set_joinstyle(self, js):
986988
"""
987989
Set how to draw connections between line segments.
988990
989991
Parameters
990992
----------
991-
js : `.JoinStyle` or {'miter', 'round', 'bevel'}.
993+
js : `.JoinStyle` or %(JoinStyle)s
992994
"""
993995
self._joinstyle = JoinStyle(js)
994996

0 commit comments

Comments
 (0)