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
513from enum import Enum , auto
6- from matplotlib import cbook
14+ from matplotlib import cbook , docstring
715
816
917class _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
1527def _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+
118140class 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 })
0 commit comments