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

Commitdd34f72

Browse files
committed
REORG: JoinStyle and CapStyle classes
Centralize docs and validation for JoinStyle and CapStyle in one place.
1 parentc5ab728 commitdd34f72

16 files changed

+331
-147
lines changed

‎doc/api/_types.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
**********************
2+
``matplotlib._types``
3+
**********************
4+
5+
..automodule::matplotlib._types
6+
:members:
7+
:undoc-members:
8+
:show-inheritance:
9+

‎doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ Matplotlib consists of the following submodules:
123123
transformations.rst
124124
tri_api.rst
125125
type1font.rst
126+
_types.rst
126127
units_api.rst
127128
widgets_api.rst
128129

‎lib/matplotlib/_types.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
"""
2+
Style desription information that is shared across unrelated classses.
3+
"""
4+
5+
fromenumimportEnum
6+
frommatplotlibimportcbook
7+
8+
9+
def_deprecate_case_insensitive_join_cap(s):
10+
s_low=s.lower()
11+
ifs!=s_low:
12+
ifs_lowin ['miter','round','bevel']:
13+
cbook.warn_deprecated(
14+
"3.3",message="Case-insensitive capstyles are deprecated "
15+
"since %(since)s and support for them will be removed "
16+
"%(removal)s; please pass them in lowercase.")
17+
elifs_lowin ['butt','round','projecting']:
18+
cbook.warn_deprecated(
19+
"3.3",message="Case-insensitive joinstyles are deprecated "
20+
"since %(since)s and support for them will be removed "
21+
"%(removal)s; please pass them in lowercase.")
22+
# Else, error out at the check_in_list stage.
23+
returns_low
24+
25+
26+
classJoinStyle(Enum):
27+
"""
28+
Define how the connection between two line segments is drawn.
29+
30+
For a simple visual description of each *JoinStyle*, `view these docs
31+
online <JoinStyle>`, or simply run `JoinStyle.demo`.
32+
33+
.. plot::
34+
:alt: Demo of possible JoinStyle's
35+
36+
from matplotlib._types import JoinStyle
37+
JoinStyle.demo()
38+
39+
For a more precise description, we first recall that lines in Matplotlib
40+
are typically defined by a 1D `~.path.Path` and a finite ``linewidth``,
41+
where the underlying 1D `~.path.Path` represents the center of the stroked
42+
line.
43+
44+
By default, `~.backend_bases.GraphicsContextBase` defines the boundaries of
45+
a stroked line to simply be every point within some radius,
46+
``linewidth/2``, away from any point of the center line. However, this
47+
results in corners appearing "rounded", which may not be the desired
48+
behavior if you are drawing, for example, a polygon or pointed star.
49+
50+
Matplotlib provides three options for defining how the corners where two
51+
segments meet should be drawn. In short:
52+
53+
- *miter* is the "arrow-tip" style. Each boundary of the filled-in area
54+
will extend in a straight line parallel to the tangent vector of the
55+
centerline at the point it meets the corner, until they meet in a
56+
sharp point.
57+
- *round* stokes every point within a radius of ``linewidth/2`` of the
58+
center lines.
59+
- *bevel* is the "squared-off" style. It can be thought of as a rounded
60+
corner where the "circular" part of the corner has been cut off.
61+
62+
.. note::
63+
64+
The *miter* option can be controller further by specifying a "miter
65+
limit", which specifies how long a miter tip can get before it is
66+
automatically "bevel"ed off. Matplotlib does not currently expose a
67+
``miterlimit`` parameter to the user, and most backends simply use the
68+
upstream default value. For example, the PDF backend assumes the
69+
default value of 10 specified by the PDF standard, while the SVG
70+
backend does not even specify the miter limit, resulting in a default
71+
value of 4 per the SVG specification.
72+
73+
A more detailed description of the effect of a miter limit can be found
74+
in the `Mozilla Developer Docs
75+
<https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit>`_
76+
"""
77+
78+
miter='miter'
79+
round='round'
80+
bevel='bevel'
81+
82+
def__init__(self,s):
83+
s=_deprecate_case_insensitive_join_cap(s)
84+
Enum.__init__(self)
85+
86+
@staticmethod
87+
defdemo():
88+
importnumpyasnp
89+
importmatplotlib.pyplotasplt
90+
91+
defplot_angle(ax,x,y,angle,style):
92+
phi=np.radians(angle)
93+
xx= [x+.5,x,x+.5*np.cos(phi)]
94+
yy= [y,y,y+.5*np.sin(phi)]
95+
ax.plot(xx,yy,lw=12,color='tab:blue',solid_joinstyle=style)
96+
ax.plot(xx,yy,lw=1,color='black')
97+
ax.plot(xx[1],yy[1],'o',color='tab:red',markersize=3)
98+
99+
fig,ax=plt.subplots(figsize=(8,6))
100+
ax.set_title('Join style')
101+
forx,styleinenumerate(['miter','round','bevel']):
102+
ax.text(x,5,style)
103+
fory,angleinenumerate([20,45,60,90,120]):
104+
plot_angle(ax,x,y,angle,style)
105+
ifx==0:
106+
ax.text(-1.3,y,f'{angle} degrees')
107+
ax.set_xlim(-1.5,2.75)
108+
ax.set_ylim(-.5,5.5)
109+
ax.set_axis_off()
110+
111+
plt.show()
112+
113+
114+
classCapStyle(Enum):
115+
"""
116+
Define how the the end of a line is drawn.
117+
118+
How to draw the start and end points of lines that represent a closed curve
119+
(i.e. that end in a `~.path.Path.CLOSEPOLY`) is controlled by the line's
120+
`JoinStyle`. For all other lines, how the start and end points are drawn is
121+
controlled by the *CapStyle*.
122+
123+
For a simple visual description of each *CapStyle*, `view these docs
124+
online <CapStyle>` or simply run `CapStyle.demo`.
125+
126+
.. plot::
127+
:alt: Demo of possible CapStyle's
128+
129+
from matplotlib._types import CapStyle
130+
CapStyle.demo()
131+
132+
Briefly, the three options available are:
133+
134+
- *butt*: the line is squared off at its endpoint.
135+
- *projecting*: the line is squared off as in *butt*, but the filled in
136+
area extends beyond the endpoint a distance of ``linewidth/2``.
137+
- *round*: like *butt*, but a semicircular cap is added to the end of
138+
the line, of radius ``linewidth/2``.
139+
"""
140+
butt='butt'
141+
projecting='projecting'
142+
round='round'
143+
144+
def__init__(self,s):
145+
s=_deprecate_case_insensitive_join_cap(s)
146+
Enum.__init__(self)
147+
148+
@staticmethod
149+
defdemo():
150+
importmatplotlib.pyplotasplt
151+
152+
fig,ax=plt.subplots(figsize=(8,2))
153+
ax.set_title('Cap style')
154+
155+
forx,styleinenumerate(['butt','round','projecting']):
156+
ax.text(x+0.25,1,style,ha='center')
157+
xx= [x,x+0.5]
158+
yy= [0,0]
159+
ax.plot(xx,yy,lw=12,color='tab:blue',solid_capstyle=style)
160+
ax.plot(xx,yy,lw=1,color='black')
161+
ax.plot(xx,yy,'o',color='tab:red',markersize=3)
162+
ax.text(2.25,0.7,'(default)',ha='center')
163+
164+
ax.set_ylim(-.5,1.5)
165+
ax.set_axis_off()

