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