Description
In my investigation of image comparison fails with pytest and xdist plugin I have discovered strange behavior. By changing the extensions order of the image comparison tests you will receive different output (and of course test failures).
I made extensions shuffle like this and got these results. From the log you can see that mostly affected are legend tests on svg backend. So any baseline image from the tests with legend
call is spoiled by pdf backend, except the legend
+ tightbox
.
I tried to compare figure state before and after savefig
call but run into issue #6870.
Here is the way to reproduce the problem. You can compare output of the snippet with baseline images of matplotlib.tests.test_legend.test_legend_auto1
test, if you want.
# python savefig_sideeffects.py svg svg pdf svg
# diff -u 0.svg 1.svg
# diff -u 1.svg 3.svg
# SOURCE_DATE_EPOCH=0 python savefig_sideeffects.py pdf pdf svg pdf
import numpy as np
import matplotlib
matplotlib.use('agg')
import matplotlib.pylab as plt
# matplotlib.testing.decorators.ImageComparisonTest.remove_text
def remove_text(figure):
from matplotlib import ticker
figure.suptitle("")
for ax in figure.get_axes():
ax.set_title("")
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.xaxis.set_minor_formatter(ticker.NullFormatter())
ax.yaxis.set_major_formatter(ticker.NullFormatter())
ax.yaxis.set_minor_formatter(ticker.NullFormatter())
try:
ax.zaxis.set_major_formatter(ticker.NullFormatter())
ax.zaxis.set_minor_formatter(ticker.NullFormatter())
except AttributeError:
pass
# matplotlib.tests.test_legend.test_legend_auto1
def test_legend_auto1():
'Test automatic legend placement'
fig = plt.figure()
ax = fig.add_subplot(111)
x = np.arange(100)
ax.plot(x, 50 - x, 'o', label='y=1')
ax.plot(x, x - 50, 'o', label='y=-1')
ax.legend(loc=0)
return fig
def prepare():
import matplotlib.testing
matplotlib._init_tests()
# matplotlib.testing.decorators.ImageComparisonTest.setup_class
matplotlib.testing.setup()
matplotlib.style.use('classic')
matplotlib.testing.set_font_settings_for_testing()
fig = test_legend_auto1()
remove_text(fig)
return fig
def test(exts):
fig = prepare()
# this will stick svg path ids with the same values
matplotlib.rc('svg', hashsalt='asdf')
for p in enumerate(exts):
fig.savefig('%d.%s' % p)
if __name__ == '__main__':
import sys
test(sys.argv[1:])
This is the demonstration of the issue, where savefig
with pdf backend has sideeffect on the next savefig
with svg backend:
>python savefig_sideeffects.py svg svg pdf svg
>diff -u 0.svg 1.svg
>diff -u 1.svg 3.svg
--- 1.svg 2016-08-04 00:29:52.429050200 +0300
+++ 3.svg 2016-08-04 00:29:52.537061000 +0300
@@ -462,18 +462,18 @@
</g>
<g id="legend_1">
<g id="patch_7">
- <path d="M 424.413 239.2965
-L 511.2 239.2965
-L 511.2 192.7035
-L 424.413 192.7035
+ <path d="M 424.469375 239.25225
+L 511.2 239.25225
+L 511.2 192.74775
+L 424.469375 192.74775
z
" style="fill:#ffffff;stroke:#000000;stroke-linejoin:miter;"/>
</g>
<g id="line2d_29"/>
<g id="line2d_30">
<g>
- <use style="fill:#0000ff;stroke:#000000;stroke-width:0.5;" x="434.493" xlink:href="#mb9df33688a" y="204.36525"/>
- <use style="fill:#0000ff;stroke:#000000;stroke-width:0.5;" x="454.653" xlink:href="#mb9df33688a" y="204.36525"/>
+ <use style="fill:#0000ff;stroke:#000000;stroke-width:0.5;" x="434.549375" xlink:href="#mb9df33688a" y="204.4095"/>
+ <use style="fill:#0000ff;stroke:#000000;stroke-width:0.5;" x="454.709375" xlink:href="#mb9df33688a" y="204.4095"/>
</g>
</g>
<g id="text_1">
@@ -520,7 +520,7 @@
z
" id="DejaVuSans-31"/>
</defs>
- <g transform="translate(470.493 209.40525)scale(0.144 -0.144)">
+ <g transform="translate(470.549375 209.4495)scale(0.144 -0.144)">
<use xlink:href="#DejaVuSans-79"/>
<use x="59.179688" xlink:href="#DejaVuSans-3d"/>
<use x="142.96875" xlink:href="#DejaVuSans-31"/>
@@ -529,8 +529,8 @@
<g id="line2d_31"/>
<g id="line2d_32">
<g>
- <use style="fill:#008000;stroke:#000000;stroke-width:0.5;" x="434.493" xlink:href="#m3d71661f95" y="225.50175"/>
- <use style="fill:#008000;stroke:#000000;stroke-width:0.5;" x="454.653" xlink:href="#m3d71661f95" y="225.50175"/>
+ <use style="fill:#008000;stroke:#000000;stroke-width:0.5;" x="434.549375" xlink:href="#m3d71661f95" y="225.546"/>
+ <use style="fill:#008000;stroke:#000000;stroke-width:0.5;" x="454.709375" xlink:href="#m3d71661f95" y="225.546"/>
</g>
</g>
<g id="text_2">
@@ -543,7 +543,7 @@
z
" id="DejaVuSans-2d"/>
</defs>
- <g transform="translate(470.493 230.54175)scale(0.144 -0.144)">
+ <g transform="translate(470.549375 230.586)scale(0.144 -0.144)">
<use xlink:href="#DejaVuSans-79"/>
<use x="59.179688" xlink:href="#DejaVuSans-3d"/>
<use x="142.96875" xlink:href="#DejaVuSans-2d"/>
Same happens to pdf after svg.
By accident, while fixing issue #6870, it seems that I have fixed this too. Test above now passes but there are 505 SVG baseline images affected and need update. I will open PR for this soon.