Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e5404d8

Browse files
authored
Merge pull request #18654 from anntzer/pgftmpdir
Simplify tmpdir handling in backend_pgf.
2 parents 2ab1676 + 27fea5f commit e5404d8

File tree

2 files changed

+38
-65
lines changed

2 files changed

+38
-65
lines changed

lib/matplotlib/backends/backend_pgf.py

Lines changed: 31 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import codecs
33
import datetime
44
import functools
5+
from io import BytesIO
56
import logging
67
import math
78
import os
@@ -11,6 +12,7 @@
1112
import subprocess
1213
import sys
1314
import tempfile
15+
from tempfile import TemporaryDirectory
1416
import weakref
1517

1618
from PIL import Image
@@ -866,18 +868,12 @@ def _print_pdf_to_fh(self, fh, *args, metadata=None, **kwargs):
866868
hyperref_options = ','.join(
867869
_metadata_to_str(k, v) for k, v in info_dict.items())
868870

869-
try:
870-
# create temporary directory for compiling the figure
871-
tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
872-
fname_pgf = os.path.join(tmpdir, "figure.pgf")
873-
fname_tex = os.path.join(tmpdir, "figure.tex")
874-
fname_pdf = os.path.join(tmpdir, "figure.pdf")
871+
with TemporaryDirectory() as tmpdir:
872+
tmppath = pathlib.Path(tmpdir)
875873

876874
# print figure to pgf and compile it with latex
877-
self.print_pgf(fname_pgf, *args, **kwargs)
875+
self.print_pgf(tmppath / "figure.pgf", *args, **kwargs)
878876

