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

Commiteb546b4

Browse files
eudoxososcargus
authored andcommitted
Added path.sketch_seed to rcParams
Seed can be manually set for path.sketch by modifying the value of rcParams path.sketch_seed or by passing a seed value to xkcd or Artist.set_sketch . Seed will also have a rolling(auto incrementing) behaviour.Co-Authored-By: Oscar Gustafsson <8114497+oscargus@users.noreply.github.com>Co-Authored-By: eudoxos <1029876+eudoxos@users.noreply.github.com>
1 parent835220b commiteb546b4

25 files changed

+259
-28
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Seed for ``path.sketch`` will have a rolling (auto incrementing) behaviour
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The seed for the internal Pseudo number generator will now have an auto changing behavior.
5+
This means that the C code of every artist will get a different seed every time it is called
6+
and this will be done in a deterministic manner.
7+
8+
Two figures sketched with the same parameters and different seed will look different from one another.
9+
10+
``Artist.get_sketch_params()`` will now return a 4-tuple instead of a 3-tuple consisting of
11+
(scale, length, randomness, seed) of the form (float, float, float, int).
12+
13+
See 'What's new' on how to set a value to the seed and its behaviour.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
``sketch_seed`` parameter for rcParams
2+
--------------------------------------
3+
4+
`~matplotlib.rcParams` now has a new parameter ``path.sketch_seed``.
5+
Its default value is 0 and accepted values are any non negative integer.
6+
This allows the user to set the seed for the internal pseudo random number generator in one of three ways.
7+
8+
1) Directly changing the rcParam:
9+
10+
rcParams['path.sketch_seed'] = 20
11+
12+
2) Passing a value to the new *seed* parameter of `~matplotlib.pyplot.xkcd` function:
13+
14+
plt.xkcd(seed=20)
15+
16+
3) Passing a value to the new *seed* parameter of matplotlib.artist.set_sketch_params function:
17+
18+
ln = plt.plot(x, y)
19+
ln[0].set_sketch_params(seed = 20)
20+
21+
The seed will also have a changing characteristic for every artist which will be done in a deterministic manner.
22+
23+
24+
..plot::
25+
:include-source: true
26+
27+
import matplotlib.pyplot as plt
28+
from matplotlib import rcParams
29+
30+
with plt.xkcd():
31+
rcParams['path.sketch_seed']=0
32+
rcParams['path.sketch']=(2,120,40)
33+
pat,txt=plt.pie([10,20,30,40],wedgeprops={'edgecolor':'black'})
34+
plt.legend(pat,['first','second','third','fourth'],loc='best')
35+
plt.title("seed = 0")
36+
plt.show()
37+
38+
..plot::
39+
:include-source: true
40+
41+
import matplotlib.pyplot as plt
42+
from matplotlib import rcParams
43+
44+
fig, ax = plt.subplots()
45+
x = np.linspace(0.7, 1.42, 100)
46+
y = x ** 2
47+
ln = ax.plot(x, y, color='black')
48+
ln[0].set_sketch_params(100, 100, 20, 40)
49+
plt.title("seed = 40")
50+
plt.show()
51+
52+
..plot::
53+
:include-source: true
54+
55+
import matplotlib.pyplot as plt
56+
from matplotlib import rcParams
57+
58+
with plt.xkcd(seed=19680801):
59+
import matplotlib
60+
from matplotlib import gridspec
61+
62+
rcParams['path.sketch']=(2,120,40)
63+
64+
pat,txt=plt.pie([10,20,30,40],wedgeprops={'edgecolor':'black'})
65+
plt.legend(pat,['first','second','third','fourth'],loc='best')
66+
plt.title("seed = 19680801")
67+
plt.show()

‎lib/matplotlib/artist.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ def __init__(self):
209209
self._gid=None
210210
self._snap=None
211211
self._sketch=mpl.rcParams['path.sketch']
212+
self._sketch_seed=mpl.rcParams['path.sketch_seed']
212213
self._path_effects=mpl.rcParams['path.effects']
213214
self._sticky_edges=_XYPair([], [])
214215
self._in_layout=True
@@ -681,7 +682,8 @@ def get_sketch_params(self):
681682
"""
682683
returnself._sketch
683684

684-
defset_sketch_params(self,scale=None,length=None,randomness=None):
685+
defset_sketch_params(self,scale=None,length=None,randomness=None,
686+
seed=None):
685687
"""
686688
Set the sketch parameters.
687689
@@ -701,12 +703,21 @@ def set_sketch_params(self, scale=None, length=None, randomness=None):
701703
The PGF backend uses this argument as an RNG seed and not as
702704
described above. Using the same seed yields the same random shape.
703705
704-
.. ACCEPTS: (scale: float, length: float, randomness: float)
706+
seed : int, optional
707+
Seed for the internal pseudo-random number generator.
708+
709+
.. versionadded:: 3.8
710+
711+
.. ACCEPTS: (scale: float, length: float, randomness: float, seed: int)
705712
"""
713+
ifseedisnotNone:
714+
self._sketch_seed=seed
715+
706716
ifscaleisNone:
707717
self._sketch=None
708718
else:
709-
self._sketch= (scale,lengthor128.0,randomnessor16.0)
719+
self._sketch= (scale,lengthor128.0,randomnessor16.0,
720+
self._sketch_seed)
710721
self.stale=True
711722

712723
defset_path_effects(self,path_effects):

‎lib/matplotlib/artist.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,13 @@ class Artist:
7676
defset_gid(self,gid:str|None)->None: ...
7777
defget_snap(self)->bool|None: ...
7878
defset_snap(self,snap:bool|None)->None: ...
79-
defget_sketch_params(self)->tuple[float,float,float]|None: ...
79+
defget_sketch_params(self)->tuple[float,float,float,int]|None: ...
8080
defset_sketch_params(
8181
self,
8282
scale:float|None= ...,
8383
length:float|None= ...,
8484
randomness:float|None= ...,
85+
seed:int|None= ...,
8586
)->None: ...
8687
defset_path_effects(self,path_effects:list[AbstractPathEffect])->None: ...
8788
defget_path_effects(self)->list[AbstractPathEffect]: ...

‎lib/matplotlib/backend_bases.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,19 @@ def _draw_disabled(self):
754754

755755
return_setattr_cm(self,**no_ops)
756756

757+
@property
758+
def_seed_increment(self):
759+
"""
760+
seed increment for renderer.
761+
It is used to implement the rolling characteristic for seed
762+
"""
763+
self.__seed_increment+=1
764+
returnself.__seed_increment
765+
766+
@_seed_increment.setter
767+
def_seed_increment(self,value):
768+
self.__seed_increment=value
769+
757770

758771
classGraphicsContextBase:
759772
"""An abstract base class that provides color, line styles, etc."""
@@ -1062,7 +1075,8 @@ def get_sketch_params(self):
10621075
"""
10631076
returnself._sketch
10641077

1065-
defset_sketch_params(self,scale=None,length=None,randomness=None):
1078+
defset_sketch_params(self,scale=None,length=None,randomness=None,
1079+
seed=None):
10661080
"""
10671081
Set the sketch parameters.
10681082
@@ -1076,10 +1090,19 @@ def set_sketch_params(self, scale=None, length=None, randomness=None):
10761090
The length of the wiggle along the line, in pixels.
10771091
randomness : float, default: 16
10781092
The scale factor by which the length is shrunken or expanded.
1093+
seed : int, optional
1094+
Seed for the internal pseudo-random number generator.
1095+
1096+
.. versionadded:: 3.8
10791097
"""
1098+
10801099
self._sketch= (
10811100
NoneifscaleisNone
1082-
else (scale,lengthor128.,randomnessor16.))
1101+
else (scale,
1102+
lengthorrcParams['path.sketch'][1],
1103+
randomnessorrcParams['path.sketch'][2],
1104+
seedorrcParams['path.sketch_seed'])
1105+
)
10831106

10841107

10851108
classTimerBase:

