test_backend_ps.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import io
  2. import os
  3. from pathlib import Path
  4. import re
  5. import tempfile
  6. import pytest
  7. import matplotlib as mpl
  8. import matplotlib.pyplot as plt
  9. from matplotlib import cbook, patheffects
  10. from matplotlib.testing.decorators import image_comparison
  11. needs_ghostscript = pytest.mark.skipif(
  12. "eps" not in mpl.testing.compare.converter,
  13. reason="This test needs a ghostscript installation")
  14. needs_usetex = pytest.mark.skipif(
  15. not mpl.checkdep_usetex(True),
  16. reason="This test needs a TeX installation")
  17. # This tests tends to hit a TeX cache lock on AppVeyor.
  18. @pytest.mark.flaky(reruns=3)
  19. @pytest.mark.parametrize('orientation', ['portrait', 'landscape'])
  20. @pytest.mark.parametrize('format, use_log, rcParams', [
  21. ('ps', False, {}),
  22. pytest.param('ps', False, {'ps.usedistiller': 'ghostscript'},
  23. marks=needs_ghostscript),
  24. pytest.param('ps', False, {'text.usetex': True},
  25. marks=[needs_ghostscript, needs_usetex]),
  26. ('eps', False, {}),
  27. ('eps', True, {'ps.useafm': True}),
  28. pytest.param('eps', False, {'text.usetex': True},
  29. marks=[needs_ghostscript, needs_usetex]),
  30. ], ids=[
  31. 'ps',
  32. 'ps with distiller',
  33. 'ps with usetex',
  34. 'eps',
  35. 'eps afm',
  36. 'eps with usetex'
  37. ])
  38. def test_savefig_to_stringio(format, use_log, rcParams, orientation,
  39. monkeypatch):
  40. mpl.rcParams.update(rcParams)
  41. monkeypatch.setenv("SOURCE_DATE_EPOCH", "0") # For reproducibility.
  42. fig, ax = plt.subplots()
  43. with io.StringIO() as s_buf, io.BytesIO() as b_buf:
  44. if use_log:
  45. ax.set_yscale('log')
  46. ax.plot([1, 2], [1, 2])
  47. title = "Déjà vu"
  48. if not mpl.rcParams["text.usetex"]:
  49. title += " \N{MINUS SIGN}\N{EURO SIGN}"
  50. ax.set_title(title)
  51. fig.savefig(s_buf, format=format, orientation=orientation)
  52. fig.savefig(b_buf, format=format, orientation=orientation)
  53. s_val = s_buf.getvalue().encode('ascii')
  54. b_val = b_buf.getvalue()
  55. assert s_val == b_val.replace(b'\r\n', b'\n')
  56. def test_patheffects():
  57. mpl.rcParams['path.effects'] = [
  58. patheffects.withStroke(linewidth=4, foreground='w')]
  59. fig, ax = plt.subplots()
  60. ax.plot([1, 2, 3])
  61. with io.BytesIO() as ps:
  62. fig.savefig(ps, format='ps')
  63. @needs_usetex
  64. @needs_ghostscript
  65. def test_tilde_in_tempfilename(tmpdir):
  66. # Tilde ~ in the tempdir path (e.g. TMPDIR, TMP or TEMP on windows
  67. # when the username is very long and windows uses a short name) breaks
  68. # latex before https://github.com/matplotlib/matplotlib/pull/5928
  69. base_tempdir = Path(tmpdir, "short-1")
  70. base_tempdir.mkdir()
  71. # Change the path for new tempdirs, which is used internally by the ps
  72. # backend to write a file.
  73. with cbook._setattr_cm(tempfile, tempdir=str(base_tempdir)):
  74. # usetex results in the latex call, which does not like the ~
  75. mpl.rcParams['text.usetex'] = True
  76. plt.plot([1, 2, 3, 4])
  77. plt.xlabel(r'\textbf{time} (s)')
  78. # use the PS backend to write the file...
  79. plt.savefig(base_tempdir / 'tex_demo.eps', format="ps")
  80. @image_comparison(["empty.eps"])
  81. def test_transparency():
  82. fig, ax = plt.subplots()
  83. ax.set_axis_off()
  84. ax.plot([0, 1], color="r", alpha=0)
  85. ax.text(.5, .5, "foo", color="r", alpha=0)
  86. @needs_usetex
  87. def test_failing_latex(tmpdir):
  88. """Test failing latex subprocess call"""
  89. mpl.rcParams['text.usetex'] = True
  90. # This fails with "Double subscript"
  91. plt.xlabel("$22_2_2$")
  92. with pytest.raises(RuntimeError):
  93. plt.savefig(Path(tmpdir, "tmpoutput.ps"))