879-
latex_preamble = get_preamble()
880-
latex_fontspec = get_fontspec()
881877
latexcode = """
882878
\\PassOptionsToPackage{pdfinfo={%s}}{hyperref}
883879
\\RequirePackage{hyperref}
@@ -890,22 +886,16 @@ def _print_pdf_to_fh(self, fh, *args, metadata=None, **kwargs):
890886
\\begin{document}
891887
\\centering
892888
\\input{figure.pgf}
893-
\\end{document}""" % (hyperref_options, w, h, latex_preamble, latex_fontspec)
894-
pathlib.Path(fname_tex).write_text(latexcode, encoding="utf-8")
889+
\\end{document}""" % (hyperref_options, w, h, get_preamble(), get_fontspec())
890+
(tmppath / "figure.tex").write_text(latexcode, encoding="utf-8")
895891

896892
texcommand = mpl.rcParams["pgf.texsystem"]
897893
cbook._check_and_log_subprocess(
898894
[texcommand, "-interaction=nonstopmode", "-halt-on-error",
899895
"figure.tex"], _log, cwd=tmpdir)
900896

901-
# copy file contents to target
902-
with open(fname_pdf, "rb") as fh_src:
903-
shutil.copyfileobj(fh_src, fh)
904-
finally:
905-
try:
906-
shutil.rmtree(tmpdir)
907-
except:
908-
TmpDirCleaner.add(tmpdir)
897+
with (tmppath / "figure.pdf").open("rb") as fh_src:
898+
shutil.copyfileobj(fh_src, fh) # copy file contents to target
909899

910900
def print_pdf(self, fname_or_fh, *args, **kwargs):
911901
"""Use LaTeX to compile a Pgf generated figure to PDF."""
@@ -914,23 +904,14 @@ def print_pdf(self, fname_or_fh, *args, **kwargs):
914904

915905
def _print_png_to_fh(self, fh, *args, **kwargs):
916906
converter = make_pdf_to_png_converter()
917-
918-
try:
919-
# create temporary directory for pdf creation and png conversion
920-
tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
921-
fname_pdf = os.path.join(tmpdir, "figure.pdf")
922-
fname_png = os.path.join(tmpdir, "figure.png")
923-
# create pdf and try to convert it to png
924-
self.print_pdf(fname_pdf, *args, **kwargs)
925-
converter(fname_pdf, fname_png, dpi=self.figure.dpi)
926-
# copy file contents to target
927-
with open(fname_png, "rb") as fh_src:
928-
shutil.copyfileobj(fh_src, fh)
929-
finally:
930-
try:
931-
shutil.rmtree(tmpdir)
932-
except:
933-
TmpDirCleaner.add(tmpdir)
907+
with TemporaryDirectory() as tmpdir:
908+
tmppath = pathlib.Path(tmpdir)
909+
pdf_path = tmppath / "figure.pdf"
910+
png_path = tmppath / "figure.png"
911+
self.print_pdf(pdf_path, *args, **kwargs)
912+
converter(pdf_path, png_path, dpi=self.figure.dpi)
913+
with png_path.open("rb") as fh_src:
914+
shutil.copyfileobj(fh_src, fh) # copy file contents to target
934915

935916
def print_png(self, fname_or_fh, *args, **kwargs):
936917
"""Use LaTeX to compile a pgf figure to pdf and convert it to png."""
@@ -973,12 +954,8 @@ class PdfPages:
973954
... pdf.savefig()
974955
"""
975956
__slots__ = (
976-
'_outputfile',
957+
'_output_name',
977958
'keep_empty',
978-
'_tmpdir',
979-
'_basename',
980-
'_fname_tex',
981-
'_fname_pdf',
982959
'_n_figures',
983960
'_file',
984961
'_info_dict',
@@ -1009,7 +986,7 @@ def __init__(self, filename, *, keep_empty=True, metadata=None):
1009986
'Trapped'. Values have been predefined for 'Creator', 'Producer'
1010987
and 'CreationDate'. They can be removed by setting them to `None`.
1011988
"""
1012-
self._outputfile = filename
989+
self._output_name = filename
1013990
self._n_figures = 0
1014991
self.keep_empty = keep_empty
1015992
self._metadata = (metadata or {}).copy()
@@ -1027,13 +1004,7 @@ def __init__(self, filename, *, keep_empty=True, metadata=None):
10271004
f'set {canonical} instead of {key}.')
10281005
self._metadata[canonical] = self._metadata.pop(key)
10291006
self._info_dict = _create_pdf_info_dict('pgf', self._metadata)
1030-
1031-
# create temporary directory for compiling the figure
1032-
self._tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_pdfpages_")
1033-
self._basename = 'pdf_pages'
1034-
self._fname_tex = os.path.join(self._tmpdir, self._basename + ".tex")
1035-
self._fname_pdf = os.path.join(self._tmpdir, self._basename + ".pdf")
1036-
self._file = open(self._fname_tex, 'wb')
1007+
self._file = BytesIO()
10371008

10381009
@cbook.deprecated('3.3')
10391010
@property
@@ -1085,27 +1056,22 @@ def close(self):
10851056
and moving the final pdf file to *filename*.
10861057
"""
10871058
self._file.write(rb'\end{document}\n')
1088-
self._file.close()
1089-
10901059
if self._n_figures > 0:
1091-
try:
1092-
self._run_latex()
1093-
finally:
1094-
try:
1095-
shutil.rmtree(self._tmpdir)
1096-
except:
1097-
TmpDirCleaner.add(self._tmpdir)
1060+
self._run_latex()
10981061
elif self.keep_empty:
1099-
open(self._outputfile, 'wb').close()
1062+
open(self._output_name, 'wb').close()
1063+
self._file.close()
11001064

11011065
def _run_latex(self):
11021066
texcommand = mpl.rcParams["pgf.texsystem"]
1103-
cbook._check_and_log_subprocess(
1104-
[texcommand, "-interaction=nonstopmode", "-halt-on-error",
1105-
os.path.basename(self._fname_tex)],
1106-
_log, cwd=self._tmpdir)
1107-
# copy file contents to target
1108-
shutil.copyfile(self._fname_pdf, self._outputfile)
1067+
with TemporaryDirectory() as tmpdir:
1068+
tex_source = pathlib.Path(tmpdir, "pdf_pages.tex")
1069+
tex_source.write_bytes(self._file.getvalue())
1070+
cbook._check_and_log_subprocess(
1071+
[texcommand, "-interaction=nonstopmode", "-halt-on-error",
1072+
tex_source],
1073+
_log, cwd=tmpdir)
1074+
shutil.move(tex_source.with_suffix(".pdf"), self._output_name)
11091075

11101076
def savefig(self, figure=None, **kwargs):
11111077
"""

lib/matplotlib/tests/test_backend_pgf.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,10 @@ def test_bbox_inches_tight(tmpdir):
321321
ax.imshow([[0, 1], [2, 3]])
322322
fig.savefig(os.path.join(tmpdir, "test.pdf"), backend="pgf",
323323
bbox_inches="tight")
324+
325+
326+
@needs_xelatex
327+
def test_png():
328+
# Just a smoketest.
329+
fig, ax = plt.subplots()
330+
fig.savefig(BytesIO(), format="png", backend="pgf")

0 commit comments

Comments
 (0)