From: <md...@us...> - 2007-09-06 18:50:14
|
Revision: 3798 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3798&view=rev Author: mdboom Date: 2007-09-06 11:50:08 -0700 (Thu, 06 Sep 2007) Log Message: ----------- Refactoring of FigureCanvas*.print_figure so that each backend does not have to track all other possible filetypes. This should make it easier to add new filetype backends without updating lots of places. All GUI backends have the same base set of filetypes they support, defined in FigureCanvasBase. Non-GUI backends, for the most part will still only write to their own file format (and not do any switch_backend magic.) All GUI backends (where possible) now generate a list of file patterns for their file chooser dialogs, rather than having hard-coded lists. See FILETYPES for matrix of filetypes supported by each backend. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backend_bases.py trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py trunk/matplotlib/lib/matplotlib/backends/backend_emf.py trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_gd.py trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py trunk/matplotlib/lib/matplotlib/backends/backend_paint.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/backends/backend_qt.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4.py trunk/matplotlib/lib/matplotlib/backends/backend_qt4agg.py trunk/matplotlib/lib/matplotlib/backends/backend_qtagg.py trunk/matplotlib/lib/matplotlib/backends/backend_svg.py trunk/matplotlib/lib/matplotlib/backends/backend_template.py trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py trunk/matplotlib/lib/matplotlib/backends/backend_wx.py trunk/matplotlib/lib/matplotlib/backends/backend_wxagg.py trunk/matplotlib/lib/matplotlib/figure.py Added Paths: ----------- trunk/matplotlib/FILETYPES Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/CHANGELOG 2007-09-06 18:50:08 UTC (rev 3798) @@ -1,3 +1,11 @@ +2007-09-06 Refactored image saving code so that all GUI backends can + save most image types. See FILETYPES for a matrix of + backends and their supported file types. + Backend canvases should no longer write their own print_figure() + method -- instead they should write a print_xxx method for + each filetype they can output and add an entry to their + class-scoped filetypes dictionary. - MGD + 2007-09-05 Fixed Qt version reporting in setupext.py - DSD 2007-09-04 Embedding Type 1 fonts in PDF, and thus usetex support Added: trunk/matplotlib/FILETYPES =================================================================== --- trunk/matplotlib/FILETYPES (rev 0) +++ trunk/matplotlib/FILETYPES 2007-09-06 18:50:08 UTC (rev 3798) @@ -0,0 +1,60 @@ +This is a table of the output formats supported by each backend. + +You may need to expand your terminal window to read this table +correctly. It may be edited with emacs' table mode. + +Each cell specifies the backend that actually handles the file format. +A cell with a '+' in it denotes the rasterizer and the file writing +infrastructure as separate pieces. + ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +| |bmp |emf |eps |jpeg |pcx |pdf |png |ps |raw |svg |tiff |xpm | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Agg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Cairo | |emf |ps | | |cairo |cairo |cairo|agg |cairo| | | +|[1] | | |[2] | | | |* | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|CocoaAgg| |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Emf | |emf *| | | | | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|FltkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Gd | | | | | | |gd * | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Gtk | |emf |ps |gdk + | |pdf |gdk + |ps |agg |svg | | | +|(gdk) | | | |pixbuf | | |pixbuf| | | | | | +| | | | | | | |* | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|GtkAgg | |emf |ps |agg + | |pdf |agg + |ps |agg |svg | | | +| | | | |pixbuf | | |pixbuf| | | | | | +| | | | | | | |* | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|GtkCairo| |emf |ps |cairo +| |cairo |cairo |cairo|agg |svg | | | +| | | | |pixbuf | | |* | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Paint | | | | | | |libart| | | | | | +|(libart)| | | | | | |* | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Pdf | | | | | |pdf * | | | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Ps | | |ps | | | | |ps * | | | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|QtAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Qt4Agg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Svg | | | | | | | | | |svg *| | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|TkAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|Wx |wx + |emf |ps |wx + wx|wx + |pdf |wx + |ps |agg |svg |wx + |wx + | +| |wx | | | |wx | |wx * | | | |wx |wx | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ +|WxAgg | |emf |ps | | |pdf |agg * |ps |agg |svg | | | ++--------+-----+-----+-----+-------+-----+------+------+-----+-----+-----+-----+-----+ + +* Default filetype for the backend +[1] Cairo's default filetype is specified in rcParams['cairo.format'] +[2] Cairo does not produce .eps files, and instead falls back on backend_ps.py \ No newline at end of file Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -4,7 +4,7 @@ """ from __future__ import division -import sys, warnings +import os, sys, warnings import numpy as npy import matplotlib.numerix.npyma as ma @@ -12,6 +12,7 @@ import matplotlib.colors as colors import matplotlib.transforms as transforms import matplotlib.widgets as widgets +from matplotlib import rcParams class RendererBase: """An abstract base class to handle drawing/rendering operations @@ -1071,8 +1072,70 @@ (depending on the backend), truncated to integers""" return int(self.figure.bbox.width()), int(self.figure.bbox.height()) + filetypes = { + 'emf': 'Enhanced Metafile', + 'eps': 'Encapsulated Postscript', + 'pdf': 'Portable Document Format', + 'png': 'Portable Network Graphics', + 'ps' : 'Postscript', + 'raw': 'Raw RGBA bitmap', + 'rgb': 'Raw RGBA bitmap', + 'svg': 'Scalable Vector Graphics', + } + + # All of these print_* functions do a lazy import because + # a) otherwise we'd have cyclical imports, since all of these + # classes inherit from FigureCanvasBase + # b) so we don't import a bunch of stuff the user may never use + + def print_emf(self, *args, **kwargs): + from backends.backend_emf import FigureCanvasEMF # lazy import + emf = self.switch_backends(FigureCanvasEMF) + return emf.print_emf(*args, **kwargs) + + def print_eps(self, *args, **kwargs): + from backends.backend_ps import FigureCanvasPS # lazy import + ps = self.switch_backends(FigureCanvasPS) + return ps.print_eps(*args, **kwargs) + + def print_pdf(self, *args, **kwargs): + from backends.backend_pdf import FigureCanvasPdf # lazy import + pdf = self.switch_backends(FigureCanvasPdf) + return pdf.print_pdf(*args, **kwargs) + + def print_png(self, *args, **kwargs): + from backends.backend_agg import FigureCanvasAgg # lazy import + agg = self.switch_backends(FigureCanvasAgg) + return agg.print_png(*args, **kwargs) + + def print_ps(self, *args, **kwargs): + from backends.backend_ps import FigureCanvasPS # lazy import + ps = self.switch_backends(FigureCanvasPS) + return ps.print_ps(*args, **kwargs) + + def print_raw(self, *args, **kwargs): + from backends.backend_agg import FigureCanvasAgg # lazy import + agg = self.switch_backends(FigureCanvasAgg) + return agg.print_raw(*args, **kwargs) + print_bmp = print_rgb = print_raw + + def print_svg(self, *args, **kwargs): + from backends.backend_svg import FigureCanvasSVG # lazy import + svg = self.switch_backends(FigureCanvasSVG) + return svg.print_svg(*args, **kwargs) + + def get_supported_filetypes(self): + return self.filetypes + + def get_supported_filetypes_grouped(self): + groupings = {} + for ext, name in self.filetypes.items(): + groupings.setdefault(name, []).append(ext) + groupings[name].sort() + return groupings + def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): + orientation='portrait', format=None, **kwargs): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a gray figure @@ -1085,9 +1148,57 @@ facecolor - the facecolor of the figure edgecolor - the edgecolor of the figure orientation - 'landscape' | 'portrait' (not supported on all backends) + format - when set, forcibly set the file format to save to """ - pass + if format is None: + if cbook.is_string_like(filename): + format = os.path.splitext(filename)[1][1:] + if format is None or format == '': + format = self.get_default_filetype() + if cbook.is_string_like(filename): + filename = filename.rstrip('.') + '.' + format + format = format.lower() + method_name = 'print_%s' % format + if (format not in self.filetypes or + not hasattr(self, method_name)): + formats = self.filetypes.keys() + formats.sort() + raise ValueError( + 'Format "%s" is not supported.\n' + 'Supported formats: ' + '%s.' % (format, ', '.join(formats))) + + if dpi is None: + dpi = rcParams['savefig.dpi'] + + origDPI = self.figure.dpi.get() + origfacecolor = self.figure.get_facecolor() + origedgecolor = self.figure.get_edgecolor() + + self.figure.dpi.set(dpi) + self.figure.set_facecolor(facecolor) + self.figure.set_edgecolor(edgecolor) + + try: + result = getattr(self, method_name)( + filename, + dpi=dpi, + facecolor=facecolor, + edgecolor=edgecolor, + orientation=orientation, + **kwargs) + finally: + self.figure.dpi.set(origDPI) + self.figure.set_facecolor(origfacecolor) + self.figure.set_edgecolor(origedgecolor) + self.figure.set_canvas(self) + + return result + + def get_default_filetype(self): + raise NotImplementedError + def switch_backends(self, FigureCanvasClass): """ instantiate an instance of FigureCanvasClass Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -405,95 +405,15 @@ 'debug-annoying') return self.renderer.buffer_rgba(x,y) - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and - edge colors. This is useful because some of the GUIs have a - gray figure face color background and you'll probably want to - override this on hardcopy + def get_default_filetype(self): + return 'png' - If the extension matches PNG, write a PNG file - - If the extension matches BMP or RAW, write an RGBA bitmap file - - If filename is a fileobject, write png to file object (thus - you can, for example, write the png to stdout - """ - if __debug__: verbose.report('FigureCanvasAgg.print_figure', - 'debug-annoying') - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - - # store the orig figure dpi, color and size information so we - # can restore them later. For image creation alone, this is - # not important since after the print the figure is done. But - # backend_agg may be used as a renderer for a GUI figure, and - # restoring figure props will be important in that case. - # TODO: move most of this functionality into backend_bases - - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - # render the printed figure + def print_raw(self, filename, *args, **kwargs): self.draw() - - printfunc = None - if not is_string_like(filename): - # assume png and write to fileobject - self.renderer._renderer.write_png(filename) - #pass - else: - # take a look at the extension and choose the print handler - basename, ext = os.path.splitext(filename) - if not len(ext): - ext = '.png' - filename += ext - - ext = ext.lower() - if (ext.find('rgb')>=0 or - ext.find('raw')>=0 or - ext.find('bmp')>=0 ): - # agg doesn't handle unicode yet - self.renderer._renderer.write_rgba(str(filename)) - elif ext.find('png')>=0: - # agg doesn't handle unicode yet - self.renderer._renderer.write_png(str(filename)) - #pass - elif ext.find('svg')>=0: - from backend_svg import FigureCanvasSVG - svg = self.switch_backends(FigureCanvasSVG) - printfunc = svg.print_figure - elif ext.find('ps')>=0 or ext.find('ep')>=0: - from backend_ps import FigureCanvasPS # lazy import - ps = self.switch_backends(FigureCanvasPS) - printfunc = ps.print_figure - elif ext.find('pdf')>=0: - from backend_pdf import FigureCanvasPdf - pdf = self.switch_backends(FigureCanvasPdf) - printfunc = pdf.print_figure - else: - raise IOError('Do not know know to handle extension *%s' % ext) - - if printfunc is not None: - try: - printfunc(filename, dpi, facecolor, edgecolor, orientation, **kwargs) - except: - # restore the original figure properties - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_canvas(self) - raise - - # restore the original figure properties - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_canvas(self) - - + self.get_renderer()._renderer.write_rgba(str(filename)) + print_rgba = print_raw + + def print_png(self, filename, *args, **kwargs): + self.draw() + self.get_renderer()._renderer.write_png(str(filename)) + Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -488,41 +488,7 @@ class FigureCanvasCairo (FigureCanvasBase): - def print_figure(self, fo, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', format=None, **kwargs): - if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) - # settings for printing - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - if format is None and isinstance (fo, basestring): - # get format from filename extension - format = os.path.splitext(fo)[1][1:] - if format == '': - format = rcParams['cairo.format'] - fo = '%s.%s' % (fo, format) - - if format is not None: - format = format.lower() - - if format == 'png': - self._save_png (fo) - elif format in ('pdf', 'ps', 'svg'): - self._save (fo, format, orientation, **kwargs) - elif format == 'eps': # backend_ps for eps - warnings.warn('eps format is printed by ps backend, not cairo') - from backend_ps import FigureCanvasPS as FigureCanvas - fc = FigureCanvas(self.figure) - fc.print_figure (fo, dpi, facecolor, edgecolor, - orientation, **kwargs) - else: - warnings.warn('Format "%s" is not supported.\n' - 'Supported formats: ' - '%s.' % (format, ', '.join(IMAGE_FORMAT))) - - - def _save_png (self, fobj): + def print_png(self, fobj, *args, **kwargs): width, height = self.get_width_height() renderer = RendererCairo (self.figure.dpi) @@ -532,9 +498,20 @@ self.figure.draw (renderer) surface.write_to_png (fobj) + + def print_pdf(self, fobj, *args, **kwargs): + return self._save(fobj, 'pdf', *args, **kwargs) + def print_ps(self, fobj, *args, **kwargs): + return self._save(fobj, 'ps', *args, **kwargs) - def _save (self, fo, format, orientation, **kwargs): + def print_svg(self, fobj, *args, **kwargs): + return self._save(fobj, 'svg', *args, **kwargs) + + def get_default_filetype(self): + return rcParams['cairo.format'] + + def _save (self, fo, format, **kwargs): # save PDF/PS/SVG orientation = kwargs.get('orientation', 'portrait') Modified: trunk/matplotlib/lib/matplotlib/backends/backend_emf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_emf.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -599,36 +599,17 @@ """ pass - def print_figure(self, filename, dpi=300, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and edge - colors. This is useful because some of the GUIs have a gray figure - face color background and you'll probably want to override this on - hardcopy. - - Following the style of backend_ps and backend_gd - """ - basename, ext = os.path.splitext(filename) - if not ext: - ext = '.emf' - filename += ext - - # set the DPI to this hardcoded value for now, because libEMF - # doesn't allow any changes to the device pixel size (1024 - # pixels per 320 mm) - #dpi=1024.0/320.0*25.4 - #dpi=300 - self.figure.dpi.set(dpi) + filetypes = {'emf': 'Enhanced Metafile'} + + def print_emf(self, filename, dpi=300, **kwargs): width, height = self.figure.get_size_inches() - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - renderer = RendererEMF(filename,width,height,dpi) self.figure.draw(renderer) renderer.save() - + def get_default_filetype(self): + return 'emf' + class FigureManagerEMF(FigureManagerBase): """ Wrap everything up into a window for the pylab interface Modified: trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_fltkagg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -242,17 +242,8 @@ def blit(self,bbox): self.canvas.blit(bbox) - show = draw - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - agg = self.switch_backends(FigureCanvasAgg) - agg.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - self.figure.set_canvas(self) - def widget(self): return self.canvas @@ -493,7 +484,23 @@ def save_figure(ptr,base): + filetypes = base.canvas.get_supported_filetypes() + default_filetype = base.canvas.get_default_filetype() + sorted_filetypes = filetypes.items() + sorted_filetypes.sort() + + selected_filter = 0 + filters = [] + for i, (ext, name) in enumerate(sorted_filetypes): + filter = '%s (*.%s)' % (name, ext) + filters.append(filter) + if ext == default_filetype: + selected_filter = i + filters = '\t'.join(filters) + file_chooser=base._fc + file_chooser.filter(filters) + file_chooser.filter_value(selected_filter) file_chooser.show() while file_chooser.visible() : Fltk.Fl.wait() @@ -507,9 +514,10 @@ #start from last directory lastDir = os.path.dirname(fname) file_chooser.directory(lastDir) - + format = sorted_filetypes[file_chooser.filter_value()][0] + try: - base.canvas.print_figure(fname) + base.canvas.print_figure(fname, format=format) except IOError, msg: err = '\n'.join(map(str, msg)) msg = 'Failed to save %s: Error msg was\n\n%s' % ( Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gd.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gd.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -329,38 +329,15 @@ class FigureCanvasGD(FigureCanvasBase): + filetypes = {'PNG': 'Portable Network Graphics'} - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - - """ - Render the figure to hardcopy using self.renderer as the - renderer if neccessary - - filename can be a string filename or writable file instance - - """ - - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - + def print_png(self, filename, *args, **kwargs): im = self.draw() - - if is_string_like(filename): - basename, ext = os.path.splitext(filename) - if not len(ext): filename += '.png' - - im.writePng( filename ) - - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - + im.writePng(filename) + + def get_default_filetype(self): + return 'png' + def draw(self): """ Draw to a gd image and return the image instance Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -199,26 +199,24 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle): - width, height, descent, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, descent, font_image, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle==90: width, height = height, width x -= width y -= height - imw, imh, image_str = fonts[0].image_as_str() - N = imw*imh + imw = font_image.get_width() + imh = font_image.get_height() + N = imw * imh # a numpixels by num fonts array - Xall = npy.zeros((N,len(fonts)), npy.uint8) + Xall = npy.zeros((N,1), npy.uint8) + + image_str = font_image.as_str() + Xall[:,0] = npy.fromstring(image_str, npy.uint8) - for i, font in enumerate(fonts): - if angle == 90: - font.get_image().rotate() # <-- Rotate - imw, imh, image_str = font.image_as_str() - Xall[:,i] = npy.fromstring(image_str, npy.uint8) - # get the max alpha at each pixel Xs = npy.amax(Xall,axis=1) @@ -342,8 +340,8 @@ def get_text_width_height_descent(self, s, prop, ismath): if ismath: - width, height, descent, fonts, used_characters = self.mathtext_parser.parse( - s, self.dpi.get(), prop) + ox, oy, width, height, descent, font_image, used_characters = \ + self.mathtext_parser.parse(s, self.dpi.get(), prop) return width, height, descent layout, inkRect, logicalRect = self._get_pango_layout(s, prop) @@ -478,55 +476,28 @@ self._renderer.set_width_height (width, height) self.figure.draw (self._renderer) - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - root, ext = os.path.splitext(filename) - ext = ext[1:] - if ext == '': - ext = IMAGE_FORMAT_DEFAULT - filename = filename + '.' + ext + filetypes = FigureCanvasBase.filetypes.copy() + filetypes['jpg'] = 'JPEG' + filetypes['jpeg'] = 'JPEG' - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + def print_jpeg(self, filename, *args, **kwargs): + return self._print_image(filename, 'jpeg') + print_jpg = print_jpeg - ext = ext.lower() - if ext in ('jpg', 'png'): # native printing - width, height = self.get_width_height() - pixmap = gtk.gdk.Pixmap (None, width, height, depth=24) - self._render_figure(pixmap, width, height) + def print_png(self, filename, *args, **kwargs): + return self._print_image(filename, 'png') + + def _print_image(self, filename, format, *args, **kwargs): + width, height = self.get_width_height() + pixmap = gtk.gdk.Pixmap (None, width, height, depth=24) + self._render_figure(pixmap, width, height) - # jpg colors don't match the display very well, png colors match - # better - pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, - width, height) - pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), - 0, 0, 0, 0, width, height) + # jpg colors don't match the display very well, png colors match + # better + pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, + width, height) + pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), + 0, 0, 0, 0, width, height) - # pixbuf.save() recognises 'jpeg' not 'jpg' - if ext == 'jpg': ext = 'jpeg' - - pixbuf.save(filename, ext) - - elif ext in ('eps', 'ps', 'svg',): - if ext == 'svg': - from backend_svg import FigureCanvasSVG as FigureCanvas - else: - from backend_ps import FigureCanvasPS as FigureCanvas - - - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - elif ext in ('bmp', 'raw', 'rgb',): - - from backend_agg import FigureCanvasAgg as FigureCanvas - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, orientation, - **kwargs) - - else: - raise ValueError('Format "%s" is not supported.\nSupported formats are %s.' % - (ext, ', '.join(IMAGE_FORMAT))) - - self.figure.set_canvas(self) + pixbuf.save(filename, format) + Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtk.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -36,14 +36,6 @@ # see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi PIXELS_PER_INCH = 96 -# Image formats that this backend supports - for FileChooser and print_figure() -IMAGE_FORMAT = ['bmp', 'eps', 'jpg', 'png', 'ps', 'svg'] -# pdf not ready yet -#IMAGE_FORMAT = ['bmp', 'eps', 'jpg', 'png', 'pdf', 'ps', 'svg'] -IMAGE_FORMAT.sort() -IMAGE_FORMAT_DEFAULT = 'png' - - cursord = { cursors.MOVE : gdk.Cursor(gdk.FLEUR), cursors.HAND : gdk.Cursor(gdk.HAND2), @@ -344,105 +336,44 @@ self._pixmap, x, y, x, y, w, h) return False # finish event propagation? + filetypes = FigureCanvasBase.filetypes.copy() + filetypes['jpg'] = 'JPEG' + filetypes['jpeg'] = 'JPEG' + filetypes['png'] = 'Portable Network Graphics' - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - # TODO - use gdk/cairo/agg print_figure? - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - root, ext = os.path.splitext(filename) - ext = ext[1:] - if ext == '': - ext = IMAGE_FORMAT_DEFAULT - filename = filename + '.' + ext + def print_jpeg(self, filename, *args, **kwargs): + return self._print_image(filename, 'jpeg') + print_jpg = print_jpeg - # save figure settings - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - origWIn, origHIn = self.figure.get_size_inches() + def print_png(self, filename, *args, **kwargs): + return self._print_image(filename, 'png') + def _print_image(self, filename, format): if self.flags() & gtk.REALIZED == 0: # for self.window(for pixmap) and has a side effect of altering # figure width,height (via configure-event?) gtk.DrawingArea.realize(self) - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - - ext = ext.lower() - if ext in ('jpg', 'png'): # native printing - width, height = self.get_width_height() - pixmap = gdk.Pixmap (self.window, width, height) - self._renderer.set_pixmap (pixmap) - self._render_figure(pixmap, width, height) - - # jpg colors don't match the display very well, png colors match - # better - pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height) - pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), + + width, height = self.get_width_height() + pixmap = gdk.Pixmap (self.window, width, height) + self._renderer.set_pixmap (pixmap) + self._render_figure(pixmap, width, height) + + # jpg colors don't match the display very well, png colors match + # better + pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height) + pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width, height) - # pixbuf.save() recognises 'jpeg' not 'jpg' - if ext == 'jpg': ext = 'jpeg' - try: - pixbuf.save(filename, ext) - except gobject.GError, exc: - error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) + try: + pixbuf.save(filename, format) + except gobject.GError, exc: + error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self) - elif ext in ('eps', 'ps', 'svg',): - if ext == 'svg': - from backend_svg import FigureCanvasSVG as FigureCanvas - else: - from backend_ps import FigureCanvasPS as FigureCanvas + def get_default_filetype(self): + return 'png' - try: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - except IOError, exc: - error_msg_gtk("Save figure failure:\n%s: %s" % - (exc.filename, exc.strerror), parent=self) - except Exception, exc: - error_msg_gtk("Save figure failure:\n%s" % exc, parent=self) - - elif ext in ('bmp', 'raw', 'rgb',): - try: - from backend_agg import FigureCanvasAgg as FigureCanvas - except: - error_msg_gtk('Save figure failure:\n' - 'Agg must be installed to save as bmp, raw and rgb', - parent=self) - else: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - - elif ext in ('pdf',): - try: - from backend_cairo import FigureCanvasCairo as FigureCanvas - except: - error_msg_gtk('Save figure failure:\n' - 'Cairo must be installed to save as pdf', - parent=self) - else: - fc = self.switch_backends(FigureCanvas) - fc.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - - else: - error_msg_gtk('Format "%s" is not supported.\nSupported formats are %s.' % - (ext, ', '.join(IMAGE_FORMAT)), - parent=self) - - # restore figure settings - self.figure.dpi.set(origDPI) - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.set_size_inches(origWIn, origHIn) - self.figure.set_canvas(self) - - + class FigureManagerGTK(FigureManagerBase): """ Public attributes @@ -685,14 +616,20 @@ self.show_all() - self.fileselect = FileChooserDialog(title='Save the figure', - parent=self.win,) + self.fileselect = FileChooserDialog( + title='Save the figure', + parent=self.win, + filetypes=self.canvas.get_supported_filetypes(), + default_filetype=self.canvas.get_default_filetype()) def save_figure(self, button): - fname = self.fileselect.get_filename_from_user() + fname, format = self.fileselect.get_filename_from_user() if fname: - self.canvas.print_figure(fname) + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) def configure_subplots(self, button): toolfig = Figure(figsize=(6,3)) @@ -777,8 +714,11 @@ if gtk.pygtk_version >= (2,4,0): self._create_toolitems_2_4() self.update = self._update_2_4 - self.fileselect = FileChooserDialog(title='Save the figure', - parent=self.win,) + self.fileselect = FileChooserDialog( + title='Save the figure', + parent=self.win, + formats=self.canvas.get_supported_filetypes(), + default_type=self.canvas.get_default_filetype()) else: self._create_toolitems_2_2() self.update = self._update_2_2 @@ -999,35 +939,13 @@ def save_figure(self, button): - fname = self.fileselect.get_filename_from_user() + fname, format = self.fileselect.get_filename_from_user() if fname: - self.canvas.print_figure(fname) + try: + self.canvas.print_figure(fname, format=format) + except Exception, e: + error_msg_gtk(str(e), parent=self) - -class FileSelection(gtk.FileSelection): - """GTK+ 2.2 and lower file selector which remembers the last - file/directory selected - """ - def __init__(self, path=None, title='Select a file', parent=None): - super(FileSelection, self).__init__(title) - - if path: self.path = path - else: self.path = os.getcwd() + os.sep - - if parent: self.set_transient_for(parent) - - def get_filename_from_user(self, path=None, title=None): - if path: self.path = path - if title: self.set_title(title) - self.set_filename(self.path) - - filename = None - if self.run() == gtk.RESPONSE_OK: - self.path = filename = self.get_filename() - self.hide() - return filename - - if gtk.pygtk_version >= (2,4,0): class FileChooserDialog(gtk.FileChooserDialog): """GTK+ 2.4 file selector which remembers the last file/directory @@ -1040,6 +958,8 @@ buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK), path = None, + filetypes = [], + default_filetype = None ): super (FileChooserDialog, self).__init__ (title, parent, action, buttons) @@ -1049,10 +969,10 @@ # create an extra widget to list supported image formats self.set_current_folder (path) - self.set_current_name ('image.' + IMAGE_FORMAT_DEFAULT) + self.set_current_name ('image.' + default_filetype) hbox = gtk.HBox (spacing=10) - hbox.pack_start (gtk.Label ("Image Format:"), expand=False) + hbox.pack_start (gtk.Label ("File Format:"), expand=False) liststore = gtk.ListStore(gobject.TYPE_STRING) cbox = gtk.ComboBox(liststore) @@ -1061,21 +981,27 @@ cbox.add_attribute(cell, 'text', 0) hbox.pack_start (cbox) - for item in IMAGE_FORMAT: - cbox.append_text (item) - cbox.set_active (IMAGE_FORMAT.index (IMAGE_FORMAT_DEFAULT)) - self.ext = IMAGE_FORMAT_DEFAULT + self.filetypes = filetypes + self.sorted_filetypes = filetypes.items() + self.sorted_filetypes.sort() + default = 0 + for i, (ext, name) in enumerate(self.sorted_filetypes): + cbox.append_text ("%s (*.%s)" % (name, ext)) + if ext == default_filetype: + default = i + cbox.set_active(default) + self.ext = default_filetype def cb_cbox_changed (cbox, data=None): """File extension changed""" head, filename = os.path.split(self.get_filename()) root, ext = os.path.splitext(filename) ext = ext[1:] - new_ext = IMAGE_FORMAT[cbox.get_active()] + new_ext = self.sorted_filetypes[cbox.get_active()][0] self.ext = new_ext - if ext in IMAGE_FORMAT: - filename = filename.replace(ext, new_ext) + if ext in self.filetypes: + filename = root + '.' + new_ext elif ext == '': filename = filename.rstrip('.') + '.' + new_ext @@ -1091,24 +1017,40 @@ if self.run() != gtk.RESPONSE_OK: break filename = self.get_filename() - root, ext = os.path.splitext (filename) - ext = ext[1:] - if ext == '': - ext = self.ext - filename += '.' + ext + break + + self.hide() + return filename, self.ext +else: + class FileSelection(gtk.FileSelection): + """GTK+ 2.2 and lower file selector which remembers the last + file/directory selected + """ + def __init__(self, path=None, title='Select a file', parent=None): + super(FileSelection, self).__init__(title) - if ext in IMAGE_FORMAT: - self.path = filename - break - else: - error_msg_gtk ('Image format "%s" is not supported' % ext, - parent=self) - self.set_current_name (os.path.split(root)[1] + '.' + - self.ext) + if path: self.path = path + else: self.path = os.getcwd() + os.sep + if parent: self.set_transient_for(parent) + + def get_filename_from_user(self, path=None, title=None): + if path: self.path = path + if title: self.set_title(title) + self.set_filename(self.path) + + filename = None + if self.run() == gtk.RESPONSE_OK: + self.path = filename = self.get_filename() self.hide() - return filename + ext = None + if filename is not None: + ext = os.path.splitext(filename)[1] + if ext.startswith('.'): + ext = ext[1:] + return filename, ext + class DialogLineprops: """ Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtkagg.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -45,7 +45,9 @@ if DEBUG: print 'backend_gtkagg.new_figure_manager done' class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg): - + filetypes = FigureCanvasGTK.filetypes.copy() + filetypes.update(FigureCanvasAgg.filetypes) + def configure_event(self, widget, event=None): if DEBUG: print 'FigureCanvasGTKAgg.configure_event' @@ -95,34 +97,7 @@ 0, 0, 0, 0, w, h) if DEBUG: print 'FigureCanvasGTKAgg.done' - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - if DEBUG: print 'FigureCanvasGTKAgg.print_figure' - # delete the renderer to prevent improper blitting after print - if dpi is None: dpi = matplotlib.rcParams['savefig.dpi'] - root, ext = os.path.splitext(filename) - ext = ext.lower()[1:] - if ext == 'jpg': - FigureCanvasGTK.print_figure(self, filename, dpi, facecolor, - edgecolor, orientation, **kwargs) - - else: - agg = self.switch_backends(FigureCanvasAgg) - try: - agg.print_figure(filename, dpi, facecolor, edgecolor, - orientation, **kwargs) - except IOError, msg: - error_msg_gtk('Failed to save\nError message: %s'%(msg,), self) - except: - self.figure.set_canvas(self) - raise - - self.figure.set_canvas(self) - if DEBUG: print 'FigureCanvasGTKAgg.print_figure done' - - - """\ Traceback (most recent call last): File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtk.py", line 304, in expose_event Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gtkcairo.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -39,7 +39,10 @@ self.ctx.save() # restore, save - when call new_gc() -class FigureCanvasGTKCairo(FigureCanvasGTK): +class FigureCanvasGTKCairo(backend_cairo.FigureCanvasCairo, FigureCanvasGTK): + filetypes = FigureCanvasGTK.filetypes.copy() + filetypes.update(backend_cairo.FigureCanvasCairo.filetypes) + def _renderer_init(self): """Override to use cairo (rather than GDK) renderer""" if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_paint.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_paint.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -240,31 +240,14 @@ self.figure.draw(renderer) return renderer - def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', - orientation='portrait, '**kwargs): - - """ - Render the figure to hardcopy using self.renderer as the - renderer if neccessary - """ - origDPI = self.figure.dpi.get() - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - - self.figure.dpi.set(dpi) - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) - + filetypes = {'png': 'Portable Network Graphics'} + + def print_png(self, filename, *args, **kwargs): renderer = self.draw() - - basename, ext = os.path.splitext(filename) - if not len(ext): filename += '.png' renderer.image.write_png(filename) - # now restore the old figure params - self.figure.set_facecolor(origfacecolor) - self.figure.set_edgecolor(origedgecolor) - self.figure.dpi.set(origDPI) + 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-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -1869,25 +1869,15 @@ def draw(self): pass - def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', - orientation='portrait', **kwargs): - """ - Render the figure to hardcopy. Set the figure patch face and edge - colors. This is useful because some of the GUIs have a gray figure - face color background and you'll probably want to override this on - hardcopy. - - orientation - only currently applies to PostScript printing. - """ - self.figure.dpi.set(72) # ignore the dpi kwarg - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + filetypes = {'pdf': 'Portable Document Format'} + + def get_default_filetype(self): + return 'pdf' + + def print_pdf(self, filename, **kwargs): + dpi = kwargs.get('dpi', None) + self.figure.set_dpi(72) # Override the dpi kwarg width, height = self.figure.get_size_inches() - - basename, ext = os.path.splitext(filename) - if ext == '': - filename += '.pdf' - file = PdfFile(width, height, filename) renderer = RendererPdf(file, dpi) self.figure.draw(renderer) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-06 14:46:49 UTC (rev 3797) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-06 18:50:08 UTC (rev 3798) @@ -960,8 +960,46 @@ def draw(self): pass - def print_figure(self, outfile, dpi=72, facecolor='w', edgecolor='w', - orientation='portrait', papertype=None): + filetypes = {'ps' : 'Postscript', + 'eps' : 'Encapsulated Postscript'} + + def get_default_filetype(self): + return 'ps' + + def print_ps(self, outfile, *args, **kwargs): + return self._print_ps(outfile, 'ps', *args, **kwargs) + + def print_eps(self, outfile, *args, **kwargs): + return self._print_ps(outfile, 'eps', *args, **kwargs) + + def _print_ps(self, outfile, format, *args, **kwargs): + papertype = kwargs.get("papertype", rcParams['ps.papersize']) + papertype = papertype.lower() + if papertype == 'auto': + pass + elif papertype not in papersize: + raise RuntimeError( '%s is not a valid papertype. Use one \ + of %s'% (papertype, ', '.join( papersize.keys() )) ) + + orientation = kwargs.get("orientation", "portrait").lower() + if orientation == 'landscape': isLandscape = True + elif orientation == 'portrait': isLandscape = False + else: raise RuntimeError('Orientation must be "portrait" or "landscape"') + + self.figure.set_dpi(72) # Override the dpi kwarg + dpi = kwargs.get("dpi", 72) + facecolor = kwargs.get("facecolor", "w") + edgecolor = kwargs.get("edgecolor", "w") + + if rcParams['text.usetex']: + self._print_figure_tex(outfile, format, dpi, facecolor, edgecolor, + orientation, isLandscape, papertype) + else: + self._print_figure(outfile, format, dpi, facecolor, edgecolor, + orientation, isLandscape, papertype) + + def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', + orientation='portrait', isLandscape=False, papertype=None): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a @@ -975,176 +1013,137 @@ If outfile is a file object, a stand-alone PostScript file is written into this file object. """ - if not papertype: papertype = rcParams['ps.papersize'] - papertype = papertype.lower() - if papertype == 'auto': pass - elif not papersize.has_key(papertype): - raise RuntimeError( '%s is not a valid papertype. Use one \ - of %s'% (papertype, ', '.join( papersize.keys() )) ) + isEPSF = format == 'eps' + title = outfile - orientation = orientation.lower() - if orientation == 'landscape': isLandscape = True - elif orientation == 'portrait': isLandscape = False - else: raise RuntimeError('Orientation must be "portrait" or "landscape"') + # write to a temp file, we'll move it to outfile when done + tmpfile = os.path.join(gettempdir(), md5.md5(outfile).hexdigest()) + fh = file(tmpfile, 'w') - self.figure.dpi.set(72) # ignore the dpi kwarg + # find the appropriate papertype + width, height = self.figure.get_size_inches() + if papertype == 'auto': + if isLandscape: papertype = _get_papertype(height, width) + else: papertype = _get_papertype(width, height) - if rcParams['text.usetex']: - # Let's keep the usetex stuff seperate from the generic postscript - self._print_figure_tex(outfile, dpi, facecolor, edgecolor, - orientation, papertype) - else: - if isinstance(outfile, file): - # assume plain PostScript and write to fileobject - basename = outfile.name - ext = '.ps' - title = None - else: - basename, ext = os.path.splitext(outfile) - if not ext: - ext = '.ps' - outfile += ext - isEPSF = ext.lower().startswith('.ep') - title = outfile + if isLandscape: paperHeight, paperWidth = papersize[papertype] + else: paperWidth, paperHeight = papersize[papertype] - # write to a temp file, we'll move it to outfile when done - tmpfile = os.path.join(gettempdir(), md5.md5(basename).hexdigest()) - fh = file(tmpfile, 'w') + if rcParams['ps.usedistiller'] and not papertype == 'auto': + # distillers will improperly clip eps files if the pagesize is + # too small + if width>paperWidth or height>paperHeight: + if isLandscape: + papertype = _get_papertype(height, width) + paperHeight, paperWidth = papersize[papertype] + else: + papertype = _get_papertype(width, height) + paperWidth, paperHeight = papersize[papertype] - # find the appropriate papertype - width, height = self.figure.get_size_inches() - if papertype == 'auto': - if isLandscape: papertype = _get_papertype(height, width) - else: papertype = _get_papertype(width, height) + # center the figure on the paper + xo = 72*0.5*(paperWidth - width) + yo = 72*0.5*(paperHeight - height) - if isLandscape: paperHeight, paperWidth = papersize[papertype] - else: paperWidth, paperHeight = papersize[papertype] + l, b, w, h = self.figure.bbox.get_bounds() + llx = xo + lly = yo + urx = llx + w + ury = lly + h + rotation = 0 + if isLandscape: + llx, lly, urx, ury = lly, llx, ury, urx + xo, yo = 72*paperHeight - yo, xo + rotation = 90 + bbox = (llx, lly, urx, ury) - if rcParams['ps.usedistiller'] and not papertype == 'auto': - # distillers will improperly clip eps files if the pagesize is - # too small - if width>paperWidth or height>paperHeight: - if isLandscape: - papertype = _get_papertype(height, width) - paperHeight, paperWidth = papersize[papertype] - else: - papertype = _get_papertype(width, height) - paperWidth, paperHeight = papersize[papertype] + # generate PostScript code for the figure and store it in a string + origfacecolor = self.figure.get_facecolor() + origedgecolor = self.figure.get_edgecolor() + self.figure.set_facecolor(facecolor) + self.figure.set_edgecolor(edgecolor) - # center the figure on the paper - xo = 72*0.5*(paperWidth - width) - yo = 72*0.5*(paperHeight - height) + self._pswriter = StringIO() + renderer = RendererPS(width, height, self._pswriter, dpi=dpi) + self.figure.draw(renderer) - l, b, w, h = self.figure.bbox.get_bounds() - llx = xo - lly = yo - urx = llx + w - ury = lly + h - rotation = 0 - if isLandscape: - llx, lly, urx, ury = lly, llx, ury, urx - xo, yo = 72*paperHeight - yo, xo - rotation = 90 - bbox = (llx, lly, urx, ury) + self.figure.set_facecolor(origfacecolor) + self.figure.set_edgecolor(origedgecolor) - # generate PostScript code for the figure and store it in a string - origfacecolor = self.figure.get_facecolor() - origedgecolor = self.figure.get_edgecolor() - self.figure.set_facecolor(facecolor) - self.figure.set_edgecolor(edgecolor) + # write the PostScript headers + if isEPSF: print >>fh, "%!PS-Adobe-3.0 EPSF-3.0" + else: print >>fh, "%!PS-Adobe-3.0" + if title: print >>fh, "%%Title: "+title + print >>fh, ("%%Creator: matplotlib version " + +__version__+", http://matplotlib.sourceforge... [truncated message content] |