‎lib/matplotlib/backend_bases.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@
4949
frommatplotlib.backend_managersimportToolManager
5050
frommatplotlib.cbookimport_setattr_cm
5151
frommatplotlib.pathimportPath
52-
frommatplotlib.rcsetupimportvalidate_joinstyle,validate_capstyle
5352
frommatplotlib.transformsimportAffine2D
53+
frommatplotlib._typesimportJoinStyle,CapStyle
5454

5555

5656
_log=logging.getLogger(__name__)
@@ -764,11 +764,11 @@ def __init__(self):
764764
self._alpha=1.0
765765
self._forced_alpha=False# if True, _alpha overrides A from RGBA
766766
self._antialiased=1# use 0, 1 not True, False for extension code
767-
self._capstyle='butt'
767+
self._capstyle=CapStyle('butt')
768768
self._cliprect=None
769769
self._clippath=None
770770
self._dashes=0,None
771-
self._joinstyle='round'
771+
self._joinstyle=JoinStyle('round')
772772
self._linestyle='solid'
773773
self._linewidth=1
774774
self._rgb= (0.0,0.0,0.0,1.0)
@@ -820,7 +820,7 @@ def get_antialiased(self):
820820

821821
defget_capstyle(self):
822822
"""
823-
Return thecapstyle as a string in ('butt', 'round', 'projecting').
823+
Return thedefault `.CapStyle`.
824824
"""
825825
returnself._capstyle
826826

