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

Skip to content

Commit d1d3967

Browse files
author
pwuertz
committed
backend_pgf: support writing to file-like objects
1 parent bf725a0 commit d1d3967

File tree

1 file changed

+73
-37
lines changed

1 file changed

+73
-37
lines changed

lib/matplotlib/backends/backend_pgf.py

Lines changed: 73 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from matplotlib import _png, rcParams
1919
from matplotlib import font_manager
2020
from matplotlib.ft2font import FT2Font
21+
from matplotlib.cbook import is_string_like, is_writable_file_like
2122

2223
###############################################################################
2324

@@ -623,12 +624,7 @@ def __init__(self, *args):
623624
def get_default_filetype(self):
624625
return 'pdf'
625626

626-
def print_pgf(self, filename, *args, **kwargs):
627-
"""
628-
Output pgf commands for drawing the figure so it can be included and
629-
rendered in latex documents.
630-
"""
631-
627+
def _print_pgf_to_fh(self, fh):
632628
header_text = r"""%% Creator: Matplotlib, PGF backend
633629
%%
634630
%% To include the figure in your LaTeX document, write
@@ -658,37 +654,50 @@ def print_pgf(self, filename, *args, **kwargs):
658654
# get figure size in inch
659655
w, h = self.figure.get_figwidth(), self.figure.get_figheight()
660656

661-
# start a pgfpicture environment and set a bounding box
662-
with codecs.open(filename, "w", encoding="utf-8") as fh:
663-
fh.write(header_text)
664-
fh.write(header_info_preamble)
665-
fh.write("\n")
666-
writeln(fh, r"\begingroup")
667-
writeln(fh, r"\makeatletter")
668-
writeln(fh, r"\begin{pgfpicture}")
669-
writeln(fh, r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w,h))
670-
writeln(fh, r"\pgfusepath{use as bounding box}")
671-
672-
renderer = RendererPgf(self.figure, fh)
673-
self.figure.draw(renderer)
674-
675-
# end the pgfpicture environment
676-
writeln(fh, r"\end{pgfpicture}")
677-
writeln(fh, r"\makeatother")
678-
writeln(fh, r"\endgroup")
679-
680-
def print_pdf(self, filename, *args, **kwargs):
657+
# create pgfpicture environment and write the pgf code
658+
fh.write(header_text)
659+
fh.write(header_info_preamble)
660+
fh.write("\n")
661+
writeln(fh, r"\begingroup")
662+
writeln(fh, r"\makeatletter")
663+
writeln(fh, r"\begin{pgfpicture}")
664+
writeln(fh, r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w,h))
665+
writeln(fh, r"\pgfusepath{use as bounding box}")
666+
renderer = RendererPgf(self.figure, fh)
667+
self.figure.draw(renderer)
668+
669+
# end the pgfpicture environment
670+
writeln(fh, r"\end{pgfpicture}")
671+
writeln(fh, r"\makeatother")
672+
writeln(fh, r"\endgroup")
673+
674+
def print_pgf(self, fname_or_fh, *args, **kwargs):
681675
"""
682-
Use LaTeX to compile a Pgf generated figure to PDF.
676+
Output pgf commands for drawing the figure so it can be included and
677+
rendered in latex documents.
683678
"""
684-
w, h = self.figure.get_figwidth(), self.figure.get_figheight()
679+
if kwargs.get("dryrun", False): return
680+
681+
# figure out where the pgf is to be written to
682+
if is_string_like(fname_or_fh):
683+
with codecs.open(fname_or_fh, "w", encoding="utf-8") as fh:
684+
self._print_pgf_to_fh(fh)
685+
elif is_writable_file_like(fname_or_fh):
686+
raise ValueError("saving pgf to a stream is not supported, " + \
687+
"consider using the pdf option of the pgf-backend")
688+
else:
689+
raise ValueError("filename must be a path")
685690

686-
target = os.path.abspath(filename)
691+
def _print_pdf_to_fh(self, fh):
692+
w, h = self.figure.get_figwidth(), self.figure.get_figheight()
687693

688694
try:
695+
# create and switch to temporary directory
689696
tmpdir = tempfile.mkdtemp()
690697
cwd = os.getcwd()
691698
os.chdir(tmpdir)
699+
700+
# print figure to pgf and compile it with latex
692701
self.print_pgf("figure.pgf")
693702

694703
latex_preamble = get_preamble()
@@ -704,45 +713,72 @@ def print_pdf(self, filename, *args, **kwargs):
704713
\centering
705714
\input{figure.pgf}
706715
\end{document}""" % (w, h, latex_preamble, latex_fontspec)
707-
with codecs.open("figure.tex", "w", "utf-8") as fh:
708-
fh.write(latexcode)
716+
with codecs.open("figure.tex", "w", "utf-8") as fh_tex:
717+
fh_tex.write(latexcode)
709718

