def __init__(self, filename, *, keep_empty=True, metadata=None): """ Create a new PdfPages object. Parameters ---------- filename : str or path-like Plots using `PdfPages.savefig` will be written to a file at this location. Any older file with the same name is overwritten. keep_empty : bool, default: True If set to False, then empty pdf files will be deleted automatically when closed. metadata : dict, optional Information dictionary object (see PDF reference section 10.2.1 'Document Information Dictionary'), e.g.: ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. The standard keys are 'Title', 'Author', 'Subject', 'Keywords', 'Creator', 'Producer', 'CreationDate', 'ModDate', and 'Trapped'. Values have been predefined for 'Creator', 'Producer' and 'CreationDate'. They can be removed by setting them to `None`. """ self._output_name = filename self._n_figures = 0 self.keep_empty = keep_empty self._metadata = (metadata or {}).copy() self._info_dict = _create_pdf_info_dict('pgf', self._metadata) self._file = BytesIO()
def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs): """Use LaTeX to compile a pgf generated figure to pdf.""" w, h = self.figure.get_size_inches() info_dict = _create_pdf_info_dict('pgf', metadata or {}) pdfinfo = ','.join( _metadata_to_str(k, v) for k, v in info_dict.items()) # print figure to pgf and compile it with latex with TemporaryDirectory() as tmpdir: tmppath = pathlib.Path(tmpdir) self.print_pgf(tmppath / "figure.pgf", **kwargs) (tmppath / "figure.tex").write_text( "\n".join([ r"\PassOptionsToPackage{pdfinfo={%s}}{hyperref}" % pdfinfo, r"\RequirePackage{hyperref}", r"\documentclass[12pt]{minimal}", r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}" % (w, h), get_preamble(), get_fontspec(), r"\usepackage{pgf}", r"\begin{document}", r"\centering", r"\input{figure.pgf}", r"\end{document}", ]), encoding="utf-8") texcommand = mpl.rcParams["pgf.texsystem"] cbook._check_and_log_subprocess( [texcommand, "-interaction=nonstopmode", "-halt-on-error", "figure.tex"], _log, cwd=tmpdir) with (tmppath / "figure.pdf").open("rb") as orig, \ cbook.open_file_cm(fname_or_fh, "wb") as dest: shutil.copyfileobj(orig, dest) # copy file contents to target
def _print_pdf_to_fh(self, fh, *args, metadata=None, **kwargs): w, h = self.figure.get_figwidth(), self.figure.get_figheight() info_dict = _create_pdf_info_dict('pgf', metadata or {}) hyperref_options = ','.join( _metadata_to_str(k, v) for k, v in info_dict.items()) with TemporaryDirectory() as tmpdir: tmppath = pathlib.Path(tmpdir) # print figure to pgf and compile it with latex self.print_pgf(tmppath / "figure.pgf", *args, **kwargs) latexcode = """ \\PassOptionsToPackage{pdfinfo={%s}}{hyperref} \\RequirePackage{hyperref} \\documentclass[12pt]{minimal} \\usepackage[paperwidth=%fin, paperheight=%fin, margin=0in]{geometry} %s %s \\usepackage{pgf} \\begin{document} \\centering \\input{figure.pgf} \\end{document}""" % (hyperref_options, w, h, get_preamble(), get_fontspec()) (tmppath / "figure.tex").write_text(latexcode, encoding="utf-8") texcommand = mpl.rcParams["pgf.texsystem"] cbook._check_and_log_subprocess( [texcommand, "-interaction=nonstopmode", "-halt-on-error", "figure.tex"], _log, cwd=tmpdir) with (tmppath / "figure.pdf").open("rb") as fh_src: shutil.copyfileobj(fh_src, fh) # copy file contents to target
def __init__(self, filename, *, keep_empty=True, metadata=None): """ Create a new PdfPages object. Parameters ---------- filename : str or path-like Plots using `PdfPages.savefig` will be written to a file at this location. Any older file with the same name is overwritten. keep_empty : bool, default: True If set to False, then empty pdf files will be deleted automatically when closed. metadata : dict, optional Information dictionary object (see PDF reference section 10.2.1 'Document Information Dictionary'), e.g.: ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. The standard keys are 'Title', 'Author', 'Subject', 'Keywords', 'Creator', 'Producer', 'CreationDate', 'ModDate', and 'Trapped'. Values have been predefined for 'Creator', 'Producer' and 'CreationDate'. They can be removed by setting them to `None`. """ self._outputfile = filename self._n_figures = 0 self.keep_empty = keep_empty self._metadata = (metadata or {}).copy() if metadata: for key in metadata: canonical = { 'creationdate': 'CreationDate', 'moddate': 'ModDate', }.get(key.lower(), key.lower().title()) if canonical != key: cbook.warn_deprecated( '3.3', message='Support for setting PDF metadata keys ' 'case-insensitively is deprecated since %(since)s and ' 'will be removed %(removal)s; ' f'set {canonical} instead of {key}.') self._metadata[canonical] = self._metadata.pop(key) self._info_dict = _create_pdf_info_dict('pgf', self._metadata) # create temporary directory for compiling the figure self._tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_pdfpages_") self._basename = 'pdf_pages' self._fname_tex = os.path.join(self._tmpdir, self._basename + ".tex") self._fname_pdf = os.path.join(self._tmpdir, self._basename + ".pdf") self._file = open(self._fname_tex, 'wb')
def _print_pdf_to_fh(self, fh, *args, metadata=None, **kwargs): w, h = self.figure.get_figwidth(), self.figure.get_figheight() info_dict = _create_pdf_info_dict('pgf', metadata or {}) hyperref_options = ','.join( _metadata_to_str(k, v) for k, v in info_dict.items()) try: # create temporary directory for compiling the figure tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_") fname_pgf = os.path.join(tmpdir, "figure.pgf") fname_tex = os.path.join(tmpdir, "figure.tex") fname_pdf = os.path.join(tmpdir, "figure.pdf") # print figure to pgf and compile it with latex self.print_pgf(fname_pgf, *args, **kwargs) latex_preamble = get_preamble() latex_fontspec = get_fontspec() latexcode = """ \\PassOptionsToPackage{pdfinfo={%s}}{hyperref} \\RequirePackage{hyperref} \\documentclass[12pt]{minimal} \\usepackage[paperwidth=%fin, paperheight=%fin, margin=0in]{geometry} %s %s \\usepackage{pgf} \\begin{document} \\centering \\input{figure.pgf} \\end{document}""" % (hyperref_options, w, h, latex_preamble, latex_fontspec) pathlib.Path(fname_tex).write_text(latexcode, encoding="utf-8") texcommand = mpl.rcParams["pgf.texsystem"] cbook._check_and_log_subprocess([ texcommand, "-interaction=nonstopmode", "-halt-on-error", "figure.tex" ], _log, cwd=tmpdir) # copy file contents to target with open(fname_pdf, "rb") as fh_src: shutil.copyfileobj(fh_src, fh) finally: try: shutil.rmtree(tmpdir) except: TmpDirCleaner.add(tmpdir)
def __init__(self, filename, *, keep_empty=True, metadata=None): """ Create a new PdfPages object. Parameters ---------- filename : str or path-like Plots using `PdfPages.savefig` will be written to a file at this location. Any older file with the same name is overwritten. keep_empty : bool, default: True If set to False, then empty pdf files will be deleted automatically when closed. metadata : dict, optional Information dictionary object (see PDF reference section 10.2.1 'Document Information Dictionary'), e.g.: ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``. The standard keys are 'Title', 'Author', 'Subject', 'Keywords', 'Creator', 'Producer', 'CreationDate', 'ModDate', and 'Trapped'. Values have been predefined for 'Creator', 'Producer' and 'CreationDate'. They can be removed by setting them to `None`. Note that some versions of LaTeX engines may ignore the 'Producer' key and set it to themselves. """ self._output_name = filename self._n_figures = 0 self.keep_empty = keep_empty self._metadata = (metadata or {}).copy() if metadata: for key in metadata: canonical = { 'creationdate': 'CreationDate', 'moddate': 'ModDate', }.get(key.lower(), key.lower().title()) if canonical != key: _api.warn_deprecated( '3.3', message='Support for setting PDF metadata keys ' 'case-insensitively is deprecated since %(since)s and ' 'will be removed %(removal)s; ' f'set {canonical} instead of {key}.') self._metadata[canonical] = self._metadata.pop(key) self._info_dict = _create_pdf_info_dict('pgf', self._metadata) self._file = BytesIO()