144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
import io
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import tempfile
|
|
import warnings
|
|
|
|
import pytest
|
|
|
|
import matplotlib as mpl
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib import cbook, patheffects
|
|
from matplotlib.testing.decorators import image_comparison
|
|
from matplotlib.testing.determinism import (_determinism_source_date_epoch,
|
|
_determinism_check)
|
|
|
|
|
|
with warnings.catch_warnings():
|
|
warnings.simplefilter('ignore')
|
|
needs_ghostscript = pytest.mark.skipif(
|
|
"eps" not in mpl.testing.compare.converter,
|
|
reason="This test needs a ghostscript installation")
|
|
needs_usetex = pytest.mark.skipif(
|
|
not mpl.checkdep_usetex(True),
|
|
reason="This test needs a TeX installation")
|
|
|
|
|
|
# This tests tends to hit a TeX cache lock on AppVeyor.
|
|
@pytest.mark.flaky(reruns=3)
|
|
@pytest.mark.parametrize('format, use_log, rcParams', [
|
|
('ps', False, {}),
|
|
pytest.param('ps', False, {'ps.usedistiller': 'ghostscript'},
|
|
marks=needs_ghostscript),
|
|
pytest.param('ps', False, {'text.usetex': True},
|
|
marks=[needs_ghostscript, needs_usetex]),
|
|
('eps', False, {}),
|
|
('eps', True, {'ps.useafm': True}),
|
|
pytest.param('eps', False, {'text.usetex': True},
|
|
marks=[needs_ghostscript, needs_usetex]),
|
|
], ids=[
|
|
'ps',
|
|
'ps with distiller',
|
|
'ps with usetex',
|
|
'eps',
|
|
'eps afm',
|
|
'eps with usetex'
|
|
])
|
|
def test_savefig_to_stringio(format, use_log, rcParams):
|
|
mpl.rcParams.update(rcParams)
|
|
|
|
fig, ax = plt.subplots()
|
|
|
|
with io.StringIO() as s_buf, io.BytesIO() as b_buf:
|
|
|
|
if use_log:
|
|
ax.set_yscale('log')
|
|
|
|
ax.plot([1, 2], [1, 2])
|
|
ax.set_title("Déjà vu")
|
|
fig.savefig(s_buf, format=format)
|
|
fig.savefig(b_buf, format=format)
|
|
|
|
s_val = s_buf.getvalue().encode('ascii')
|
|
b_val = b_buf.getvalue()
|
|
|
|
# Remove comments from the output. This includes things that could
|
|
# change from run to run, such as the time.
|
|
s_val, b_val = [re.sub(b'%%.*?\n', b'', x) for x in [s_val, b_val]]
|
|
|
|
assert s_val == b_val.replace(b'\r\n', b'\n')
|
|
|
|
|
|
def test_patheffects():
|
|
with mpl.rc_context():
|
|
mpl.rcParams['path.effects'] = [
|
|
patheffects.withStroke(linewidth=4, foreground='w')]
|
|
fig, ax = plt.subplots()
|
|
ax.plot([1, 2, 3])
|
|
with io.BytesIO() as ps:
|
|
fig.savefig(ps, format='ps')
|
|
|
|
|
|
@needs_usetex
|
|
@needs_ghostscript
|
|
def test_tilde_in_tempfilename(tmpdir):
|
|
# Tilde ~ in the tempdir path (e.g. TMPDIR, TMP or TEMP on windows
|
|
# when the username is very long and windows uses a short name) breaks
|
|
# latex before https://github.com/matplotlib/matplotlib/pull/5928
|
|
base_tempdir = Path(str(tmpdir), "short-1")
|
|
base_tempdir.mkdir()
|
|
# Change the path for new tempdirs, which is used internally by the ps
|
|
# backend to write a file.
|
|
with cbook._setattr_cm(tempfile, tempdir=str(base_tempdir)):
|
|
# usetex results in the latex call, which does not like the ~
|
|
plt.rc('text', usetex=True)
|
|
plt.plot([1, 2, 3, 4])
|
|
plt.xlabel(r'\textbf{time} (s)')
|
|
output_eps = os.path.join(str(base_tempdir), 'tex_demo.eps')
|
|
# use the PS backend to write the file...
|
|
plt.savefig(output_eps, format="ps")
|
|
|
|
|
|
def test_source_date_epoch():
|
|
"""Test SOURCE_DATE_EPOCH support for PS output"""
|
|
# SOURCE_DATE_EPOCH support is not tested with text.usetex,
|
|
# because the produced timestamp comes from ghostscript:
|
|
# %%CreationDate: D:20000101000000Z00\'00\', and this could change
|
|
# with another ghostscript version.
|
|
_determinism_source_date_epoch(
|
|
"ps", b"%%CreationDate: Sat Jan 01 00:00:00 2000")
|
|
|
|
|
|
def test_determinism_all():
|
|
"""Test for reproducible PS output"""
|
|
_determinism_check(format="ps")
|
|
|
|
|
|
@needs_usetex
|
|
@needs_ghostscript
|
|
def test_determinism_all_tex():
|
|
"""Test for reproducible PS/tex output"""
|
|
_determinism_check(format="ps", usetex=True)
|
|
|
|
|
|
@image_comparison(baseline_images=["empty"], extensions=["eps"])
|
|
def test_transparency():
|
|
fig, ax = plt.subplots()
|
|
ax.set_axis_off()
|
|
ax.plot([0, 1], color="r", alpha=0)
|
|
ax.text(.5, .5, "foo", color="r", alpha=0)
|
|
|
|
|
|
@needs_usetex
|
|
def test_failing_latex(tmpdir):
|
|
"""Test failing latex subprocess call"""
|
|
path = str(tmpdir.join("tmpoutput.ps"))
|
|
|
|
mpl.rcParams['text.usetex'] = True
|
|
|
|
# This fails with "Double subscript"
|
|
plt.xlabel("$22_2_2$")
|
|
with pytest.raises(RuntimeError):
|
|
plt.savefig(path)
|