##// END OF EJS Templates
add InlineBackend.print_figure_kwargs...
MinRK -
Show More
@@ -95,9 +95,11 b' def figsize(sizex, sizey):'
95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
96
96
97
97
98 def print_figure(fig, fmt='png', quality=90):
98 def print_figure(fig, fmt='png', **kwargs):
99 """Convert a figure to svg, png or jpg for inline display.
99 """Print a figure to an image, and return the resulting bytes
100 Quality is only relevant for jpg.
100
101 Any extra keyword args are passed to fig.canvas.print_figure,
102 such as ``quality`` or ``bbox_inches``.
101 """
103 """
102 from matplotlib import rcParams
104 from matplotlib import rcParams
103 # When there's an empty figure, we shouldn't return anything, otherwise we
105 # When there's an empty figure, we shouldn't return anything, otherwise we
@@ -105,21 +107,29 b" def print_figure(fig, fmt='png', quality=90):"
105 if not fig.axes and not fig.lines:
107 if not fig.axes and not fig.lines:
106 return
108 return
107
109
108 fc = fig.get_facecolor()
109 ec = fig.get_edgecolor()
110 bytes_io = BytesIO()
111 dpi = rcParams['savefig.dpi']
110 dpi = rcParams['savefig.dpi']
112 if fmt == 'retina':
111 if fmt == 'retina':
113 dpi = dpi * 2
112 dpi = dpi * 2
114 fmt = 'png'
113 fmt = 'png'
115 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
116 facecolor=fc, edgecolor=ec, dpi=dpi, quality=quality)
117 data = bytes_io.getvalue()
118 return data
119
114
120 def retina_figure(fig):
115 # build keyword args
116 kw = dict(
117 format=fmt,
118 fc=fig.get_facecolor(),
119 ec=fig.get_edgecolor(),
120 dpi=dpi,
121 )
122 # **kwargs get higher priority
123 kw.update(kwargs)
124 print(kw)
125
126 bytes_io = BytesIO()
127 fig.canvas.print_figure(bytes_io, **kw)
128 return bytes_io.getvalue()
129
130 def retina_figure(fig, **kwargs):
121 """format a figure as a pixel-doubled (retina) PNG"""
131 """format a figure as a pixel-doubled (retina) PNG"""
122 pngdata = print_figure(fig, fmt='retina')
132 pngdata = print_figure(fig, fmt='retina', **kwargs)
123 w, h = _pngxy(pngdata)
133 w, h = _pngxy(pngdata)
124 metadata = dict(width=w//2, height=h//2)
134 metadata = dict(width=w//2, height=h//2)
125 return pngdata, metadata
135 return pngdata, metadata
@@ -166,17 +176,17 b' def mpl_runner(safe_execfile):'
166 return mpl_execfile
176 return mpl_execfile
167
177
168
178
169 def select_figure_formats(shell, formats, quality=90):
179 def select_figure_formats(shell, formats, **kwargs):
170 """Select figure formats for the inline backend.
180 """Select figure formats for the inline backend.
171
181
172 Parameters
182 Parameters
173 ==========
183 ==========
174 shell : InteractiveShell
184 shell : InteractiveShell
175 The main IPython instance.
185 The main IPython instance.
176 formats : list
186 formats : str or set
177 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
187 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
178 quality : int
188 **kwargs : any
179 A percentage for the quality of JPEG figures.
189 Extra keyword arguments to be passed to fig.canvas.print_figure.
180 """
190 """
181 from matplotlib.figure import Figure
191 from matplotlib.figure import Figure
182 from IPython.kernel.zmq.pylab import backend_inline
192 from IPython.kernel.zmq.pylab import backend_inline
@@ -188,22 +198,27 b' def select_figure_formats(shell, formats, quality=90):'
188
198
189 if isinstance(formats, py3compat.string_types):
199 if isinstance(formats, py3compat.string_types):
190 formats = {formats}
200 formats = {formats}
201 # cast in case of list / tuple
202 formats = set(formats)
191
203
192 [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ]
204 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
193
205
194 for fmt in formats:
206 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
195 if fmt == 'png':
207 bad = formats.difference(supported)
196 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
208 if bad:
197 elif fmt in ('png2x', 'retina'):
209 s = "{%s}" % ",".join([repr(f) for f in bad])
198 png_formatter.for_type(Figure, retina_figure)
210 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %s" % s)
199 elif fmt in ('jpg', 'jpeg'):
211
200 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality))
212 if 'png' in formats:
201 elif fmt == 'svg':
213 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
202 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
214 if 'retina' in formats or 'png2x' in formats:
203 elif fmt == 'pdf':
215 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
204 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf'))
216 if 'jpg' in formats or 'jpeg' in formats:
205 else:
217 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
206 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %r" % fmt)
218 if 'svg' in formats:
219 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
220 if 'pdf' in formats:
221 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
207
222
208 #-----------------------------------------------------------------------------
223 #-----------------------------------------------------------------------------
209 # Code for initializing matplotlib and importing pylab
224 # Code for initializing matplotlib and importing pylab
@@ -354,5 +369,5 b' def configure_inline_support(shell, backend):'
354 del shell._saved_rcParams
369 del shell._saved_rcParams
355
370
356 # Setup the default figure format
371 # Setup the default figure format
357 select_figure_formats(shell, cfg.figure_formats, cfg.quality)
372 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
358
373
@@ -69,6 +69,10 b' class InlineBackend(InlineBackendConfig):'
69 help="""A set of figure formats to enable: 'png',
69 help="""A set of figure formats to enable: 'png',
70 'retina', 'jpeg', 'svg', 'pdf'.""")
70 'retina', 'jpeg', 'svg', 'pdf'.""")
71
71
72 def _update_figure_formatters(self):
73 if self.shell is not None:
74 select_figure_formats(self.shell, self.figure_formats, **self.print_figure_kwargs)
75
72 def _figure_formats_changed(self, name, old, new):
76 def _figure_formats_changed(self, name, old, new):
73 from IPython.core.pylabtools import select_figure_formats
77 from IPython.core.pylabtools import select_figure_formats
74 if 'jpg' in new or 'jpeg' in new:
78 if 'jpg' in new or 'jpeg' in new:
@@ -77,7 +81,7 b' class InlineBackend(InlineBackendConfig):'
77 if self.shell is None:
81 if self.shell is None:
78 return
82 return
79 else:
83 else:
80 select_figure_formats(self.shell, new)
84 self._update_figure_formatters()
81
85
82 figure_format = Unicode(config=True, help="""The figure format to enable (deprecated
86 figure_format = Unicode(config=True, help="""The figure format to enable (deprecated
83 use `figure_formats` instead)""")
87 use `figure_formats` instead)""")
@@ -86,12 +90,13 b' class InlineBackend(InlineBackendConfig):'
86 if new:
90 if new:
87 self.figure_formats = {new}
91 self.figure_formats = {new}
88
92
89 quality = Int(default_value=90, config=True,
93 print_figure_kwargs = Dict({'bbox_inches' : 'tight'}, config=True,
90 help="Quality of compression [10-100], currently for lossy JPEG only.")
94 help="""Extra kwargs to be passed to fig.canvas.print_figure.
91
95
92 def _quality_changed(self, name, old, new):
96 Logical examples include: bbox_inches, quality (for jpeg figures), etc.
93 if new < 10 or new > 100:
97 """
94 raise TraitError("figure JPEG quality must be in [10-100] range.")
98 )
99 _print_figure_kwargs_changed = _update_figure_formatters
95
100
96 close_figures = Bool(True, config=True,
101 close_figures = Bool(True, config=True,
97 help="""Close all figures at the end of each cell.
102 help="""Close all figures at the end of each cell.
@@ -109,7 +114,7 b' class InlineBackend(InlineBackendConfig):'
109 other matplotlib backends, but figure barriers between cells must
114 other matplotlib backends, but figure barriers between cells must
110 be explicit.
115 be explicit.
111 """)
116 """)
112
117
113 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
114
119
115
120
General Comments 0
You need to be logged in to leave comments. Login now