1818from matplotlib import _png , rcParams
1919from matplotlib import font_manager
2020from 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 \n Full 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