‎lib/matplotlib/backend_bases.pyi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ class RendererBase:
136136
defstop_rasterizing(self)->None: ...
137137
defstart_filter(self)->None: ...
138138
defstop_filter(self,filter_func)->None: ...
139+
@property
140+
def_seed_increment(self)->int: ...
141+
@_seed_increment.setter
142+
def_seed_increment(self,value:int)->None: ...
139143

140144
classGraphicsContextBase:
141145
def__init__(self)->None: ...
@@ -180,6 +184,7 @@ class GraphicsContextBase:
180184
scale:float|None= ...,
181185
length:float|None= ...,
182186
randomness:float|None= ...,
187+
seed:int|None= ...,
183188
)->None: ...
184189

185190
classTimerBase:

‎lib/matplotlib/backends/backend_pgf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ def _print_pgf_path(self, gc, path, transform, rgbFace=None):
575575
# and has a separate "scale" argument for the amplitude.
576576
# -> Use "randomness" as PRNG seed to allow the user to force the
577577
# same shape on multiple sketched lines
578-
scale,length,randomness=sketch_params
578+
scale,length,randomness,seed=sketch_params
579579
ifscaleisnotNone:
580580
# make matplotlib and PGF rendering visually similar
581581
length*=0.5

‎lib/matplotlib/figure.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
Artist,allow_rasterization,_finalize_rasterization)
4646
frommatplotlib.backend_basesimport (
4747
DrawEvent,FigureCanvasBase,NonGuiException,MouseButton,_get_renderer)
48+
4849
importmatplotlib._apias_api
4950
importmatplotlib.cbookascbook
5051
importmatplotlib.colorbarascbar
@@ -3141,6 +3142,7 @@ def draw(self, renderer):
31413142

31423143
artists=self._get_draw_artists(renderer)
31433144
try:
3145+
renderer._seed_increment=0
31443146
renderer.open_group('figure',gid=self.get_gid())
31453147
ifself.axesandself.get_layout_engine()isnotNone:
31463148
try:

‎lib/matplotlib/lines.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,8 @@ def draw(self, renderer):
823823
gc.set_foreground(ec_rgba,isRGBA=True)
824824
ifself.get_sketch_params()isnotNone:
825825
scale,length,randomness=self.get_sketch_params()
826-
gc.set_sketch_params(scale/2,length/2,2*randomness)
826+
seed=self._sketch_seed
827+
gc.set_sketch_params(scale/2,length/2,2*randomness,seed)
827828

828829
marker=self._marker
829830

‎lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@
677677
# - *randomness* is the factor by which the length is
678678
# randomly scaled.
679679
#path.effects:
680+
#path.sketch_seed: 0 # seed for the internal pseudo number generator.
680681

681682

682683
## ***************************************************************************

