8000 `savefig` has sideeffects · Issue #6899 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
savefig has sideeffects #6899
Closed
Closed
@Kojoley

Description

@Kojoley

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
8F2D
.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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0