3434from six .moves import xrange
3535
3636import os
37+ import sys
3738import warnings
3839import time
3940import io
5657from matplotlib .path import Path
5758from matplotlib .cbook import mplDeprecation
5859
60+ try :
61+ from importlib import import_module
62+ except :
63+ # simple python 2.6 implementation (no relative imports)
64+ def import_module (name ):
65+ __import__ (name )
66+ return sys .modules [name ]
67+
5968try :
6069 from PIL import Image
6170 _has_pil = True
6271except ImportError :
6372 _has_pil = False
6473
65- _backend_d = {}
74+
75+ _default_filetypes = {
76+ 'ps' : 'Postscript' ,
77+ 'eps' : 'Encapsulated Postscript' ,
78+ 'pdf' : 'Portable Document Format' ,
79+ 'pgf' : 'PGF code for LaTeX' ,
80+ 'png' : 'Portable Network Graphics' ,
81+ 'raw' : 'Raw RGBA bitmap' ,
82+ 'rgba' : 'Raw RGBA bitmap' ,
83+ 'svg' : 'Scalable Vector Graphics' ,
84+ 'svgz' : 'Scalable Vector Graphics'
85+ }
86+
87+
88+ _default_backends = {
89+ 'ps' : 'matplotlib.backends.backend_ps' ,
90+ 'eps' : 'matplotlib.backends.backend_ps' ,
91+ 'pdf' : 'matplotlib.backends.backend_pdf' ,
92+ 'pgf' : 'matplotlib.backends.backend_pgf' ,
93+ 'png' : 'matplotlib.backends.backend_agg' ,
94+ 'raw' : 'matplotlib.backends.backend_agg' ,
95+ 'rgba' : 'matplotlib.backends.backend_agg' ,
96+ 'svg' : 'matplotlib.backends.backend_svg' ,
97+ 'svgz' : 'matplotlib.backends.backend_svg' ,
98+ }
99+
100+
101+ def register_backend (format , backend , description ):
102+ """
103+ Register a backend for saving to a given file format.
104+
105+ *format*
106+ File extention
107+
108+ *backend*
109+ Backend for handling file output (module string or canvas class)
110+
111+ *description*
112+ Description of the file type
113+ """
114+ _default_backends [format ] = backend
115+ _default_filetypes [format ] = description
66116
67117
68- def register_backend (format , backend_class ):
69- _backend_d [format ] = backend_class
118+ def get_registered_canvas_class (format ):
119+ """
120+ Return the registered default canvas for given file format.
121+ Handles deferred import of required backend.
122+ """
123+ if format not in _default_backends :
124+ return None
125+ backend_class = _default_backends [format ]
126+ if cbook .is_string_like (backend_class ):
127+ backend_class = import_module (backend_class ).FigureCanvas
128+ _default_backends [format ] = backend_class
129+ return backend_class
70130
71131
72132class ShowBase (object ):
@@ -1566,6 +1626,20 @@ class FigureCanvasBase(object):
15661626
15671627 supports_blit = True
15681628
1629+ filetypes = _default_filetypes
1630+ if _has_pil :
1631+ # JPEG support
1632+ register_backend ('jpg' , 'matplotlib.backends.backend_agg' ,
1633+ 'Joint Photographic Experts Group' )
1634+ register_backend ('jpeg' , 'matplotlib.backends.backend_agg' ,
1635+ 'Joint Photographic Experts Group' )
1636+
1637+ # TIFF support
1638+ register_backend ('tif' , 'matplotlib.backends.backend_agg' ,
1639+ 'Tagged Image File Format' )
1640+ register_backend ('tiff' , 'matplotlib.backends.backend_agg' ,
1641+ 'Tagged Image File Format' )
1642+
15691643 def __init__ (self , figure ):
15701644 figure .set_canvas (self )
15711645 self .figure = figure
@@ -1927,119 +2001,6 @@ def get_width_height(self):
19272001 """
19282002 return int (self .figure .bbox .width ), int (self .figure .bbox .height )
19292003
1930- filetypes = {
1931- 'eps' : 'Encapsulated Postscript' ,
1932- 'pdf' : 'Portable Document Format' ,
1933- 'pgf' : 'LaTeX PGF Figure' ,
1934- 'png' : 'Portable Network Graphics' ,
1935- 'ps' : 'Postscript' ,
1936- 'raw' : 'Raw RGBA bitmap' ,
1937- 'rgba' : 'Raw RGBA bitmap' ,
1938- 'svg' : 'Scalable Vector Graphics' ,
1939- 'svgz' : 'Scalable Vector Graphics' }
1940-
1941- # All of these print_* functions do a lazy import because
1942- # a) otherwise we'd have cyclical imports, since all of these
1943- # classes inherit from FigureCanvasBase
1944- # b) so we don't import a bunch of stuff the user may never use
1945-
1946- # TODO: these print_* throw ImportErrror when called from
1947- # compare_images_decorator (decorators.py line 112)
1948- # if the backend has not already been loaded earlier on. Simple trigger:
1949- # >>> import matplotlib.tests.test_spines
1950- # >>> list(matplotlib.tests.test_spines.test_spines_axes_positions())[0][0]()
1951-
1952- def print_eps (self , * args , ** kwargs ):
1953- from .backends .backend_ps import FigureCanvasPS # lazy import
1954- ps = self .switch_backends (FigureCanvasPS )
1955- return ps .print_eps (* args , ** kwargs )
1956-
1957- def print_pdf (self , * args , ** kwargs ):
1958- from .backends .backend_pdf import FigureCanvasPdf # lazy import
1959- pdf = self .switch_backends (FigureCanvasPdf )
1960- return pdf .print_pdf (* args , ** kwargs )
1961-
1962- def print_pgf (self , * args , ** kwargs ):
1963- from .backends .backend_pgf import FigureCanvasPgf # lazy import
1964- pgf = self .switch_backends (FigureCanvasPgf )
1965- return pgf .print_pgf (* args , ** kwargs )
1966-
1967- def print_png (self , * args , ** kwargs ):
1968- from .backends .backend_agg import FigureCanvasAgg # lazy import
1969- agg = self .switch_backends (FigureCanvasAgg )
1970- return agg .print_png (* args , ** kwargs )
1971-
1972- def print_ps (self , * args , ** kwargs ):
1973- from .backends .backend_ps import FigureCanvasPS # lazy import
1974- ps = self .switch_backends (FigureCanvasPS )
1975- return ps .print_ps (* args , ** kwargs )
1976-
1977- def print_raw (self , * args , ** kwargs ):
1978- from .backends .backend_agg import FigureCanvasAgg # lazy import
1979- agg = self .switch_backends (FigureCanvasAgg )
1980- return agg .print_raw (* args , ** kwargs )
1981- print_bmp = print_rgba = print_raw
1982-
1983- def print_svg (self , * args , ** kwargs ):
1984- from .backends .backend_svg import FigureCanvasSVG # lazy import
1985- svg = self .switch_backends (FigureCanvasSVG )
1986- return svg .print_svg (* args , ** kwargs )
1987-
1988- def print_svgz (self , * args , ** kwargs ):
1989- from .backends .backend_svg import FigureCanvasSVG # lazy import
1990- svg = self .switch_backends (FigureCanvasSVG )
1991- return svg .print_svgz (* args , ** kwargs )
1992-
1993- if _has_pil :
1994- filetypes ['jpg' ] = 'Joint Photographic Experts Group'
1995- filetypes ['jpeg' ] = filetypes ['jpg' ]
1996-
1997- def print_jpg (self , filename_or_obj , * args , ** kwargs ):
1998- """
1999- Supported kwargs:
2000-
2001- *quality*: The image quality, on a scale from 1 (worst) to
2002- 95 (best). The default is 95, if not given in the
2003- matplotlibrc file in the savefig.jpeg_quality parameter.
2004- Values above 95 should be avoided; 100 completely
2005- disables the JPEG quantization stage.
2006-
2007- *optimize*: If present, indicates that the encoder should
2008- make an extra pass over the image in order to select
2009- optimal encoder settings.
2010-
2011- *progressive*: If present, indicates that this image
2012- should be stored as a progressive JPEG file.
2013- """
2014- from .backends .backend_agg import FigureCanvasAgg # lazy import
2015- agg = self .switch_backends (FigureCanvasAgg )
2016- buf , size = agg .print_to_buffer ()
2017- if kwargs .pop ("dryrun" , False ):
2018- return
2019- image = Image .frombuffer ('RGBA' , size , buf , 'raw' , 'RGBA' , 0 , 1 )
2020- options = cbook .restrict_dict (kwargs , ['quality' , 'optimize' ,
2021- 'progressive' ])
2022-
2023- if 'quality' not in options :
2024- options ['quality' ] = rcParams ['savefig.jpeg_quality' ]
2025-
2026- return image .save (filename_or_obj , format = 'jpeg' , ** options )
2027- print_jpeg = print_jpg
2028-
2029- filetypes ['tif' ] = filetypes ['tiff' ] = 'Tagged Image File Format'
2030-
2031- def print_tif (self , filename_or_obj , * args , ** kwargs ):
2032- from .backends .backend_agg import FigureCanvasAgg # lazy import
2033- agg = self .switch_backends (FigureCanvasAgg )
2034- buf , size = agg .print_to_buffer ()
2035- if kwargs .pop ("dryrun" , False ):
2036- return
2037- image = Image .frombuffer ('RGBA' , size , buf , 'raw' , 'RGBA' , 0 , 1 )
2038- dpi = (self .figure .dpi , self .figure .dpi )
2039- return image .save (filename_or_obj , format = 'tiff' ,
2040- dpi = dpi )
2041- print_tiff = print_tif
2042-
20432004 @classmethod
20442005 def get_supported_filetypes (cls ):
20452006 """Return dict of savefig file formats supported by this backend"""
@@ -2057,29 +2018,23 @@ def get_supported_filetypes_grouped(cls):
20572018 groupings [name ].sort ()
20582019 return groupings
20592020
2060- def _get_print_method (self , format ):
2021+ def _get_print_canvas (self , format ):
20612022 method_name = 'print_%s' % format
20622023
2063- # check for registered backends
2064- if format in _backend_d :
2065- backend_class = _backend_d [format ]
2066-
2067- def _print_method (* args , ** kwargs ):
2068- backend = self .switch_backends (backend_class )
2069- print_method = getattr (backend , method_name )
2070- return print_method (* args , ** kwargs )
2071-
2072- return _print_method
2024+ # check if this canvas supports the requested format
2025+ if hasattr (self , method_name ):
2026+ return self
20732027
2074- formats = self .get_supported_filetypes ()
2075- if (format not in formats or not hasattr (self , method_name )):
2076- formats = sorted (formats )
2077- raise ValueError (
2078- 'Format "%s" is not supported.\n '
2079- 'Supported formats: '
2080- '%s.' % (format , ', ' .join (formats )))
2028+ # check if there is a default canvas for the requested format
2029+ canvas_class = get_registered_canvas_class (format )
2030+ if canvas_class :
2031+ return self .switch_backends (canvas_class )
20812032
2082- return getattr (self , method_name )
2033+ # else report error for unsupported format
2034+ formats = sorted (self .get_supported_filetypes ())
2035+ raise ValueError ('Format "%s" is not supported.\n '
2036+ 'Supported formats: '
2037+ '%s.' % (format , ', ' .join (formats )))
20832038
20842039 def print_figure (self , filename , dpi = None , facecolor = 'w' , edgecolor = 'w' ,
20852040 orientation = 'portrait' , format = None , ** kwargs ):
@@ -2136,7 +2091,9 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
21362091 filename = filename .rstrip ('.' ) + '.' + format
21372092 format = format .lower ()
21382093
2139- print_method = self ._get_print_method (format )
2094+ # get canvas object and print method for format
2095+ canvas = self ._get_print_canvas (format )
2096+ print_method = getattr (canvas , 'print_%s' % format )
21402097
21412098 if dpi is None :
21422099 dpi = rcParams ['savefig.dpi' ]
0 commit comments