‎lib/matplotlib/patches.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,9 @@ def _draw_paths_with_artist_properties(
563563
gc.set_hatch_color(self._hatch_color)
564564

565565
ifself.get_sketch_params()isnotNone:
566-
gc.set_sketch_params(*self.get_sketch_params())
566+
scale,length,randomness=self.get_sketch_params()
567+
gc.set_sketch_params(scale,length,randomness,
568+
self._sketch_seed+renderer._seed_increment)
567569

568570
ifself.get_path_effects():
569571
frommatplotlib.patheffectsimportPathEffectRenderer

‎lib/matplotlib/path.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,8 @@ def iter_segments(self, transform=None, remove_nans=True, clip=None,
382382
If True, curve segments will be returned as curve segments.
383383
If False, all curves will be converted to line segments.
384384
sketch : None or sequence, optional
385-
If not None, must be a3-tuple of the form
386-
(scale, length, randomness), representing the sketch parameters.
385+
If not None, must be a4-tuple of the form
386+
(scale, length, randomness, seed), representing the sketch parameters.
387387
"""
388388
ifnotlen(self):
389389
return

‎lib/matplotlib/path.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class Path:
6161
stroke_width:float= ...,
6262
simplify:bool|None= ...,
6363
curves:bool= ...,
64-
sketch:tuple[float,float,float]|None= ...,
64+
sketch:tuple[float,float,float,int]|None= ...,
6565
)->Generator[tuple[np.ndarray,np.uint8],None,None]: ...
6666
defiter_bezier(self,**kwargs)->Generator[BezierSegment,None,None]: ...
6767
defcleaned(
@@ -74,7 +74,7 @@ class Path:
7474
curves:bool= ...,
7575
stroke_width:float= ...,
7676
snap:bool|None= ...,
77-
sketch:tuple[float,float,float]|None= ...
77+
sketch:tuple[float,float,float,int]|None= ...
7878
)->Path: ...
7979
deftransformed(self,transform:Transform)->Path: ...
8080
defcontains_point(

‎lib/matplotlib/pyplot.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,8 @@ def setp(obj, *args, **kwargs):
701701

702702

703703
defxkcd(
704-
scale:float=1,length:float=100,randomness:float=2
705-
)->ExitStack:
704+
scale:float=1,length:float=100,randomness:float=2,
705+
seed:int|None=None)->ExitStack:
706706
"""
707707
Turn on `xkcd <https://xkcd.com/>`_ sketch-style drawing mode. This will
708708
only have effect on things drawn after this function is called.
@@ -718,6 +718,8 @@ def xkcd(
718718
The length of the wiggle along the line.
719719
randomness : float, optional
720720
The scale factor by which the length is shrunken or expanded.
721+
seed: int, optional
722+
Seed for the internal pseudo-random number generator.
721723
722724
Notes
723725
-----
@@ -738,6 +740,9 @@ def xkcd(
738740
# This cannot be implemented in terms of contextmanager() or rc_context()
739741
# because this needs to work as a non-contextmanager too.
740742

743+
ifseedisnotNone:
744+
rcParams['path.sketch_seed']=seed
745+
741746
ifrcParams['text.usetex']:
742747
raiseRuntimeError(
743748
"xkcd mode is not compatible with text.usetex = True")

‎lib/matplotlib/rcsetup.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,15 @@ def validate_sketch(s):
565565
raiseValueError("Expected a (scale, length, randomness) triplet")
566566

567567

568+
defvalidate_sketch_seed(s):
569+
s=validate_int(s)
570+
571+
ifs>=0:
572+
returns
573+
else:
574+
raiseValueError("seed must be a non negative integer")
575+
576+
568577
def_validate_greaterthan_minushalf(s):
569578
s=validate_float(s)
570579
ifs>-0.5:
@@ -1288,6 +1297,7 @@ def _convert_validator_spec(key, conv):
12881297
"path.simplify_threshold":_validate_greaterequal0_lessequal1,
12891298
"path.snap":validate_bool,
12901299
"path.sketch":validate_sketch,
1300+
"path.sketch_seed":validate_sketch_seed,
12911301
"path.effects":validate_anylist,
12921302
"agg.path.chunksize":validate_int,# 0 to disable chunking
12931303

‎lib/matplotlib/rcsetup.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def _validate_linestyle(s: Any) -> LineStyleType: ...
140140
defvalidate_markeverylist(s:Any)->list[MarkEveryType]: ...
141141
defvalidate_bbox(s:Any)->Literal["tight","standard"]|None: ...
142142
defvalidate_sketch(s:Any)->None|tuple[float,float,float]: ...
143+
defvalidate_sketch_seed(s:Any)->int: ...
143144
defvalidate_hatch(s:Any)->str: ...
144145
defvalidate_hatchlist(s:Any)->list[str]: ...
145146
defvalidate_dashlist(s:Any)->list[list[float]]: ...
Loading

‎lib/matplotlib/tests/test_backend_pgf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ def test_sketch_params():
384384
ax.set_yticks([])
385385
ax.set_frame_on(False)
386386
handle,=ax.plot([0,1])
387-
handle.set_sketch_params(scale=5,length=30,randomness=42)
387+
handle.set_sketch_params(scale=5,length=30,randomness=42,seed=0)
388388

389389
withBytesIO()asfd:
390390
fig.savefig(fd,format='pgf')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp