From: <md...@us...> - 2007-11-13 15:15:38
|
Revision: 4243 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4243&view=rev Author: mdboom Date: 2007-11-13 07:15:36 -0800 (Tue, 13 Nov 2007) Log Message: ----------- All backends can write to file-like objects rather than only regular files. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/backends/backend_wx.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/CHANGELOG 2007-11-13 15:15:36 UTC (rev 4243) @@ -1,3 +1,7 @@ +2007-11-13 All backends now support writing to a file-like object, not + just a regular file. savefig() can be passed a file-like + object in place of a file path. - MGD + 2007-11-13 Improved the default backend selection at build time: SVG -> Agg -> TkAgg -> WXAgg -> GTK -> GTKAgg. The last usable backend in this progression will be chosen in the default Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-11-13 15:15:36 UTC (rev 4243) @@ -365,11 +365,24 @@ pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width, height) - try: - pixbuf.save(filename, format) - except gobject.GError, exc: - error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) - + if is_string_like(filename): + try: + pixbuf.save(filename, format) + except gobject.GError, exc: + error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) + elif hasattr(filename, 'write') and callable(filename.write): + if hasattr(pixbuf, 'save_to_callback'): + def save_callback(buf, data=None): + data.write(buf) + try: + pixbuf.save_to_callback(save_callback, format, user_data=filename) + except gobject.GError, exc: + error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) + else: + raise ValueError("Saving to a Python file-like object is only supported by PyGTK >= 2.8") + else: + raise ValueError("filename must be a path or a file-like object") + def get_default_filetype(self): return 'png' Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-11-13 15:15:36 UTC (rev 4243) @@ -325,7 +325,15 @@ self.width, self.height = width, height self.nextObject = 1 # next free object id self.xrefTable = [ [0, 65535, 'the zero object'] ] - fh = file(filename, 'wb') + self.passed_in_file_object = False + if is_string_like(filename): + fh = file(filename, 'wb') + elif hasattr(filename, 'write') and callable(filename.write): + fh = filename + self.passed_in_file_object = True + else: + raise ValueError("filename must be a path or a file-like object") + self.fh = fh self.currentstream = None # stream object to write to, if any fh.write("%PDF-1.4\n") # 1.4 is the first version to have alpha @@ -423,7 +431,8 @@ self.writeMarkers() self.writeXref() self.writeTrailer() - self.fh.close() + if not self.passed_in_file_object: + self.fh.close() def write(self, data): if self.currentstream is None: Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-11-13 15:15:36 UTC (rev 4243) @@ -1047,10 +1047,16 @@ written into this file object. """ isEPSF = format == 'eps' - title = outfile - - # write to a temp file, we'll move it to outfile when done - tmpfile = os.path.join(gettempdir(), md5.md5(outfile).hexdigest()) + passed_in_file_object = False + if is_string_like(outfile): + title = outfile + tmpfile = os.path.join(gettempdir(), md5.md5(outfile).hexdigest()) + elif hasattr(outfile, 'write') and callable(outfile.write): + title = None + tmpfile = os.path.join(gettempdir(), md5.md5(str(hash(outfile))).hexdigest()) + passed_in_file_object = True + else: + raise ValueError("outfile must be a path or a file-like object") fh = file(tmpfile, 'w') # find the appropriate papertype @@ -1168,10 +1174,11 @@ elif rcParams['ps.usedistiller'] == 'xpdf': xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) - if isinstance(outfile, file): + if passed_in_file_object: fh = file(tmpfile) print >>outfile, fh.read() - else: shutil.move(tmpfile, outfile) + else: + shutil.move(tmpfile, outfile) def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor, orientation, isLandscape, papertype): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2007-11-13 15:15:36 UTC (rev 4243) @@ -5,6 +5,7 @@ from matplotlib import verbose, __version__, rcParams from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase +from matplotlib.cbook import is_string_like from matplotlib.colors import rgb2hex from matplotlib.figure import Figure from matplotlib.font_manager import findfont, FontProperties @@ -458,15 +459,27 @@ 'svgz': 'Scalable Vector Graphics'} def print_svg(self, filename, *args, **kwargs): - svgwriter = codecs.open(filename, 'w', 'utf-8') - return self._print_svg(filename, svgwriter) - + if is_string_like(filename): + fh_to_close = svgwriter = codecs.open(filename, 'w', 'utf-8') + elif hasattr(filename, 'write') and callable(filename.write): + svgwriter = codecs.EncodedFile(filename, 'utf-8') + fh_to_close = None + else: + raise ValueError("filename must be a path or a file-like object") + return self._print_svg(filename, svgwriter, fh_to_close) + def print_svgz(self, filename, *args, **kwargs): - gzipwriter = gzip.GzipFile(filename, 'w') - svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') - return self._print_svg(filename, svgwriter) + if is_string_like(filename): + gzipwriter = gzip.GzipFile(filename, 'w') + fh_to_close = svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') + elif hasattr(filename, 'write') and callable(filename.write): + fh_to_close = gzipwriter = gzip.GzipFile(fileobj=filename, mode='w') + svgwriter = codecs.EncodedFile(gzipwriter, 'utf-8') + else: + raise ValueError("filename must be a path or a file-like object") + return self._print_svg(filename, svgwriter, fh_to_close) - def _print_svg(self, filename, svgwriter): + def _print_svg(self, filename, svgwriter, fh_to_close=None): self.figure.dpi.set(72) width, height = self.figure.get_size_inches() w, h = width*72, height*72 @@ -474,7 +487,8 @@ renderer = RendererSVG(w, h, svgwriter, filename) self.figure.draw(renderer) renderer.finish() - svgwriter.close() + if fh_to_close is not None: + svgwriter.close() def get_default_filetype(self): return 'svg' Modified: trunk/matplotlib/lib/matplotlib/backends/backend_wx.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_wx.py 2007-11-13 13:50:29 UTC (rev 4242) +++ trunk/matplotlib/lib/matplotlib/backends/backend_wx.py 2007-11-13 15:15:36 UTC (rev 4243) @@ -152,7 +152,7 @@ cursors from matplotlib._pylab_helpers import Gcf from matplotlib.artist import Artist -from matplotlib.cbook import exception_to_str +from matplotlib.cbook import exception_to_str, is_string_like from matplotlib.figure import Figure from matplotlib.text import _process_text_args, Text from matplotlib.widgets import SubplotTool @@ -1030,12 +1030,17 @@ # Now that we have rendered into the bitmap, save it # to the appropriate file type and clean up - if not self.bitmap.SaveFile(filename, filetype): - DEBUG_MSG('print_figure() file save error', 4, self) - # note the error must be displayed here because trapping - # the error on a call or print_figure may not work because - # printing can be qued and called from realize - raise RuntimeError('Could not save figure to %s\n' % (filename)) + if is_string_like(filename): + if not self.bitmap.SaveFile(filename, filetype): + DEBUG_MSG('print_figure() file save error', 4, self) + # note the error must be displayed here because trapping + # the error on a call or print_figure may not work because + # printing can be qued and called from realize + raise RuntimeError('Could not save figure to %s\n' % (filename)) + elif hasattr(filename, 'write') and callable(filename.write): + if not self.bitmap.ConvertToImage().SaveStream(filename, filetype): + DEBUG_MSG('print_figure() file save error', 4, self) + raise RuntimeError('Could not save figure to %s\n' % (filename)) # Restore everything to normal self.bitmap = origBitmap This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |