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

Commitd0e7a36

Browse files
committed
Merge pull request#5671 from mdboom/deterministic-svg
Deterministic svg
2 parents0c64cd5 +dbb2029 commitd0e7a36

File tree

9 files changed

+79
-6
lines changed

9 files changed

+79
-6
lines changed

‎doc/api/backend_svg_api.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
:mod:`matplotlib.backends.backend_svg`
3+
======================================
4+
5+
..automodule::matplotlib.backends.backend_svg
6+
:members:
7+
:show-inheritance:

‎doc/api/index_backend_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ backends
1212
backend_qt5agg_api.rst
1313
backend_wxagg_api.rst
1414
backend_pdf_api.rst
15+
backend_svg_api.rst
1516
.. backend_webagg.rst
1617
dviread.rst
1718
type1font.rst

‎doc/users/whats_new/rcparams.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Added ``svg.hashsalt`` key to rcParams
2+
```````````````````````````````````````
3+
If ``svg.hashsalt`` is ``None`` (which it is by default), the svg backend uses ``uuid4`` to generate the hash salt.
4+
If it is not ``None``, it must be a string that is used as the hash salt instead of ``uuid4``.
5+
This allows for deterministic SVG output.

‎lib/matplotlib/axes/_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__import (absolute_import,division,print_function,
22
unicode_literals)
33

4+
fromcollectionsimportOrderedDict
5+
46
frommatplotlib.externalsimportsix
57
frommatplotlib.externals.six.movesimportxrange
68

7-
fromcollectionsimportOrderedDict
89
importitertools
910
importwarnings
1011
importmath
@@ -33,7 +34,6 @@
3334
importmatplotlib.imageasmimage
3435
frommatplotlib.offsetboximportOffsetBox
3536
frommatplotlib.artistimportallow_rasterization
36-
frommatplotlib.cbookimportiterable,index_of
3737
frommatplotlib.rcsetupimportcycler
3838

3939
rcParams=matplotlib.rcParams

‎lib/matplotlib/backends/backend_svg.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from __future__import (absolute_import,division,print_function,
22
unicode_literals)
33

4+
fromcollectionsimportOrderedDict
5+
46
frommatplotlib.externalsimportsix
57
frommatplotlib.externals.six.movesimportxrange
68
frommatplotlib.externals.siximportunichr
79

810
importos,base64,tempfile,gzip,io,sys,codecs,re
9-
fromcollectionsimportOrderedDict
1011

1112
importnumpyasnp
1213

@@ -316,7 +317,10 @@ def _write_default_style(self):
316317

317318
def_make_id(self,type,content):
318319
content=str(content)
319-
salt=str(uuid.uuid4())
320+
ifrcParams['svg.hashsalt']isNone:
321+
salt=str(uuid.uuid4())
322+
else:
323+
salt=rcParams['svg.hashsalt']
320324
ifsix.PY3:
321325
content=content.encode('utf8')
322326
salt=salt.encode('utf8')
@@ -840,7 +844,7 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
840844
ifrcParams['svg.image_inline']:
841845
bytesio=io.BytesIO()
842846
_png.write_png(np.array(im)[::-1],bytesio)
843-
oid=oidorself._make_id('image',bytesio)
847+
oid=oidorself._make_id('image',bytesio.getvalue())
844848
attrib['xlink:href']= (
845849
"data:image/png;base64,\n"+
846850
base64.b64encode(bytesio.getvalue()).decode('ascii'))

‎lib/matplotlib/rcsetup.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ def validate_float_or_None(s):
166166
raiseValueError('Could not convert "%s" to float or None'%s)
167167

168168

169+
defvalidate_string_or_None(s):
170+
"""convert s to string or raise"""
171+
ifsisNone:
172+
returnNone
173+
try:
174+
returnsix.text_type(s)
175+
exceptValueError:
176+
raiseValueError('Could not convert "%s" to string'%s)
177+
178+
169179
defvalidate_dpi(s):
170180
"""confirm s is string 'figure' or convert s to float or raise"""
171181
ifs=='figure':
@@ -1165,6 +1175,7 @@ def validate_hist_bins(s):
11651175
# True to save all characters as paths in the SVG
11661176
'svg.embed_char_paths': [True,deprecate_svg_embed_char_paths],
11671177
'svg.fonttype': ['path',validate_svg_fonttype],
1178+
'svg.hashsalt': [None,validate_string_or_None],
11681179

11691180
# set this when you want to generate hardcopy docstring
11701181
'docstring.hardcopy': [False,validate_bool],

‎lib/matplotlib/tests/test_backend_svg.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,48 @@ def test_bold_font_output_with_none_fonttype():
119119
ax.set_title('bold-title',fontweight='bold')
120120

121121

122+
def_test_determinism(filename):
123+
# This function is mostly copy&paste from "def test_visibility"
124+
# To require no GUI, we use Figure and FigureCanvasSVG
125+
# instead of plt.figure and fig.savefig
126+
frommatplotlib.figureimportFigure
127+
frommatplotlib.backends.backend_svgimportFigureCanvasSVG
128+
frommatplotlibimportrc
129+
rc('svg',hashsalt='asdf')
130+
131+
fig=Figure()
132+
ax=fig.add_subplot(111)
133+
134+
x=np.linspace(0,4*np.pi,50)
135+
y=np.sin(x)
136+
yerr=np.ones_like(y)
137+
138+
a,b,c=ax.errorbar(x,y,yerr=yerr,fmt='ko')
139+
forartistinb:
140+
artist.set_visible(False)
141+
142+
FigureCanvasSVG(fig).print_svg(filename)
143+
144+
145+
@cleanup
146+
deftest_determinism():
147+
importos
148+
importsys
149+
fromsubprocessimportcheck_call
150+
fromnose.toolsimportassert_equal
151+
plots= []
152+
foriinrange(3):
153+
check_call([sys.executable,'-R','-c',
154+
'from matplotlib.tests.test_backend_svg '
155+
'import _test_determinism;'
156+
'_test_determinism("determinism.svg")'])
157+
withopen('determinism.svg','rb')asfd:
158+
plots.append(fd.read())
159+
os.unlink('determinism.svg')
160+
forpinplots[1:]:
161+
assert_equal(p,plots[0])
162+
163+
122164
if__name__=='__main__':
123165
importnose
124166
nose.runmodule(argv=['-s','--with-doctest'],exit=False)

‎lib/matplotlib/textpath.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from __future__import (absolute_import,division,print_function,
44
unicode_literals)
55

6+
fromcollectionsimportOrderedDict
7+
68
frommatplotlib.externalsimportsix
79
frommatplotlib.externals.six.movesimportzip
810

@@ -20,7 +22,6 @@
2022
frommatplotlib.font_managerimportFontProperties,get_font
2123
frommatplotlib.transformsimportAffine2D
2224
frommatplotlib.externals.six.moves.urllib.parseimportquoteasurllib_quote
23-
fromcollectionsimportOrderedDict
2425

2526

2627
classTextToPath(object):

‎matplotlibrc.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,8 @@ backend : %(backend)s
505505
# 'path': Embed characters as paths -- supported by most SVG renderers
506506
# 'svgfont': Embed characters as SVG fonts -- supported only by Chrome,
507507
# Opera and Safari
508+
#svg.hashsalt : None # if not None, use this string as hash salt
509+
# instead of uuid4
508510

509511
# docstring params
510512
#docstring.hardcopy = False # set this when you want to generate hardcopy docstring

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp