Title: `savefig` has sideeffects · Issue #6899 · matplotlib/matplotlib · GitHub
Open Graph Title: `savefig` has sideeffects · Issue #6899 · matplotlib/matplotlib
X Title: `savefig` has sideeffects · Issue #6899 · matplotlib/matplotlib
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)...
Open Graph 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 differ...
X 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 differ...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/6899
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"`savefig` has sideeffects","articleBody":"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).\n\nI made extensions shuffle [like this](https://github.com/Kojoley/matplotlib/commit/6a361eb144003cadef1372584ccfa3b11183c072) and got [these results](https://travis-ci.org/Kojoley/matplotlib/jobs/148677312). 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`.\n\nI tried to compare figure state before and after `savefig` call but run into issue #6870.\n\nHere 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.\n\n``` python\n# python savefig_sideeffects.py svg svg pdf svg\n# diff -u 0.svg 1.svg\n# diff -u 1.svg 3.svg\n# SOURCE_DATE_EPOCH=0 python savefig_sideeffects.py pdf pdf svg pdf\n\nimport numpy as np\nimport matplotlib\nmatplotlib.use('agg')\nimport matplotlib.pylab as plt\n\n\n# matplotlib.testing.decorators.ImageComparisonTest.remove_text\ndef remove_text(figure):\n from matplotlib import ticker\n figure.suptitle(\"\")\n for ax in figure.get_axes():\n ax.set_title(\"\")\n ax.xaxis.set_major_formatter(ticker.NullFormatter())\n ax.xaxis.set_minor_formatter(ticker.NullFormatter())\n ax.yaxis.set_major_formatter(ticker.NullFormatter())\n ax.yaxis.set_minor_formatter(ticker.NullFormatter())\n try:\n ax.zaxis.set_major_formatter(ticker.NullFormatter())\n ax.zaxis.set_minor_formatter(ticker.NullFormatter())\n except AttributeError:\n pass\n\n\n# matplotlib.tests.test_legend.test_legend_auto1\ndef test_legend_auto1():\n 'Test automatic legend placement'\n fig = plt.figure()\n ax = fig.add_subplot(111)\n x = np.arange(100)\n ax.plot(x, 50 - x, 'o', label='y=1')\n ax.plot(x, x - 50, 'o', label='y=-1')\n ax.legend(loc=0)\n return fig\n\n\ndef prepare():\n import matplotlib.testing\n matplotlib._init_tests()\n\n # matplotlib.testing.decorators.ImageComparisonTest.setup_class\n matplotlib.testing.setup()\n matplotlib.style.use('classic')\n matplotlib.testing.set_font_settings_for_testing()\n\n fig = test_legend_auto1()\n\n remove_text(fig)\n\n return fig\n\n\ndef test(exts):\n fig = prepare()\n\n # this will stick svg path ids with the same values\n matplotlib.rc('svg', hashsalt='asdf')\n\n for p in enumerate(exts):\n fig.savefig('%d.%s' % p)\n\n\nif __name__ == '__main__':\n import sys\n test(sys.argv[1:])\n```\n\nThis is the demonstration of the issue, where `savefig` with pdf backend has sideeffect on the next `savefig` with svg backend:\n\n``` patch\n\u003epython savefig_sideeffects.py svg svg pdf svg\n\n\u003ediff -u 0.svg 1.svg\n\n\u003ediff -u 1.svg 3.svg\n--- 1.svg 2016-08-04 00:29:52.429050200 +0300\n+++ 3.svg 2016-08-04 00:29:52.537061000 +0300\n@@ -462,18 +462,18 @@\n \u003c/g\u003e\n \u003cg id=\"legend_1\"\u003e\n \u003cg id=\"patch_7\"\u003e\n- \u003cpath d=\"M 424.413 239.2965\n-L 511.2 239.2965\n-L 511.2 192.7035\n-L 424.413 192.7035\n+ \u003cpath d=\"M 424.469375 239.25225\n+L 511.2 239.25225\n+L 511.2 192.74775\n+L 424.469375 192.74775\n z\n \" style=\"fill:#ffffff;stroke:#000000;stroke-linejoin:miter;\"/\u003e\n \u003c/g\u003e\n \u003cg id=\"line2d_29\"/\u003e\n \u003cg id=\"line2d_30\"\u003e\n \u003cg\u003e\n- \u003cuse style=\"fill:#0000ff;stroke:#000000;stroke-width:0.5;\" x=\"434.493\" xlink:href=\"#mb9df33688a\" y=\"204.36525\"/\u003e\n- \u003cuse style=\"fill:#0000ff;stroke:#000000;stroke-width:0.5;\" x=\"454.653\" xlink:href=\"#mb9df33688a\" y=\"204.36525\"/\u003e\n+ \u003cuse style=\"fill:#0000ff;stroke:#000000;stroke-width:0.5;\" x=\"434.549375\" xlink:href=\"#mb9df33688a\" y=\"204.4095\"/\u003e\n+ \u003cuse style=\"fill:#0000ff;stroke:#000000;stroke-width:0.5;\" x=\"454.709375\" xlink:href=\"#mb9df33688a\" y=\"204.4095\"/\u003e\n \u003c/g\u003e\n \u003c/g\u003e\n \u003cg id=\"text_1\"\u003e\n@@ -520,7 +520,7 @@\n z\n \" id=\"DejaVuSans-31\"/\u003e\n \u003c/defs\u003e\n- \u003cg transform=\"translate(470.493 209.40525)scale(0.144 -0.144)\"\u003e\n+ \u003cg transform=\"translate(470.549375 209.4495)scale(0.144 -0.144)\"\u003e\n \u003cuse xlink:href=\"#DejaVuSans-79\"/\u003e\n \u003cuse x=\"59.179688\" xlink:href=\"#DejaVuSans-3d\"/\u003e\n \u003cuse x=\"142.96875\" xlink:href=\"#DejaVuSans-31\"/\u003e\n@@ -529,8 +529,8 @@\n \u003cg id=\"line2d_31\"/\u003e\n \u003cg id=\"line2d_32\"\u003e\n \u003cg\u003e\n- \u003cuse style=\"fill:#008000;stroke:#000000;stroke-width:0.5;\" x=\"434.493\" xlink:href=\"#m3d71661f95\" y=\"225.50175\"/\u003e\n- \u003cuse style=\"fill:#008000;stroke:#000000;stroke-width:0.5;\" x=\"454.653\" xlink:href=\"#m3d71661f95\" y=\"225.50175\"/\u003e\n+ \u003cuse style=\"fill:#008000;stroke:#000000;stroke-width:0.5;\" x=\"434.549375\" xlink:href=\"#m3d71661f95\" y=\"225.546\"/\u003e\n+ \u003cuse style=\"fill:#008000;stroke:#000000;stroke-width:0.5;\" x=\"454.709375\" xlink:href=\"#m3d71661f95\" y=\"225.546\"/\u003e\n \u003c/g\u003e\n \u003c/g\u003e\n \u003cg id=\"text_2\"\u003e\n@@ -543,7 +543,7 @@\n z\n \" id=\"DejaVuSans-2d\"/\u003e\n \u003c/defs\u003e\n- \u003cg transform=\"translate(470.493 230.54175)scale(0.144 -0.144)\"\u003e\n+ \u003cg transform=\"translate(470.549375 230.586)scale(0.144 -0.144)\"\u003e\n \u003cuse xlink:href=\"#DejaVuSans-79\"/\u003e\n \u003cuse x=\"59.179688\" xlink:href=\"#DejaVuSans-3d\"/\u003e\n \u003cuse x=\"142.96875\" xlink:href=\"#DejaVuSans-2d\"/\u003e\n```\n\nSame happens to pdf after svg.\n\nBy 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.\n","author":{"url":"https://github.com/Kojoley","@type":"Person","name":"Kojoley"},"datePublished":"2016-08-03T22:41:48.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/6899/matplotlib/issues/6899"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:275daab3-73c2-4cb0-bca6-bb66126e1fcf |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8B5A:FA8B5:119324:17F245:6A523968 |
| html-safe-nonce | 8087db9ba3bff007ad0ab03ebb09fde2ba1edf7cded5d48352beb14ea6c2c8ed |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4QjVBOkZBOEI1OjExOTMyNDoxN0YyNDU6NkE1MjM5NjgiLCJ2aXNpdG9yX2lkIjoiMzc2NDcyODgyMDMxMTE0NDgwOCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | dfd8f9fc965494c826c314ade031fab8f4e6b1137f93f7b7c73cc08cf4d90b76 |
| hovercard-subject-tag | issue:169251598 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/matplotlib/matplotlib/6899/issue_layout |
| twitter:image | https://opengraph.githubassets.com/cdcc6fca043b20cef976aaff695d65610eaa75bcab5d5d1aab230d4a85fb1727/matplotlib/matplotlib/issues/6899 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/cdcc6fca043b20cef976aaff695d65610eaa75bcab5d5d1aab230d4a85fb1727/matplotlib/matplotlib/issues/6899 |
| og:image:alt | 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 differ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Kojoley |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/matplotlib/matplotlib git https://github.com/matplotlib/matplotlib.git |
| octolytics-dimension-user_id | 215947 |
| octolytics-dimension-user_login | matplotlib |
| octolytics-dimension-repository_id | 1385122 |
| octolytics-dimension-repository_nwo | matplotlib/matplotlib |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1385122 |
| octolytics-dimension-repository_network_root_nwo | matplotlib/matplotlib |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7aed05249554b889eb33d002851a973eebcc7e91 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width