Skip to content

Commit

Permalink
Added docs about deterministic figures
Browse files Browse the repository at this point in the history
  • Loading branch information
astrofrog committed Mar 31, 2023
1 parent 28b171e commit 28c0a01
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
57 changes: 56 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ When generating a hash library, the tests will also be run as usual against the
existing hash library specified by ``--mpl-hash-library`` or the keyword argument.
However, generating baseline images will always result in the tests being skipped.


Hybrid Mode: Hashes and Images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -278,6 +277,62 @@ decorator:
This will make the test insensitive to changes in e.g. the freetype
library.

Supported formats and deterministic output
------------------------------------------

By default, pytest-mpl will save and compare figures in PNG format. However,
it is possible to set the format to use by setting e.g. ``savefig_kwargs={'format': 'pdf'}``
in ``mpl_image_compare``. Supported formats are ``'eps'``, ``'pdf'``, ``'png'``, and ``'svg'``.
Note that Ghostscript is required to be installed for comparing PDF and EPS figures, while
Inkscape is required for SVG comparison.

By default, Matplotlib does not produce deterministic output that will
have a consistent hash every time it is run, or over different Matplotlib versions.
In order to enforce that the output is deterministic, you will need to do the following:

PNG
^^^

For PNG files, the output can be made deterministic by setting::

@pytest.mark.mpl_image_compare(savefig_kwargs={'metadata': {"Software": None}})

PDF
^^^

For PDF files, the output can be made deterministic by setting::

@pytest.mark.mpl_image_compare(savefig_kwargs={'format': 'pdf',
'metadata': {"Creator": None,
"Producer": None,
"CreationDate": None}})

EPS
^^^

For PDF files, the output can be made deterministic by setting::

@pytest.mark.mpl_image_compare(savefig_kwargs={'format': 'pdf',
'metadata': {"Creator": "test"})

and in addition you will need to set the SOURCE_DATE_EPOCH environment variable to
a constant value (this is a unit timestamp)::

os.environ['SOURCE_DATE_EPOCH'] = '1680254601'

You could do this inside the test.

SVG
^^^

For SVG files, the output can be made deterministic by setting::

@pytest.mark.mpl_image_compare(savefig_kwargs={'metadata': '{"Date": None}})

and in addition, you should make sure the following rcParam is set to a constant string::

plt.rcParams['svg.hashsalt'] = 'test'

Test failure example
--------------------

Expand Down
4 changes: 2 additions & 2 deletions tests/baseline/hashes/mpl20_ft261.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test.test_modified": "54f6cf83d5b06fa2ecb7fa23d6e87898679178ef5d0dfdd2551a139f1932127b",
"test.test_new": "54f6cf83d5b06fa2ecb7fa23d6e87898679178ef5d0dfdd2551a139f1932127b",
"test.test_unmodified": "54f6cf83d5b06fa2ecb7fa23d6e87898679178ef5d0dfdd2551a139f1932127b",
"test_formats.test_format_eps": "da67357559501ff4afae72acede897d75d968ba0c4573dcd7ff992cfa72e49d4",
"test_formats.test_format_pdf": "9098ce368ec6e20951e9305fcb7da05a3f10169d270c84d8da3331371c6596bc",
"test_formats.test_format_eps": "396d67b9a51519a312903e817211abef713151225deeb6735cca6059ace3ca4e",
"test_formats.test_format_pdf": "a73ea1bd1a9edc68da280240a080c3b8ae11a3b1170d27f7229e95ba3019c098",
"test_formats.test_format_png": "480062c2239ed9d70e361d1a5b578dc2aa756971161ac6e7287b492ae6118c59"
}
2 changes: 1 addition & 1 deletion tests/test_pytest_mpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ def test_formats(pytester, use_hash_library, passes, file_format):
elif file_format == 'pdf':
metadata = '{"Creator": None, "Producer": None, "CreationDate": None}'
elif file_format == 'eps':
metadata = '{"Creator": None}'
metadata = '{"Creator": "test"}'
elif file_format == 'svg':
metadata = '{"Date": None}'

Expand Down

0 comments on commit 28c0a01

Please sign in to comment.