710719
texcommand = get_texcommand()
711720
cmdargs = [texcommand, "-interaction=nonstopmode", "-halt-on-error", "figure.tex"]
712721
try:
713-
stdout = subprocess.check_output(cmdargs, stderr=subprocess.STDOUT)
722+
subprocess.check_output(cmdargs, stderr=subprocess.STDOUT)
714723
except subprocess.CalledProcessError as e:
715724
raise RuntimeError("%s was not able to process your file.\n\nFull log:\n%s" % (texcommand, e.output))
716-
shutil.copyfile("figure.pdf", target)
725+
726+
# copy file contents to target
727+
with open("figure.pdf", "rb") as fh_src:
728+
shutil.copyfileobj(fh_src, fh)
717729
finally:
718730
os.chdir(cwd)
719731
try:
720732
shutil.rmtree(tmpdir)
721733
except:
722734
sys.stderr.write("could not delete tmp directory %s\n" % tmpdir)
723735

724-
def print_png(self, filename, *args, **kwargs):
736+
def print_pdf(self, fname_or_fh, *args, **kwargs):
725737
"""
726-
Use LaTeX to compile a pgf figure to pdf and convert it to png.
738+
Use LaTeX to compile a Pgf generated figure to PDF.
727739
"""
740+
# figure out where the pdf is to be written to
741+
if is_string_like(fname_or_fh):
742+
with open(fname_or_fh, "wb") as fh:
743+
self._print_pdf_to_fh(fh)
744+
elif is_writable_file_like(fname_or_fh):
745+
self._print_pdf_to_fh(fname_or_fh)
746+
else:
747+
raise ValueError("filename must be a path or a file-like object")
728748

749+
def _print_png_to_fh(self, fh):
729750
converter = make_pdf_to_png_converter()
730751

731-
target = os.path.abspath(filename)
732752
try:
753+
# create and switch to temporary directory
733754
tmpdir = tempfile.mkdtemp()
734755
cwd = os.getcwd()
735756
os.chdir(tmpdir)
757+
# create pdf and try to convert it to png
736758
self.print_pdf("figure.pdf")
737759
converter("figure.pdf", "figure.png", dpi=self.figure.dpi)
738-
shutil.copyfile("figure.png", target)
760+
# copy file contents to target
761+
with open("figure.png", "rb") as fh_src:
762+
shutil.copyfileobj(fh_src, fh)
739763
finally:
740764
os.chdir(cwd)
741765
try:
742766
shutil.rmtree(tmpdir)
743767
except:
744768
sys.stderr.write("could not delete tmp directory %s\n" % tmpdir)
745769

770+
def print_png(self, fname_or_fh, *args, **kwargs):
771+
"""
772+
Use LaTeX to compile a pgf figure to pdf and convert it to png.
773+
"""
774+
if is_string_like(fname_or_fh):
775+
with open(fname_or_fh, "wb") as fh:
776+
self._print_png_to_fh(fh)
777+
elif is_writable_file_like(fname_or_fh):
778+
self._print_png_to_fh(fname_or_fh)
779+
else:
780+
raise ValueError("filename must be a path or a file-like object")
781+
746782
def _render_texts_pgf(self, fh):
747783
# TODO: currently unused code path
748784

0 commit comments

Comments
 (0)