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.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to