From 9add8145e940e5ecf37c43144b857af53707a86e 2014-02-06 22:11:13 From: Brian E. Granger Date: 2014-02-06 22:11:13 Subject: [PATCH] Adding support for multiple figure formats in InlineBackend. --- diff --git a/IPython/core/pylabtools.py b/IPython/core/pylabtools.py index a8779d2..f232404 100644 --- a/IPython/core/pylabtools.py +++ b/IPython/core/pylabtools.py @@ -25,6 +25,7 @@ from io import BytesIO from IPython.core.display import _pngxy from IPython.utils.decorators import flag_calls +from IPython.utils import py3compat # If user specifies a GUI, that dictates the backend, otherwise we read the # user's mpl default from the mpl rc structure @@ -165,10 +166,15 @@ def mpl_runner(safe_execfile): return mpl_execfile -def select_figure_format(shell, fmt, quality=90): - """Select figure format for inline backend, can be 'png', 'retina', 'jpg', or 'svg'. +def select_figure_format(shell, formats, quality=90): + """Select figure formats for the inline backend. - Using this method ensures only one figure format is active at a time. + Parameters + ========== + shell : InteractiveShell + The main IPython instance + formats : list + One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'. """ from matplotlib.figure import Figure from IPython.kernel.zmq.pylab import backend_inline @@ -176,22 +182,26 @@ def select_figure_format(shell, fmt, quality=90): svg_formatter = shell.display_formatter.formatters['image/svg+xml'] png_formatter = shell.display_formatter.formatters['image/png'] jpg_formatter = shell.display_formatter.formatters['image/jpeg'] + pdf_formatter = shell.display_formatter.formatters['application/pdf'] - [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ] + if isinstance(formats, py3compat.string_types): + formats = {formats} - if fmt == 'png': - png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png')) - elif fmt in ('png2x', 'retina'): - png_formatter.for_type(Figure, retina_figure) - elif fmt in ('jpg', 'jpeg'): - jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality)) - elif fmt == 'svg': - svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg')) - else: - raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', not %r" % fmt) + [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ] - # set the format to be used in the backend() - backend_inline._figure_format = fmt + for fmt in formats: + if fmt == 'png': + png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png')) + elif fmt in ('png2x', 'retina'): + png_formatter.for_type(Figure, retina_figure) + elif fmt in ('jpg', 'jpeg'): + jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality)) + elif fmt == 'svg': + svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg')) + elif fmt == 'pdf': + pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf')) + else: + raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %r" % fmt) #----------------------------------------------------------------------------- # Code for initializing matplotlib and importing pylab @@ -342,5 +352,5 @@ def configure_inline_support(shell, backend): del shell._saved_rcParams # Setup the default figure format - select_figure_format(shell, cfg.figure_format, cfg.quality) + select_figure_format(shell, cfg.figure_formats, cfg.quality) diff --git a/IPython/kernel/zmq/pylab/config.py b/IPython/kernel/zmq/pylab/config.py index 922ef5f..13b7225 100644 --- a/IPython/kernel/zmq/pylab/config.py +++ b/IPython/kernel/zmq/pylab/config.py @@ -14,7 +14,9 @@ This module does not import anything from matplotlib. #----------------------------------------------------------------------------- from IPython.config.configurable import SingletonConfigurable -from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, Bool, Int, TraitError +from IPython.utils.traitlets import ( + Dict, Instance, CaselessStrEnum, Set, Bool, Int, TraitError, Unicode +) from IPython.utils.warn import warn #----------------------------------------------------------------------------- @@ -63,15 +65,13 @@ class InlineBackend(InlineBackendConfig): inline backend.""" ) + figure_formats = Set({'png'}, config=True, + help="""A set of figure formats to enable: 'png', + 'retina', 'jpeg', 'svg', 'pdf'.""") - figure_format = CaselessStrEnum(['svg', 'png', 'retina', 'jpg'], - default_value='png', config=True, - help="""The image format for figures with the inline - backend. JPEG requires the PIL/Pillow library.""") - - def _figure_format_changed(self, name, old, new): + def _figure_formats_changed(self, name, old, new): from IPython.core.pylabtools import select_figure_format - if new in {"jpg", "jpeg"}: + if 'jpg' in new or 'jpeg' in new: if not pil_available(): raise TraitError("Requires PIL/Pillow for JPG figures") if self.shell is None: @@ -79,6 +79,12 @@ class InlineBackend(InlineBackendConfig): else: select_figure_format(self.shell, new) + figure_format = Unicode() + + def _figure_format_changed(self, name, old, new): + if new: + self.figure_formats = {new} + quality = Int(default_value=90, config=True, help="Quality of compression [10-100], currently for lossy JPEG only.")