##// 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}
191
201 # cast in case of list / tuple
192 [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ]
202 formats = set(formats)
193
203
194 for fmt in formats:
204 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
195 if fmt == 'png':
205
196 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
206 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
197 elif fmt in ('png2x', 'retina'):
207 bad = formats.difference(supported)
198 png_formatter.for_type(Figure, retina_figure)
208 if bad:
199 elif fmt in ('jpg', 'jpeg'):
209 s = "{%s}" % ",".join([repr(f) for f in bad])
200 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality))
210 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %s" % s)
201 elif fmt == 'svg':
211
202 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
212 if 'png' in formats:
203 elif fmt == 'pdf':
213 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
204 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf'))
214 if 'retina' in formats or 'png2x' in formats:
205 else:
215 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
206 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %r" % fmt)
216 if 'jpg' in formats or 'jpeg' in formats:
217 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
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.
General Comments 0
You need to be logged in to leave comments. Login now