Skip to content

Commit fca1464

Browse files
committed
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> Co-authored-by: AryanSheka
1 parent 32805b1 commit fca1464

24 files changed

Lines changed: 254 additions & 26 deletions
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
@@ -222,6 +222,7 @@ def __init__(self):
222222
self._gid = None
223223
self._snap = None
224224
self._sketch = mpl.rcParams['path.sketch']
225+
self._sketch_seed = mpl.rcParams['path.sketch_seed']
225226
self._path_effects = mpl.rcParams['path.effects']
226227
self._sticky_edges = _XYPair([], [])
227228
self._in_layout = True
@@ -713,7 +714,8 @@ def get_sketch_params(self):
713714
"""
714715
return self._sketch
715716

716-
def set_sketch_params(self, scale=None, length=None, randomness=None):
717+
def set_sketch_params(self, scale=None, length=None, randomness=None,
718+
seed=None):
717719
"""
718720
Set the sketch parameters.
719721
@@ -733,12 +735,21 @@ def set_sketch_params(self, scale=None, length=None, randomness=None):
733735
The PGF backend uses this argument as an RNG seed and not as
734736
described above. Using the same seed yields the same random shape.
735737
736-
.. ACCEPTS: (scale: float, length: float, randomness: float)
738+
seed : int, optional
739+
Seed for the internal pseudo-random number generator.
740+
741+
.. versionadded:: 3.8
742+
743+
.. ACCEPTS: (scale: float, length: float, randomness: float, seed: int)
737744
"""
745+
if seed is not None:
746+
self._sketch_seed = seed
747+
738748
if scale is None:
739749
self._sketch = None
740750
else:
741-
self._sketch = (scale, length or 128.0, randomness or 16.0)
751+
self._sketch = (scale, length or 128.0, randomness or 16.0,
752+
self._sketch_seed)
742753
self.stale = True
743754

744755
def set_path_effects(self, path_effects):

lib/matplotlib/artist.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ class Artist:
7777
def set_gid(self, gid: str | None) -> None: ...
7878
def get_snap(self) -> bool | None: ...
7979
def set_snap(self, snap: bool | None) -> None: ...
80-
def get_sketch_params(self) -> tuple[float, float, float] | None: ...
80+
def get_sketch_params(self) -> tuple[float, float, float, int] | None: ...
8181
def set_sketch_params(
8282
self,
8383
scale: float | None = ...,
8484
length: float | None = ...,
8585
randomness: float | None = ...,
86+
seed: int | None = ...,
8687
) -> None: ...
8788
def set_path_effects(self, path_effects: list[AbstractPathEffect]) -> None: ...
8889
def get_path_effects(self) -> list[AbstractPathEffect]: ...

lib/matplotlib/backend_bases.py

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

692692
return _setattr_cm(self, **no_ops)
693693

694+
@property
695+
def _seed_increment(self):
696+
"""
697+
seed increment for renderer.
698+
It is used to implement the rolling characteristic for seed
699+
"""
700+
self.__seed_increment += 1
701+
return self.__seed_increment
702+
703+
@_seed_increment.setter
704+
def _seed_increment(self, value):
705+
self.__seed_increment = value
706+
694707

695708
class GraphicsContextBase:
696709
"""An abstract base class that provides color, line styles, etc."""
@@ -1003,7 +1016,8 @@ def get_sketch_params(self):
10031016
"""
10041017
return self._sketch
10051018

1006-
def set_sketch_params(self, scale=None, length=None, randomness=None):
1019+
def set_sketch_params(self, scale=None, length=None, randomness=None,
1020+
seed=None):
10071021
"""
10081022
Set the sketch parameters.
10091023
@@ -1017,10 +1031,19 @@ def set_sketch_params(self, scale=None, length=None, randomness=None):
10171031
The length of the wiggle along the line, in pixels.
10181032
randomness : float, default: 16
10191033
The scale factor by which the length is shrunken or expanded.
1034+
seed : int, optional
1035+
Seed for the internal pseudo-random number generator.
1036+
1037+
.. versionadded:: 3.8
10201038
"""
1039+
10211040
self._sketch = (
10221041
None if scale is None
1023-
else (scale, length or 128., randomness or 16.))
1042+
else (scale,
1043+
length or rcParams['path.sketch'][1],
1044+
randomness or rcParams['path.sketch'][2],
1045+
seed or rcParams['path.sketch_seed'])
1046+
)
10241047

10251048

10261049
class TimerBase:

lib/matplotlib/backend_bases.pyi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ class RendererBase:
142142
def stop_rasterizing(self) -> None: ...
143143
def start_filter(self) -> None: ...
144144
def stop_filter(self, filter_func) -> None: ...
145+
@property
146+
def _seed_increment(self) -> int: ...
147+
@_seed_increment.setter
148+
def _seed_increment(self, value: int) -> None: ...
145149

146150
class GraphicsContextBase:
147151
def __init__(self) -> None: ...
@@ -187,6 +191,7 @@ class GraphicsContextBase:
187191
scale: float | None = ...,
188192
length: float | None = ...,
189193
randomness: float | None = ...,
194+
seed:int | None = ...,
190195
) -> None: ...
191196

192197
class TimerBase:

lib/matplotlib/backends/backend_pgf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ def _print_pgf_path(self, gc, path, transform, rgbFace=None):
598598
# and has a separate "scale" argument for the amplitude.
599599
# -> Use "randomness" as PRNG seed to allow the user to force the
600600
# same shape on multiple sketched lines
601-
scale, length, randomness = sketch_params
601+
scale, length, randomness, seed = sketch_params
602602
if scale is not None:
603603
# make matplotlib and PGF rendering visually similar
604604
length *= 0.5

lib/matplotlib/figure.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
Artist, allow_rasterization, _finalize_rasterization)
4343
from matplotlib.backend_bases import (
4444
DrawEvent, FigureCanvasBase, NonGuiException, MouseButton, _get_renderer)
45+
4546
import matplotlib._api as _api
4647
import matplotlib.cbook as cbook
4748
import matplotlib.colorbar as cbar
@@ -3263,6 +3264,7 @@ def draw(self, renderer):
32633264

32643265
artists = self._get_draw_artists(renderer)
32653266
try:
3267+
renderer._seed_increment = 0
32663268
renderer.open_group('figure', gid=self.get_gid())
32673269
if self.axes and self.get_layout_engine() is not None:
32683270
try:

lib/matplotlib/lines.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,8 @@ def draw(self, renderer):
838838
gc.set_foreground(ec_rgba, isRGBA=True)
839839
if self.get_sketch_params() is not None:
840840
scale, length, randomness = self.get_sketch_params()
841-
gc.set_sketch_params(scale/2, length/2, 2*randomness)
841+
seed = self._sketch_seed
842+
gc.set_sketch_params(scale/2, length/2, 2*randomness, seed)
842843

843844
marker = self._marker
844845

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@
714714
# - *randomness* is the factor by which the length is
715715
# randomly scaled.
716716
#path.effects:
717+
#path.sketch_seed: 0 # seed for the internal pseudo number generator.
717718

718719

719720
## ***************************************************************************

0 commit comments

Comments
 (0)