@@ -866,7 +866,7 @@ def get_forced_alpha(self):
866866
returnself._forced_alpha
867867

868868
defget_joinstyle(self):
869-
"""Return theline join style as one of ('miter', 'round', 'bevel')."""
869+
"""Return the`.JoinStyle`."""
870870
returnself._joinstyle
871871

872872
defget_linewidth(self):
@@ -919,9 +919,15 @@ def set_antialiased(self, b):
919919
self._antialiased=int(bool(b))
920920

921921
defset_capstyle(self,cs):
922-
"""Set the capstyle to be one of ('butt', 'round', 'projecting')."""
923-
validate_capstyle(cs)
924-
self._capstyle=cs
922+
"""
923+
Set the `.CapStyle`.
924+
925+
Parameters
926+
----------
927+
cs : `.CapStyle` or {'butt', 'round', 'projecting'}
928+
How to draw end points of lines.
929+
"""
930+
self._capstyle=CapStyle(cs)
925931

926932
defset_clip_rectangle(self,rectangle):
927933
"""
@@ -987,9 +993,14 @@ def set_foreground(self, fg, isRGBA=False):
987993
self._rgb=colors.to_rgba(fg)
988994

989995
defset_joinstyle(self,js):
990-
"""Set the join style to be one of ('miter', 'round', 'bevel')."""
991-
validate_joinstyle(js)
992-
self._joinstyle=js
996+
"""
997+
Set the `.JoinStyle`.
998+
999+
Parameters
1000+
----------
1001+
js : `.JoinStyle` or {'miter', 'round', 'bevel'}.
1002+
"""
1003+
self._joinstyle=JoinStyle(js)
9931004

9941005
defset_linewidth(self,w):
9951006
"""Set the linewidth in points."""

‎lib/matplotlib/backends/backend_pdf.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,23 @@
2626
importmatplotlibasmpl
2727
frommatplotlibimport_text_layout,cbook
2828
frommatplotlib._pylab_helpersimportGcf
29+
frommatplotlib.afmimportAFM
2930
frommatplotlib.backend_basesimport (
3031
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
3132
GraphicsContextBase,RendererBase)
3233
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
34+
frommatplotlib.datesimportUTC
35+
importmatplotlib.dvireadasdviread
3336
frommatplotlib.figureimportFigure
3437
frommatplotlib.font_managerimportfindfont,is_opentype_cff_font,get_font
35-
frommatplotlib.afmimportAFM
36-
importmatplotlib.type1fontastype1font
37-
importmatplotlib.dvireadasdviread
3838
frommatplotlib.ft2fontimport (FIXED_WIDTH,ITALIC,LOAD_NO_SCALE,
3939
LOAD_NO_HINTING,KERNING_UNFITTED)
4040
frommatplotlib.mathtextimportMathTextParser
41-
frommatplotlib.transformsimportAffine2D,BboxBase
42-
frommatplotlib.pathimportPath
43-
frommatplotlib.datesimportUTC
4441
frommatplotlibimport_path
42+
frommatplotlib.pathimportPath
43+
frommatplotlib._typesimportJoinStyle,CapStyle
44+
importmatplotlib.type1fontastype1font
45+
frommatplotlib.transformsimportAffine2D,BboxBase
4546
from .import_backend_pdf_ps
4647

4748
_log=logging.getLogger(__name__)
@@ -738,7 +739,8 @@ def newPage(self, width, height):
738739
self.reserveObject('length of content stream'))
739740
# Initialize the pdf graphics state to match the default mpl
740741
# graphics context: currently only the join style needs to be set
741-
self.output(GraphicsContextPdf.joinstyles['round'],Op.setlinejoin)
742+
self.output(GraphicsContextPdf.joinstyles[JoinStyle.round],
743+
Op.setlinejoin)
742744

743745
# Clear the list of annotations for the next page
744746
self.pageAnnotations= []
@@ -2377,8 +2379,8 @@ def paint(self):
23772379
"""
23782380
returnOp.paint_path(self.fill(),self.stroke())
23792381

2380-
capstyles= {'butt':0,'round':1,'projecting':2}
2381-
joinstyles= {'miter':0,'round':1,'bevel':2}
2382+
capstyles= {CapStyle.butt:0,CapStyle.round:1,CapStyle.projecting:2}
2383+
joinstyles= {JoinStyle.miter:0,JoinStyle.round:1,JoinStyle.bevel:2}
23822384

23832385
defcapstyle_cmd(self,style):
23842386
return [self.capstyles[style],Op.setlinecap]

‎lib/matplotlib/backends/backend_pgf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,13 @@ def _print_pgf_path_styles(self, gc, rgbFace):
534534
capstyles= {"butt":r"\pgfsetbuttcap",
535535
"round":r"\pgfsetroundcap",
536536
"projecting":r"\pgfsetrectcap"}
537-
writeln(self.fh,capstyles[gc.get_capstyle()])
537+
writeln(self.fh,capstyles[gc.get_capstyle().name])
538538

539539
# join style
540540
joinstyles= {"miter":r"\pgfsetmiterjoin",
541541
"round":r"\pgfsetroundjoin",
542542
"bevel":r"\pgfsetbeveljoin"}
543-
writeln(self.fh,joinstyles[gc.get_joinstyle()])
543+
writeln(self.fh,joinstyles[gc.get_joinstyle().name])
544544

545545
# filling
546546
has_fill=rgbFaceisnotNone

‎lib/matplotlib/backends/backend_ps.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@
2424
frommatplotlib.backend_basesimport (
2525
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
2626
GraphicsContextBase,RendererBase)
27+
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
2728
frommatplotlib.cbookimportis_writable_file_like,file_requires_unicode
2829
frommatplotlib.font_managerimportis_opentype_cff_font,get_font
2930
frommatplotlib.ft2fontimportLOAD_NO_HINTING
3031
frommatplotlib._ttconvimportconvert_ttf_to_ps
3132
frommatplotlib.mathtextimportMathTextParser
3233
frommatplotlib._mathtext_dataimportuni2type1
3334
frommatplotlib.pathimportPath
35+
frommatplotlib._typesimportJoinStyle,CapStyle
3436
frommatplotlib.texmanagerimportTexManager
3537
frommatplotlib.transformsimportAffine2D
36-
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
3738
from .import_backend_pdf_ps
3839

3940
_log=logging.getLogger(__name__)
@@ -760,11 +761,16 @@ def _is_transparent(rgb_or_rgba):
760761

761762

762763
classGraphicsContextPS(GraphicsContextBase):
764+
765+
_capstyles= {CapStyle.butt:0,CapStyle.round:1,CapStyle.projecting:2}
766+
763767
defget_capstyle(self):
764-
return {'butt':0,'round':1,'projecting':2}[super().get_capstyle()]
768+
returnself._capstyles[super().get_capstyle()]
769+
770+
_joinstyles= {JoinStyle.miter:0,JoinStyle.round:1,JoinStyle.bevel:2}
765771

766772
defget_joinstyle(self):
767-
return{'miter':0,'round':1,'bevel':2}[super().get_joinstyle()]
773+
returnself._joinstyles[super().get_joinstyle()]
768774

769775

770776
class_Orientation(Enum):

‎lib/matplotlib/backends/backend_svg.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
frommatplotlib.pathimportPath
2828
frommatplotlibimport_path
2929
frommatplotlib.transformsimportAffine2D,Affine2DBase
30+
frommatplotlib._typesimportJoinStyle,CapStyle
3031

3132
_log=logging.getLogger(__name__)
3233

@@ -571,10 +572,10 @@ def _get_style_dict(self, gc, rgbFace):
571572
attrib['stroke-opacity']=short_float_fmt(rgb[3])
572573
iflinewidth!=1.0:
573574
attrib['stroke-width']=short_float_fmt(linewidth)
574-
ifgc.get_joinstyle()!='round':
575-
attrib['stroke-linejoin']=gc.get_joinstyle()
576-
ifgc.get_capstyle()!='butt':
577-
attrib['stroke-linecap']=_capstyle_d[gc.get_capstyle()]
575+
ifgc.get_joinstyle()!=JoinStyle.round:
576+
attrib['stroke-linejoin']=gc.get_joinstyle().name
577+
ifgc.get_capstyle()!=CapStyle.butt:
578+
attrib['stroke-linecap']=_capstyle_d[gc.get_capstyle().name]
578579

579580
returnattrib
580581

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp