Show More
@@ -5,6 +5,8 b'' | |||||
5 | # Distributed under the terms of the Modified BSD License. |
|
5 | # Distributed under the terms of the Modified BSD License. | |
6 |
|
6 | |||
7 | from io import BytesIO |
|
7 | from io import BytesIO | |
|
8 | from binascii import b2a_base64 | |||
|
9 | from functools import partial | |||
8 | import warnings |
|
10 | import warnings | |
9 |
|
11 | |||
10 | from IPython.core.display import _pngxy |
|
12 | from IPython.core.display import _pngxy | |
@@ -99,7 +101,7 b' def figsize(sizex, sizey):' | |||||
99 | matplotlib.rcParams['figure.figsize'] = [sizex, sizey] |
|
101 | matplotlib.rcParams['figure.figsize'] = [sizex, sizey] | |
100 |
|
102 | |||
101 |
|
103 | |||
102 |
def print_figure(fig, fmt= |
|
104 | def print_figure(fig, fmt="png", bbox_inches="tight", base64=False, **kwargs): | |
103 | """Print a figure to an image, and return the resulting file data |
|
105 | """Print a figure to an image, and return the resulting file data | |
104 |
|
106 | |||
105 | Returned data will be bytes unless ``fmt='svg'``, |
|
107 | Returned data will be bytes unless ``fmt='svg'``, | |
@@ -107,6 +109,12 b" def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):" | |||||
107 |
|
109 | |||
108 | Any keyword args are passed to fig.canvas.print_figure, |
|
110 | Any keyword args are passed to fig.canvas.print_figure, | |
109 | such as ``quality`` or ``bbox_inches``. |
|
111 | such as ``quality`` or ``bbox_inches``. | |
|
112 | ||||
|
113 | If `base64` is True, return base64-encoded str instead of raw bytes | |||
|
114 | for binary-encoded image formats | |||
|
115 | ||||
|
116 | .. versionadded: 7.29 | |||
|
117 | base64 argument | |||
110 | """ |
|
118 | """ | |
111 | # When there's an empty figure, we shouldn't return anything, otherwise we |
|
119 | # When there's an empty figure, we shouldn't return anything, otherwise we | |
112 | # get big blank areas in the qt console. |
|
120 | # get big blank areas in the qt console. | |
@@ -138,19 +146,31 b" def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):" | |||||
138 | data = bytes_io.getvalue() |
|
146 | data = bytes_io.getvalue() | |
139 | if fmt == 'svg': |
|
147 | if fmt == 'svg': | |
140 | data = data.decode('utf-8') |
|
148 | data = data.decode('utf-8') | |
|
149 | elif base64: | |||
|
150 | data = b2a_base64(data).decode("ascii") | |||
141 | return data |
|
151 | return data | |
142 |
|
152 | |||
143 | def retina_figure(fig, **kwargs): |
|
153 | def retina_figure(fig, base64=False, **kwargs): | |
144 |
"""format a figure as a pixel-doubled (retina) PNG |
|
154 | """format a figure as a pixel-doubled (retina) PNG | |
145 | pngdata = print_figure(fig, fmt='retina', **kwargs) |
|
155 | ||
|
156 | If `base64` is True, return base64-encoded str instead of raw bytes | |||
|
157 | for binary-encoded image formats | |||
|
158 | ||||
|
159 | .. versionadded: 7.29 | |||
|
160 | base64 argument | |||
|
161 | """ | |||
|
162 | pngdata = print_figure(fig, fmt="retina", base64=False, **kwargs) | |||
146 | # Make sure that retina_figure acts just like print_figure and returns |
|
163 | # Make sure that retina_figure acts just like print_figure and returns | |
147 | # None when the figure is empty. |
|
164 | # None when the figure is empty. | |
148 | if pngdata is None: |
|
165 | if pngdata is None: | |
149 | return |
|
166 | return | |
150 | w, h = _pngxy(pngdata) |
|
167 | w, h = _pngxy(pngdata) | |
151 | metadata = {"width": w//2, "height":h//2} |
|
168 | metadata = {"width": w//2, "height":h//2} | |
|
169 | if base64: | |||
|
170 | pngdata = b2a_base64(pngdata).decode("ascii") | |||
152 | return pngdata, metadata |
|
171 | return pngdata, metadata | |
153 |
|
172 | |||
|
173 | ||||
154 | # We need a little factory function here to create the closure where |
|
174 | # We need a little factory function here to create the closure where | |
155 | # safe_execfile can live. |
|
175 | # safe_execfile can live. | |
156 | def mpl_runner(safe_execfile): |
|
176 | def mpl_runner(safe_execfile): | |
@@ -249,16 +269,22 b' def select_figure_formats(shell, formats, **kwargs):' | |||||
249 | gs = "%s" % ','.join([repr(f) for f in supported]) |
|
269 | gs = "%s" % ','.join([repr(f) for f in supported]) | |
250 | raise ValueError("supported formats are: %s not %s" % (gs, bs)) |
|
270 | raise ValueError("supported formats are: %s not %s" % (gs, bs)) | |
251 |
|
271 | |||
252 |
if |
|
272 | if "png" in formats: | |
253 | png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs)) |
|
273 | png_formatter.for_type( | |
254 | if 'retina' in formats or 'png2x' in formats: |
|
274 | Figure, partial(print_figure, fmt="png", base64=True, **kwargs) | |
255 | png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs)) |
|
275 | ) | |
256 |
if |
|
276 | if "retina" in formats or "png2x" in formats: | |
257 |
|
|
277 | png_formatter.for_type(Figure, partial(retina_figure, base64=True, **kwargs)) | |
258 |
if |
|
278 | if "jpg" in formats or "jpeg" in formats: | |
259 | svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs)) |
|
279 | jpg_formatter.for_type( | |
260 | if 'pdf' in formats: |
|
280 | Figure, partial(print_figure, fmt="jpg", base64=True, **kwargs) | |
261 | pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs)) |
|
281 | ) | |
|
282 | if "svg" in formats: | |||
|
283 | svg_formatter.for_type(Figure, partial(print_figure, fmt="svg", **kwargs)) | |||
|
284 | if "pdf" in formats: | |||
|
285 | pdf_formatter.for_type( | |||
|
286 | Figure, partial(print_figure, fmt="pdf", base64=True, **kwargs) | |||
|
287 | ) | |||
262 |
|
288 | |||
263 | #----------------------------------------------------------------------------- |
|
289 | #----------------------------------------------------------------------------- | |
264 | # Code for initializing matplotlib and importing pylab |
|
290 | # Code for initializing matplotlib and importing pylab |
@@ -187,10 +187,12 b' def test_set_matplotlib_formats_kwargs():' | |||||
187 | display.set_matplotlib_formats('png', **kwargs) |
|
187 | display.set_matplotlib_formats('png', **kwargs) | |
188 | formatter = ip.display_formatter.formatters['image/png'] |
|
188 | formatter = ip.display_formatter.formatters['image/png'] | |
189 | f = formatter.lookup_by_type(Figure) |
|
189 | f = formatter.lookup_by_type(Figure) | |
190 | cell = f.__closure__[0].cell_contents |
|
190 | formatter_kwargs = f.keywords | |
191 | expected = kwargs |
|
191 | expected = kwargs | |
|
192 | expected["base64"] = True | |||
|
193 | expected["fmt"] = "png" | |||
192 | expected.update(cfg.print_figure_kwargs) |
|
194 | expected.update(cfg.print_figure_kwargs) | |
193 |
nt.assert_equal( |
|
195 | nt.assert_equal(formatter_kwargs, expected) | |
194 |
|
196 | |||
195 | def test_display_available(): |
|
197 | def test_display_available(): | |
196 | """ |
|
198 | """ |
@@ -5,7 +5,8 b'' | |||||
5 | # Distributed under the terms of the Modified BSD License. |
|
5 | # Distributed under the terms of the Modified BSD License. | |
6 |
|
6 | |||
7 |
|
7 | |||
8 | from io import UnsupportedOperation, BytesIO |
|
8 | from binascii import a2b_base64 | |
|
9 | from io import BytesIO | |||
9 |
|
10 | |||
10 | import matplotlib |
|
11 | import matplotlib | |
11 | matplotlib.use('Agg') |
|
12 | matplotlib.use('Agg') | |
@@ -104,8 +105,11 b' def test_select_figure_formats_kwargs():' | |||||
104 | pt.select_figure_formats(ip, 'png', **kwargs) |
|
105 | pt.select_figure_formats(ip, 'png', **kwargs) | |
105 | formatter = ip.display_formatter.formatters['image/png'] |
|
106 | formatter = ip.display_formatter.formatters['image/png'] | |
106 | f = formatter.lookup_by_type(Figure) |
|
107 | f = formatter.lookup_by_type(Figure) | |
107 | cell = f.__closure__[0].cell_contents |
|
108 | cell = f.keywords | |
108 | nt.assert_equal(cell, kwargs) |
|
109 | expected = kwargs | |
|
110 | expected["base64"] = True | |||
|
111 | expected["fmt"] = "png" | |||
|
112 | assert cell == expected | |||
109 |
|
113 | |||
110 | # check that the formatter doesn't raise |
|
114 | # check that the formatter doesn't raise | |
111 | fig = plt.figure() |
|
115 | fig = plt.figure() | |
@@ -114,7 +118,9 b' def test_select_figure_formats_kwargs():' | |||||
114 | plt.draw() |
|
118 | plt.draw() | |
115 | formatter.enabled = True |
|
119 | formatter.enabled = True | |
116 | png = formatter(fig) |
|
120 | png = formatter(fig) | |
117 | assert png.startswith(_PNG) |
|
121 | assert isinstance(png, str) | |
|
122 | png_bytes = a2b_base64(png) | |||
|
123 | assert png_bytes.startswith(_PNG) | |||
118 |
|
124 | |||
119 | def test_select_figure_formats_set(): |
|
125 | def test_select_figure_formats_set(): | |
120 | ip = get_ipython() |
|
126 | ip = get_ipython() |
General Comments 0
You need to be logged in to leave comments.
Login now