##// END OF EJS Templates
Merge pull request #10952 from ipython/auto-backport-of-pr-10634...
Thomas Kluyver -
r24104:37c9ed80 merge
parent child Browse files
Show More
@@ -1,1285 +1,1290 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats."""
2 """Top-level display functions for displaying object in different formats."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 try:
9 try:
10 from base64 import encodebytes as base64_encode
10 from base64 import encodebytes as base64_encode
11 except ImportError:
11 except ImportError:
12 from base64 import encodestring as base64_encode
12 from base64 import encodestring as base64_encode
13
13
14 from binascii import b2a_hex, hexlify
14 from binascii import b2a_hex, hexlify
15 import json
15 import json
16 import mimetypes
16 import mimetypes
17 import os
17 import os
18 import struct
18 import struct
19 import sys
19 import sys
20 import warnings
20 import warnings
21
21
22 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
22 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
23 unicode_type)
23 unicode_type)
24 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.testing.skipdoctest import skip_doctest
25
25
26 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
26 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
27 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
27 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
28 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
28 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
29 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON', 'Javascript',
29 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'ProgressBar', 'JSON', 'Javascript',
30 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
30 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
31 'publish_display_data', 'update_display', 'DisplayHandle']
31 'publish_display_data', 'update_display', 'DisplayHandle']
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # utility functions
34 # utility functions
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 def _safe_exists(path):
37 def _safe_exists(path):
38 """Check path, but don't let exceptions raise"""
38 """Check path, but don't let exceptions raise"""
39 try:
39 try:
40 return os.path.exists(path)
40 return os.path.exists(path)
41 except Exception:
41 except Exception:
42 return False
42 return False
43
43
44 def _merge(d1, d2):
44 def _merge(d1, d2):
45 """Like update, but merges sub-dicts instead of clobbering at the top level.
45 """Like update, but merges sub-dicts instead of clobbering at the top level.
46
46
47 Updates d1 in-place
47 Updates d1 in-place
48 """
48 """
49
49
50 if not isinstance(d2, dict) or not isinstance(d1, dict):
50 if not isinstance(d2, dict) or not isinstance(d1, dict):
51 return d2
51 return d2
52 for key, value in d2.items():
52 for key, value in d2.items():
53 d1[key] = _merge(d1.get(key), value)
53 d1[key] = _merge(d1.get(key), value)
54 return d1
54 return d1
55
55
56 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
56 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
57 """internal implementation of all display_foo methods
57 """internal implementation of all display_foo methods
58
58
59 Parameters
59 Parameters
60 ----------
60 ----------
61 mimetype : str
61 mimetype : str
62 The mimetype to be published (e.g. 'image/png')
62 The mimetype to be published (e.g. 'image/png')
63 objs : tuple of objects
63 objs : tuple of objects
64 The Python objects to display, or if raw=True raw text data to
64 The Python objects to display, or if raw=True raw text data to
65 display.
65 display.
66 raw : bool
66 raw : bool
67 Are the data objects raw data or Python objects that need to be
67 Are the data objects raw data or Python objects that need to be
68 formatted before display? [default: False]
68 formatted before display? [default: False]
69 metadata : dict (optional)
69 metadata : dict (optional)
70 Metadata to be associated with the specific mimetype output.
70 Metadata to be associated with the specific mimetype output.
71 """
71 """
72 if metadata:
72 if metadata:
73 metadata = {mimetype: metadata}
73 metadata = {mimetype: metadata}
74 if raw:
74 if raw:
75 # turn list of pngdata into list of { 'image/png': pngdata }
75 # turn list of pngdata into list of { 'image/png': pngdata }
76 objs = [ {mimetype: obj} for obj in objs ]
76 objs = [ {mimetype: obj} for obj in objs ]
77 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
77 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
78
78
79 #-----------------------------------------------------------------------------
79 #-----------------------------------------------------------------------------
80 # Main functions
80 # Main functions
81 #-----------------------------------------------------------------------------
81 #-----------------------------------------------------------------------------
82 # use * to indicate transient is keyword-only
82 # use * to indicate transient is keyword-only
83 def publish_display_data(data, metadata=None, source=None, **kwargs):
83 def publish_display_data(data, metadata=None, source=None, **kwargs):
84 """Publish data and metadata to all frontends.
84 """Publish data and metadata to all frontends.
85
85
86 See the ``display_data`` message in the messaging documentation for
86 See the ``display_data`` message in the messaging documentation for
87 more details about this message type.
87 more details about this message type.
88
88
89 The following MIME types are currently implemented:
89 The following MIME types are currently implemented:
90
90
91 * text/plain
91 * text/plain
92 * text/html
92 * text/html
93 * text/markdown
93 * text/markdown
94 * text/latex
94 * text/latex
95 * application/json
95 * application/json
96 * application/javascript
96 * application/javascript
97 * image/png
97 * image/png
98 * image/jpeg
98 * image/jpeg
99 * image/svg+xml
99 * image/svg+xml
100
100
101 Parameters
101 Parameters
102 ----------
102 ----------
103 data : dict
103 data : dict
104 A dictionary having keys that are valid MIME types (like
104 A dictionary having keys that are valid MIME types (like
105 'text/plain' or 'image/svg+xml') and values that are the data for
105 'text/plain' or 'image/svg+xml') and values that are the data for
106 that MIME type. The data itself must be a JSON'able data
106 that MIME type. The data itself must be a JSON'able data
107 structure. Minimally all data should have the 'text/plain' data,
107 structure. Minimally all data should have the 'text/plain' data,
108 which can be displayed by all frontends. If more than the plain
108 which can be displayed by all frontends. If more than the plain
109 text is given, it is up to the frontend to decide which
109 text is given, it is up to the frontend to decide which
110 representation to use.
110 representation to use.
111 metadata : dict
111 metadata : dict
112 A dictionary for metadata related to the data. This can contain
112 A dictionary for metadata related to the data. This can contain
113 arbitrary key, value pairs that frontends can use to interpret
113 arbitrary key, value pairs that frontends can use to interpret
114 the data. mime-type keys matching those in data can be used
114 the data. mime-type keys matching those in data can be used
115 to specify metadata about particular representations.
115 to specify metadata about particular representations.
116 source : str, deprecated
116 source : str, deprecated
117 Unused.
117 Unused.
118 transient : dict, keyword-only
118 transient : dict, keyword-only
119 A dictionary of transient data, such as display_id.
119 A dictionary of transient data, such as display_id.
120 """
120 """
121 from IPython.core.interactiveshell import InteractiveShell
121 from IPython.core.interactiveshell import InteractiveShell
122
122
123 display_pub = InteractiveShell.instance().display_pub
123 display_pub = InteractiveShell.instance().display_pub
124
124
125 # only pass transient if supplied,
125 # only pass transient if supplied,
126 # to avoid errors with older ipykernel.
126 # to avoid errors with older ipykernel.
127 # TODO: We could check for ipykernel version and provide a detailed upgrade message.
127 # TODO: We could check for ipykernel version and provide a detailed upgrade message.
128
128
129 display_pub.publish(
129 display_pub.publish(
130 data=data,
130 data=data,
131 metadata=metadata,
131 metadata=metadata,
132 **kwargs
132 **kwargs
133 )
133 )
134
134
135
135
136 def _new_id():
136 def _new_id():
137 """Generate a new random text id with urandom"""
137 """Generate a new random text id with urandom"""
138 return b2a_hex(os.urandom(16)).decode('ascii')
138 return b2a_hex(os.urandom(16)).decode('ascii')
139
139
140
140
141 def display(*objs, **kwargs):
141 def display(*objs, **kwargs):
142 """Display a Python object in all frontends.
142 """Display a Python object in all frontends.
143
143
144 By default all representations will be computed and sent to the frontends.
144 By default all representations will be computed and sent to the frontends.
145 Frontends can decide which representation is used and how.
145 Frontends can decide which representation is used and how.
146
146
147 In terminal IPython this will be similar to using :func:`print`, for use in richer
147 In terminal IPython this will be similar to using :func:`print`, for use in richer
148 frontends see Jupyter notebook examples with rich display logic.
148 frontends see Jupyter notebook examples with rich display logic.
149
149
150 Parameters
150 Parameters
151 ----------
151 ----------
152 objs : tuple of objects
152 objs : tuple of objects
153 The Python objects to display.
153 The Python objects to display.
154 raw : bool, optional
154 raw : bool, optional
155 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
155 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
156 or Python objects that need to be formatted before display? [default: False]
156 or Python objects that need to be formatted before display? [default: False]
157 include : list, tuple or set, optional
157 include : list, tuple or set, optional
158 A list of format type strings (MIME types) to include in the
158 A list of format type strings (MIME types) to include in the
159 format data dict. If this is set *only* the format types included
159 format data dict. If this is set *only* the format types included
160 in this list will be computed.
160 in this list will be computed.
161 exclude : list, tuple or set, optional
161 exclude : list, tuple or set, optional
162 A list of format type strings (MIME types) to exclude in the format
162 A list of format type strings (MIME types) to exclude in the format
163 data dict. If this is set all format types will be computed,
163 data dict. If this is set all format types will be computed,
164 except for those included in this argument.
164 except for those included in this argument.
165 metadata : dict, optional
165 metadata : dict, optional
166 A dictionary of metadata to associate with the output.
166 A dictionary of metadata to associate with the output.
167 mime-type keys in this dictionary will be associated with the individual
167 mime-type keys in this dictionary will be associated with the individual
168 representation formats, if they exist.
168 representation formats, if they exist.
169 transient : dict, optional
169 transient : dict, optional
170 A dictionary of transient data to associate with the output.
170 A dictionary of transient data to associate with the output.
171 Data in this dict should not be persisted to files (e.g. notebooks).
171 Data in this dict should not be persisted to files (e.g. notebooks).
172 display_id : str, bool optional
172 display_id : str, bool optional
173 Set an id for the display.
173 Set an id for the display.
174 This id can be used for updating this display area later via update_display.
174 This id can be used for updating this display area later via update_display.
175 If given as `True`, generate a new `display_id`
175 If given as `True`, generate a new `display_id`
176 kwargs: additional keyword-args, optional
176 kwargs: additional keyword-args, optional
177 Additional keyword-arguments are passed through to the display publisher.
177 Additional keyword-arguments are passed through to the display publisher.
178
178
179 Returns
179 Returns
180 -------
180 -------
181
181
182 handle: DisplayHandle
182 handle: DisplayHandle
183 Returns a handle on updatable displays for use with :func:`update_display`,
183 Returns a handle on updatable displays for use with :func:`update_display`,
184 if `display_id` is given. Returns :any:`None` if no `display_id` is given
184 if `display_id` is given. Returns :any:`None` if no `display_id` is given
185 (default).
185 (default).
186
186
187 Examples
187 Examples
188 --------
188 --------
189
189
190 >>> class Json(object):
190 >>> class Json(object):
191 ... def __init__(self, json):
191 ... def __init__(self, json):
192 ... self.json = json
192 ... self.json = json
193 ... def _repr_pretty_(self, pp, cycle):
193 ... def _repr_pretty_(self, pp, cycle):
194 ... import json
194 ... import json
195 ... pp.text(json.dumps(self.json, indent=2))
195 ... pp.text(json.dumps(self.json, indent=2))
196 ... def __repr__(self):
196 ... def __repr__(self):
197 ... return str(self.json)
197 ... return str(self.json)
198 ...
198 ...
199
199
200 >>> d = Json({1:2, 3: {4:5}})
200 >>> d = Json({1:2, 3: {4:5}})
201
201
202 >>> print(d)
202 >>> print(d)
203 {1: 2, 3: {4: 5}}
203 {1: 2, 3: {4: 5}}
204
204
205 >>> display(d)
205 >>> display(d)
206 {
206 {
207 "1": 2,
207 "1": 2,
208 "3": {
208 "3": {
209 "4": 5
209 "4": 5
210 }
210 }
211 }
211 }
212
212
213 >>> def int_formatter(integer, pp, cycle):
213 >>> def int_formatter(integer, pp, cycle):
214 ... pp.text('I'*integer)
214 ... pp.text('I'*integer)
215
215
216 >>> plain = get_ipython().display_formatter.formatters['text/plain']
216 >>> plain = get_ipython().display_formatter.formatters['text/plain']
217 >>> plain.for_type(int, int_formatter)
217 >>> plain.for_type(int, int_formatter)
218 <function _repr_pprint at 0x...>
218 <function _repr_pprint at 0x...>
219 >>> display(7-5)
219 >>> display(7-5)
220 II
220 II
221
221
222 >>> del plain.type_printers[int]
222 >>> del plain.type_printers[int]
223 >>> display(7-5)
223 >>> display(7-5)
224 2
224 2
225
225
226 See Also
226 See Also
227 --------
227 --------
228
228
229 :func:`update_display`
229 :func:`update_display`
230
230
231 Notes
231 Notes
232 -----
232 -----
233
233
234 In Python, objects can declare their textual representation using the
234 In Python, objects can declare their textual representation using the
235 `__repr__` method. IPython expands on this idea and allows objects to declare
235 `__repr__` method. IPython expands on this idea and allows objects to declare
236 other, rich representations including:
236 other, rich representations including:
237
237
238 - HTML
238 - HTML
239 - JSON
239 - JSON
240 - PNG
240 - PNG
241 - JPEG
241 - JPEG
242 - SVG
242 - SVG
243 - LaTeX
243 - LaTeX
244
244
245 A single object can declare some or all of these representations; all are
245 A single object can declare some or all of these representations; all are
246 handled by IPython's display system.
246 handled by IPython's display system.
247
247
248 The main idea of the first approach is that you have to implement special
248 The main idea of the first approach is that you have to implement special
249 display methods when you define your class, one for each representation you
249 display methods when you define your class, one for each representation you
250 want to use. Here is a list of the names of the special methods and the
250 want to use. Here is a list of the names of the special methods and the
251 values they must return:
251 values they must return:
252
252
253 - `_repr_html_`: return raw HTML as a string
253 - `_repr_html_`: return raw HTML as a string
254 - `_repr_json_`: return a JSONable dict
254 - `_repr_json_`: return a JSONable dict
255 - `_repr_jpeg_`: return raw JPEG data
255 - `_repr_jpeg_`: return raw JPEG data
256 - `_repr_png_`: return raw PNG data
256 - `_repr_png_`: return raw PNG data
257 - `_repr_svg_`: return raw SVG data as a string
257 - `_repr_svg_`: return raw SVG data as a string
258 - `_repr_latex_`: return LaTeX commands in a string surrounded by "$".
258 - `_repr_latex_`: return LaTeX commands in a string surrounded by "$".
259 - `_repr_mimebundle_`: return a full mimebundle containing the mapping
259 - `_repr_mimebundle_`: return a full mimebundle containing the mapping
260 from all mimetypes to data
260 from all mimetypes to data
261
261
262 When you are directly writing your own classes, you can adapt them for
262 When you are directly writing your own classes, you can adapt them for
263 display in IPython by following the above approach. But in practice, you
263 display in IPython by following the above approach. But in practice, you
264 often need to work with existing classes that you can't easily modify.
264 often need to work with existing classes that you can't easily modify.
265
265
266 You can refer to the documentation on IPython display formatters in order to
266 You can refer to the documentation on IPython display formatters in order to
267 register custom formatters for already existing types.
267 register custom formatters for already existing types.
268
268
269 .. versionadded:: 5.4 display available without import
269 .. versionadded:: 5.4 display available without import
270 .. versionadded:: 6.1 display available without import
270 .. versionadded:: 6.1 display available without import
271
271
272 Since IPython 5.4 and 6.1 :func:`display` is automatically made available to
272 Since IPython 5.4 and 6.1 :func:`display` is automatically made available to
273 the user without import. If you are using display in a document that might
273 the user without import. If you are using display in a document that might
274 be used in a pure python context or with older version of IPython, use the
274 be used in a pure python context or with older version of IPython, use the
275 following import at the top of your file::
275 following import at the top of your file::
276
276
277 from IPython.display import display
277 from IPython.display import display
278
278
279 """
279 """
280 from IPython.core.interactiveshell import InteractiveShell
281
282 if not InteractiveShell.initialized():
283 # Directly print objects.
284 print(*objs)
285 return
286
280 raw = kwargs.pop('raw', False)
287 raw = kwargs.pop('raw', False)
281 include = kwargs.pop('include', None)
288 include = kwargs.pop('include', None)
282 exclude = kwargs.pop('exclude', None)
289 exclude = kwargs.pop('exclude', None)
283 metadata = kwargs.pop('metadata', None)
290 metadata = kwargs.pop('metadata', None)
284 transient = kwargs.pop('transient', None)
291 transient = kwargs.pop('transient', None)
285 display_id = kwargs.pop('display_id', None)
292 display_id = kwargs.pop('display_id', None)
286 if transient is None:
293 if transient is None:
287 transient = {}
294 transient = {}
288 if display_id:
295 if display_id:
289 if display_id is True:
296 if display_id is True:
290 display_id = _new_id()
297 display_id = _new_id()
291 transient['display_id'] = display_id
298 transient['display_id'] = display_id
292 if kwargs.get('update') and 'display_id' not in transient:
299 if kwargs.get('update') and 'display_id' not in transient:
293 raise TypeError('display_id required for update_display')
300 raise TypeError('display_id required for update_display')
294 if transient:
301 if transient:
295 kwargs['transient'] = transient
302 kwargs['transient'] = transient
296
303
297 from IPython.core.interactiveshell import InteractiveShell
298
299 if not raw:
304 if not raw:
300 format = InteractiveShell.instance().display_formatter.format
305 format = InteractiveShell.instance().display_formatter.format
301
306
302 for obj in objs:
307 for obj in objs:
303 if raw:
308 if raw:
304 publish_display_data(data=obj, metadata=metadata, **kwargs)
309 publish_display_data(data=obj, metadata=metadata, **kwargs)
305 else:
310 else:
306 format_dict, md_dict = format(obj, include=include, exclude=exclude)
311 format_dict, md_dict = format(obj, include=include, exclude=exclude)
307 if not format_dict:
312 if not format_dict:
308 # nothing to display (e.g. _ipython_display_ took over)
313 # nothing to display (e.g. _ipython_display_ took over)
309 continue
314 continue
310 if metadata:
315 if metadata:
311 # kwarg-specified metadata gets precedence
316 # kwarg-specified metadata gets precedence
312 _merge(md_dict, metadata)
317 _merge(md_dict, metadata)
313 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
318 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
314 if display_id:
319 if display_id:
315 return DisplayHandle(display_id)
320 return DisplayHandle(display_id)
316
321
317
322
318 # use * for keyword-only display_id arg
323 # use * for keyword-only display_id arg
319 def update_display(obj, **kwargs):
324 def update_display(obj, **kwargs):
320 """Update an existing display by id
325 """Update an existing display by id
321
326
322 Parameters
327 Parameters
323 ----------
328 ----------
324
329
325 obj:
330 obj:
326 The object with which to update the display
331 The object with which to update the display
327 display_id: keyword-only
332 display_id: keyword-only
328 The id of the display to update
333 The id of the display to update
329
334
330 See Also
335 See Also
331 --------
336 --------
332
337
333 :func:`display`
338 :func:`display`
334 """
339 """
335 sentinel = object()
340 sentinel = object()
336 display_id = kwargs.pop('display_id', sentinel)
341 display_id = kwargs.pop('display_id', sentinel)
337 if display_id is sentinel:
342 if display_id is sentinel:
338 raise TypeError("update_display() missing 1 required keyword-only argument: 'display_id'")
343 raise TypeError("update_display() missing 1 required keyword-only argument: 'display_id'")
339 kwargs['update'] = True
344 kwargs['update'] = True
340 display(obj, display_id=display_id, **kwargs)
345 display(obj, display_id=display_id, **kwargs)
341
346
342
347
343 class DisplayHandle(object):
348 class DisplayHandle(object):
344 """A handle on an updatable display
349 """A handle on an updatable display
345
350
346 Call `.update(obj)` to display a new object.
351 Call `.update(obj)` to display a new object.
347
352
348 Call `.display(obj`) to add a new instance of this display,
353 Call `.display(obj`) to add a new instance of this display,
349 and update existing instances.
354 and update existing instances.
350
355
351 See Also
356 See Also
352 --------
357 --------
353
358
354 :func:`display`, :func:`update_display`
359 :func:`display`, :func:`update_display`
355
360
356 """
361 """
357
362
358 def __init__(self, display_id=None):
363 def __init__(self, display_id=None):
359 if display_id is None:
364 if display_id is None:
360 display_id = _new_id()
365 display_id = _new_id()
361 self.display_id = display_id
366 self.display_id = display_id
362
367
363 def __repr__(self):
368 def __repr__(self):
364 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
369 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
365
370
366 def display(self, obj, **kwargs):
371 def display(self, obj, **kwargs):
367 """Make a new display with my id, updating existing instances.
372 """Make a new display with my id, updating existing instances.
368
373
369 Parameters
374 Parameters
370 ----------
375 ----------
371
376
372 obj:
377 obj:
373 object to display
378 object to display
374 **kwargs:
379 **kwargs:
375 additional keyword arguments passed to display
380 additional keyword arguments passed to display
376 """
381 """
377 display(obj, display_id=self.display_id, **kwargs)
382 display(obj, display_id=self.display_id, **kwargs)
378
383
379 def update(self, obj, **kwargs):
384 def update(self, obj, **kwargs):
380 """Update existing displays with my id
385 """Update existing displays with my id
381
386
382 Parameters
387 Parameters
383 ----------
388 ----------
384
389
385 obj:
390 obj:
386 object to display
391 object to display
387 **kwargs:
392 **kwargs:
388 additional keyword arguments passed to update_display
393 additional keyword arguments passed to update_display
389 """
394 """
390 update_display(obj, display_id=self.display_id, **kwargs)
395 update_display(obj, display_id=self.display_id, **kwargs)
391
396
392
397
393 def display_pretty(*objs, **kwargs):
398 def display_pretty(*objs, **kwargs):
394 """Display the pretty (default) representation of an object.
399 """Display the pretty (default) representation of an object.
395
400
396 Parameters
401 Parameters
397 ----------
402 ----------
398 objs : tuple of objects
403 objs : tuple of objects
399 The Python objects to display, or if raw=True raw text data to
404 The Python objects to display, or if raw=True raw text data to
400 display.
405 display.
401 raw : bool
406 raw : bool
402 Are the data objects raw data or Python objects that need to be
407 Are the data objects raw data or Python objects that need to be
403 formatted before display? [default: False]
408 formatted before display? [default: False]
404 metadata : dict (optional)
409 metadata : dict (optional)
405 Metadata to be associated with the specific mimetype output.
410 Metadata to be associated with the specific mimetype output.
406 """
411 """
407 _display_mimetype('text/plain', objs, **kwargs)
412 _display_mimetype('text/plain', objs, **kwargs)
408
413
409
414
410 def display_html(*objs, **kwargs):
415 def display_html(*objs, **kwargs):
411 """Display the HTML representation of an object.
416 """Display the HTML representation of an object.
412
417
413 Note: If raw=False and the object does not have a HTML
418 Note: If raw=False and the object does not have a HTML
414 representation, no HTML will be shown.
419 representation, no HTML will be shown.
415
420
416 Parameters
421 Parameters
417 ----------
422 ----------
418 objs : tuple of objects
423 objs : tuple of objects
419 The Python objects to display, or if raw=True raw HTML data to
424 The Python objects to display, or if raw=True raw HTML data to
420 display.
425 display.
421 raw : bool
426 raw : bool
422 Are the data objects raw data or Python objects that need to be
427 Are the data objects raw data or Python objects that need to be
423 formatted before display? [default: False]
428 formatted before display? [default: False]
424 metadata : dict (optional)
429 metadata : dict (optional)
425 Metadata to be associated with the specific mimetype output.
430 Metadata to be associated with the specific mimetype output.
426 """
431 """
427 _display_mimetype('text/html', objs, **kwargs)
432 _display_mimetype('text/html', objs, **kwargs)
428
433
429
434
430 def display_markdown(*objs, **kwargs):
435 def display_markdown(*objs, **kwargs):
431 """Displays the Markdown representation of an object.
436 """Displays the Markdown representation of an object.
432
437
433 Parameters
438 Parameters
434 ----------
439 ----------
435 objs : tuple of objects
440 objs : tuple of objects
436 The Python objects to display, or if raw=True raw markdown data to
441 The Python objects to display, or if raw=True raw markdown data to
437 display.
442 display.
438 raw : bool
443 raw : bool
439 Are the data objects raw data or Python objects that need to be
444 Are the data objects raw data or Python objects that need to be
440 formatted before display? [default: False]
445 formatted before display? [default: False]
441 metadata : dict (optional)
446 metadata : dict (optional)
442 Metadata to be associated with the specific mimetype output.
447 Metadata to be associated with the specific mimetype output.
443 """
448 """
444
449
445 _display_mimetype('text/markdown', objs, **kwargs)
450 _display_mimetype('text/markdown', objs, **kwargs)
446
451
447
452
448 def display_svg(*objs, **kwargs):
453 def display_svg(*objs, **kwargs):
449 """Display the SVG representation of an object.
454 """Display the SVG representation of an object.
450
455
451 Parameters
456 Parameters
452 ----------
457 ----------
453 objs : tuple of objects
458 objs : tuple of objects
454 The Python objects to display, or if raw=True raw svg data to
459 The Python objects to display, or if raw=True raw svg data to
455 display.
460 display.
456 raw : bool
461 raw : bool
457 Are the data objects raw data or Python objects that need to be
462 Are the data objects raw data or Python objects that need to be
458 formatted before display? [default: False]
463 formatted before display? [default: False]
459 metadata : dict (optional)
464 metadata : dict (optional)
460 Metadata to be associated with the specific mimetype output.
465 Metadata to be associated with the specific mimetype output.
461 """
466 """
462 _display_mimetype('image/svg+xml', objs, **kwargs)
467 _display_mimetype('image/svg+xml', objs, **kwargs)
463
468
464
469
465 def display_png(*objs, **kwargs):
470 def display_png(*objs, **kwargs):
466 """Display the PNG representation of an object.
471 """Display the PNG representation of an object.
467
472
468 Parameters
473 Parameters
469 ----------
474 ----------
470 objs : tuple of objects
475 objs : tuple of objects
471 The Python objects to display, or if raw=True raw png data to
476 The Python objects to display, or if raw=True raw png data to
472 display.
477 display.
473 raw : bool
478 raw : bool
474 Are the data objects raw data or Python objects that need to be
479 Are the data objects raw data or Python objects that need to be
475 formatted before display? [default: False]
480 formatted before display? [default: False]
476 metadata : dict (optional)
481 metadata : dict (optional)
477 Metadata to be associated with the specific mimetype output.
482 Metadata to be associated with the specific mimetype output.
478 """
483 """
479 _display_mimetype('image/png', objs, **kwargs)
484 _display_mimetype('image/png', objs, **kwargs)
480
485
481
486
482 def display_jpeg(*objs, **kwargs):
487 def display_jpeg(*objs, **kwargs):
483 """Display the JPEG representation of an object.
488 """Display the JPEG representation of an object.
484
489
485 Parameters
490 Parameters
486 ----------
491 ----------
487 objs : tuple of objects
492 objs : tuple of objects
488 The Python objects to display, or if raw=True raw JPEG data to
493 The Python objects to display, or if raw=True raw JPEG data to
489 display.
494 display.
490 raw : bool
495 raw : bool
491 Are the data objects raw data or Python objects that need to be
496 Are the data objects raw data or Python objects that need to be
492 formatted before display? [default: False]
497 formatted before display? [default: False]
493 metadata : dict (optional)
498 metadata : dict (optional)
494 Metadata to be associated with the specific mimetype output.
499 Metadata to be associated with the specific mimetype output.
495 """
500 """
496 _display_mimetype('image/jpeg', objs, **kwargs)
501 _display_mimetype('image/jpeg', objs, **kwargs)
497
502
498
503
499 def display_latex(*objs, **kwargs):
504 def display_latex(*objs, **kwargs):
500 """Display the LaTeX representation of an object.
505 """Display the LaTeX representation of an object.
501
506
502 Parameters
507 Parameters
503 ----------
508 ----------
504 objs : tuple of objects
509 objs : tuple of objects
505 The Python objects to display, or if raw=True raw latex data to
510 The Python objects to display, or if raw=True raw latex data to
506 display.
511 display.
507 raw : bool
512 raw : bool
508 Are the data objects raw data or Python objects that need to be
513 Are the data objects raw data or Python objects that need to be
509 formatted before display? [default: False]
514 formatted before display? [default: False]
510 metadata : dict (optional)
515 metadata : dict (optional)
511 Metadata to be associated with the specific mimetype output.
516 Metadata to be associated with the specific mimetype output.
512 """
517 """
513 _display_mimetype('text/latex', objs, **kwargs)
518 _display_mimetype('text/latex', objs, **kwargs)
514
519
515
520
516 def display_json(*objs, **kwargs):
521 def display_json(*objs, **kwargs):
517 """Display the JSON representation of an object.
522 """Display the JSON representation of an object.
518
523
519 Note that not many frontends support displaying JSON.
524 Note that not many frontends support displaying JSON.
520
525
521 Parameters
526 Parameters
522 ----------
527 ----------
523 objs : tuple of objects
528 objs : tuple of objects
524 The Python objects to display, or if raw=True raw json data to
529 The Python objects to display, or if raw=True raw json data to
525 display.
530 display.
526 raw : bool
531 raw : bool
527 Are the data objects raw data or Python objects that need to be
532 Are the data objects raw data or Python objects that need to be
528 formatted before display? [default: False]
533 formatted before display? [default: False]
529 metadata : dict (optional)
534 metadata : dict (optional)
530 Metadata to be associated with the specific mimetype output.
535 Metadata to be associated with the specific mimetype output.
531 """
536 """
532 _display_mimetype('application/json', objs, **kwargs)
537 _display_mimetype('application/json', objs, **kwargs)
533
538
534
539
535 def display_javascript(*objs, **kwargs):
540 def display_javascript(*objs, **kwargs):
536 """Display the Javascript representation of an object.
541 """Display the Javascript representation of an object.
537
542
538 Parameters
543 Parameters
539 ----------
544 ----------
540 objs : tuple of objects
545 objs : tuple of objects
541 The Python objects to display, or if raw=True raw javascript data to
546 The Python objects to display, or if raw=True raw javascript data to
542 display.
547 display.
543 raw : bool
548 raw : bool
544 Are the data objects raw data or Python objects that need to be
549 Are the data objects raw data or Python objects that need to be
545 formatted before display? [default: False]
550 formatted before display? [default: False]
546 metadata : dict (optional)
551 metadata : dict (optional)
547 Metadata to be associated with the specific mimetype output.
552 Metadata to be associated with the specific mimetype output.
548 """
553 """
549 _display_mimetype('application/javascript', objs, **kwargs)
554 _display_mimetype('application/javascript', objs, **kwargs)
550
555
551
556
552 def display_pdf(*objs, **kwargs):
557 def display_pdf(*objs, **kwargs):
553 """Display the PDF representation of an object.
558 """Display the PDF representation of an object.
554
559
555 Parameters
560 Parameters
556 ----------
561 ----------
557 objs : tuple of objects
562 objs : tuple of objects
558 The Python objects to display, or if raw=True raw javascript data to
563 The Python objects to display, or if raw=True raw javascript data to
559 display.
564 display.
560 raw : bool
565 raw : bool
561 Are the data objects raw data or Python objects that need to be
566 Are the data objects raw data or Python objects that need to be
562 formatted before display? [default: False]
567 formatted before display? [default: False]
563 metadata : dict (optional)
568 metadata : dict (optional)
564 Metadata to be associated with the specific mimetype output.
569 Metadata to be associated with the specific mimetype output.
565 """
570 """
566 _display_mimetype('application/pdf', objs, **kwargs)
571 _display_mimetype('application/pdf', objs, **kwargs)
567
572
568
573
569 #-----------------------------------------------------------------------------
574 #-----------------------------------------------------------------------------
570 # Smart classes
575 # Smart classes
571 #-----------------------------------------------------------------------------
576 #-----------------------------------------------------------------------------
572
577
573
578
574 class DisplayObject(object):
579 class DisplayObject(object):
575 """An object that wraps data to be displayed."""
580 """An object that wraps data to be displayed."""
576
581
577 _read_flags = 'r'
582 _read_flags = 'r'
578 _show_mem_addr = False
583 _show_mem_addr = False
579
584
580 def __init__(self, data=None, url=None, filename=None):
585 def __init__(self, data=None, url=None, filename=None):
581 """Create a display object given raw data.
586 """Create a display object given raw data.
582
587
583 When this object is returned by an expression or passed to the
588 When this object is returned by an expression or passed to the
584 display function, it will result in the data being displayed
589 display function, it will result in the data being displayed
585 in the frontend. The MIME type of the data should match the
590 in the frontend. The MIME type of the data should match the
586 subclasses used, so the Png subclass should be used for 'image/png'
591 subclasses used, so the Png subclass should be used for 'image/png'
587 data. If the data is a URL, the data will first be downloaded
592 data. If the data is a URL, the data will first be downloaded
588 and then displayed. If
593 and then displayed. If
589
594
590 Parameters
595 Parameters
591 ----------
596 ----------
592 data : unicode, str or bytes
597 data : unicode, str or bytes
593 The raw data or a URL or file to load the data from
598 The raw data or a URL or file to load the data from
594 url : unicode
599 url : unicode
595 A URL to download the data from.
600 A URL to download the data from.
596 filename : unicode
601 filename : unicode
597 Path to a local file to load the data from.
602 Path to a local file to load the data from.
598 """
603 """
599 if data is not None and isinstance(data, string_types):
604 if data is not None and isinstance(data, string_types):
600 if data.startswith('http') and url is None:
605 if data.startswith('http') and url is None:
601 url = data
606 url = data
602 filename = None
607 filename = None
603 data = None
608 data = None
604 elif _safe_exists(data) and filename is None:
609 elif _safe_exists(data) and filename is None:
605 url = None
610 url = None
606 filename = data
611 filename = data
607 data = None
612 data = None
608
613
609 self.data = data
614 self.data = data
610 self.url = url
615 self.url = url
611 self.filename = None if filename is None else unicode_type(filename)
616 self.filename = None if filename is None else unicode_type(filename)
612
617
613 self.reload()
618 self.reload()
614 self._check_data()
619 self._check_data()
615
620
616 def __repr__(self):
621 def __repr__(self):
617 if not self._show_mem_addr:
622 if not self._show_mem_addr:
618 cls = self.__class__
623 cls = self.__class__
619 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
624 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
620 else:
625 else:
621 r = super(DisplayObject, self).__repr__()
626 r = super(DisplayObject, self).__repr__()
622 return r
627 return r
623
628
624 def _check_data(self):
629 def _check_data(self):
625 """Override in subclasses if there's something to check."""
630 """Override in subclasses if there's something to check."""
626 pass
631 pass
627
632
628 def reload(self):
633 def reload(self):
629 """Reload the raw data from file or URL."""
634 """Reload the raw data from file or URL."""
630 if self.filename is not None:
635 if self.filename is not None:
631 with open(self.filename, self._read_flags) as f:
636 with open(self.filename, self._read_flags) as f:
632 self.data = f.read()
637 self.data = f.read()
633 elif self.url is not None:
638 elif self.url is not None:
634 try:
639 try:
635 try:
640 try:
636 from urllib.request import urlopen # Py3
641 from urllib.request import urlopen # Py3
637 except ImportError:
642 except ImportError:
638 from urllib2 import urlopen
643 from urllib2 import urlopen
639 response = urlopen(self.url)
644 response = urlopen(self.url)
640 self.data = response.read()
645 self.data = response.read()
641 # extract encoding from header, if there is one:
646 # extract encoding from header, if there is one:
642 encoding = None
647 encoding = None
643 for sub in response.headers['content-type'].split(';'):
648 for sub in response.headers['content-type'].split(';'):
644 sub = sub.strip()
649 sub = sub.strip()
645 if sub.startswith('charset'):
650 if sub.startswith('charset'):
646 encoding = sub.split('=')[-1].strip()
651 encoding = sub.split('=')[-1].strip()
647 break
652 break
648 # decode data, if an encoding was specified
653 # decode data, if an encoding was specified
649 if encoding:
654 if encoding:
650 self.data = self.data.decode(encoding, 'replace')
655 self.data = self.data.decode(encoding, 'replace')
651 except:
656 except:
652 self.data = None
657 self.data = None
653
658
654 class TextDisplayObject(DisplayObject):
659 class TextDisplayObject(DisplayObject):
655 """Validate that display data is text"""
660 """Validate that display data is text"""
656 def _check_data(self):
661 def _check_data(self):
657 if self.data is not None and not isinstance(self.data, string_types):
662 if self.data is not None and not isinstance(self.data, string_types):
658 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
663 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
659
664
660 class Pretty(TextDisplayObject):
665 class Pretty(TextDisplayObject):
661
666
662 def _repr_pretty_(self, pp, cycle):
667 def _repr_pretty_(self, pp, cycle):
663 return pp.text(self.data)
668 return pp.text(self.data)
664
669
665
670
666 class HTML(TextDisplayObject):
671 class HTML(TextDisplayObject):
667
672
668 def _repr_html_(self):
673 def _repr_html_(self):
669 return self.data
674 return self.data
670
675
671 def __html__(self):
676 def __html__(self):
672 """
677 """
673 This method exists to inform other HTML-using modules (e.g. Markupsafe,
678 This method exists to inform other HTML-using modules (e.g. Markupsafe,
674 htmltag, etc) that this object is HTML and does not need things like
679 htmltag, etc) that this object is HTML and does not need things like
675 special characters (<>&) escaped.
680 special characters (<>&) escaped.
676 """
681 """
677 return self._repr_html_()
682 return self._repr_html_()
678
683
679
684
680 class Markdown(TextDisplayObject):
685 class Markdown(TextDisplayObject):
681
686
682 def _repr_markdown_(self):
687 def _repr_markdown_(self):
683 return self.data
688 return self.data
684
689
685
690
686 class Math(TextDisplayObject):
691 class Math(TextDisplayObject):
687
692
688 def _repr_latex_(self):
693 def _repr_latex_(self):
689 s = self.data.strip('$')
694 s = self.data.strip('$')
690 return "$$%s$$" % s
695 return "$$%s$$" % s
691
696
692
697
693 class Latex(TextDisplayObject):
698 class Latex(TextDisplayObject):
694
699
695 def _repr_latex_(self):
700 def _repr_latex_(self):
696 return self.data
701 return self.data
697
702
698
703
699 class SVG(DisplayObject):
704 class SVG(DisplayObject):
700
705
701 _read_flags = 'rb'
706 _read_flags = 'rb'
702 # wrap data in a property, which extracts the <svg> tag, discarding
707 # wrap data in a property, which extracts the <svg> tag, discarding
703 # document headers
708 # document headers
704 _data = None
709 _data = None
705
710
706 @property
711 @property
707 def data(self):
712 def data(self):
708 return self._data
713 return self._data
709
714
710 @data.setter
715 @data.setter
711 def data(self, svg):
716 def data(self, svg):
712 if svg is None:
717 if svg is None:
713 self._data = None
718 self._data = None
714 return
719 return
715 # parse into dom object
720 # parse into dom object
716 from xml.dom import minidom
721 from xml.dom import minidom
717 svg = cast_bytes_py2(svg)
722 svg = cast_bytes_py2(svg)
718 x = minidom.parseString(svg)
723 x = minidom.parseString(svg)
719 # get svg tag (should be 1)
724 # get svg tag (should be 1)
720 found_svg = x.getElementsByTagName('svg')
725 found_svg = x.getElementsByTagName('svg')
721 if found_svg:
726 if found_svg:
722 svg = found_svg[0].toxml()
727 svg = found_svg[0].toxml()
723 else:
728 else:
724 # fallback on the input, trust the user
729 # fallback on the input, trust the user
725 # but this is probably an error.
730 # but this is probably an error.
726 pass
731 pass
727 svg = cast_unicode(svg)
732 svg = cast_unicode(svg)
728 self._data = svg
733 self._data = svg
729
734
730 def _repr_svg_(self):
735 def _repr_svg_(self):
731 return self.data
736 return self.data
732
737
733 class ProgressBar(DisplayObject):
738 class ProgressBar(DisplayObject):
734 """Progressbar supports displaying a progressbar like element
739 """Progressbar supports displaying a progressbar like element
735 """
740 """
736 def __init__(self, total):
741 def __init__(self, total):
737 """Creates a new progressbar
742 """Creates a new progressbar
738
743
739 Parameters
744 Parameters
740 ----------
745 ----------
741 total : int
746 total : int
742 maximum size of the progressbar
747 maximum size of the progressbar
743 """
748 """
744 self.total = total
749 self.total = total
745 self._progress = 0
750 self._progress = 0
746 self.html_width = '60ex'
751 self.html_width = '60ex'
747 self.text_width = 60
752 self.text_width = 60
748 self._display_id = hexlify(os.urandom(8)).decode('ascii')
753 self._display_id = hexlify(os.urandom(8)).decode('ascii')
749
754
750 def __repr__(self):
755 def __repr__(self):
751 fraction = self.progress / self.total
756 fraction = self.progress / self.total
752 filled = '=' * int(fraction * self.text_width)
757 filled = '=' * int(fraction * self.text_width)
753 rest = ' ' * (self.text_width - len(filled))
758 rest = ' ' * (self.text_width - len(filled))
754 return '[{}{}] {}/{}'.format(
759 return '[{}{}] {}/{}'.format(
755 filled, rest,
760 filled, rest,
756 self.progress, self.total,
761 self.progress, self.total,
757 )
762 )
758
763
759 def _repr_html_(self):
764 def _repr_html_(self):
760 return "<progress style='width:{}' max='{}' value='{}'></progress>".format(
765 return "<progress style='width:{}' max='{}' value='{}'></progress>".format(
761 self.html_width, self.total, self.progress)
766 self.html_width, self.total, self.progress)
762
767
763 def display(self):
768 def display(self):
764 display(self, display_id=self._display_id)
769 display(self, display_id=self._display_id)
765
770
766 def update(self):
771 def update(self):
767 display(self, display_id=self._display_id, update=True)
772 display(self, display_id=self._display_id, update=True)
768
773
769 @property
774 @property
770 def progress(self):
775 def progress(self):
771 return self._progress
776 return self._progress
772
777
773 @progress.setter
778 @progress.setter
774 def progress(self, value):
779 def progress(self, value):
775 self._progress = value
780 self._progress = value
776 self.update()
781 self.update()
777
782
778 def __iter__(self):
783 def __iter__(self):
779 self.display()
784 self.display()
780 self._progress = -1 # First iteration is 0
785 self._progress = -1 # First iteration is 0
781 return self
786 return self
782
787
783 def __next__(self):
788 def __next__(self):
784 """Returns current value and increments display by one."""
789 """Returns current value and increments display by one."""
785 self.progress += 1
790 self.progress += 1
786 if self.progress < self.total:
791 if self.progress < self.total:
787 return self.progress
792 return self.progress
788 else:
793 else:
789 raise StopIteration()
794 raise StopIteration()
790
795
791 def next(self):
796 def next(self):
792 """Python 2 compatibility"""
797 """Python 2 compatibility"""
793 return self.__next__()
798 return self.__next__()
794
799
795 class JSON(DisplayObject):
800 class JSON(DisplayObject):
796 """JSON expects a JSON-able dict or list
801 """JSON expects a JSON-able dict or list
797
802
798 not an already-serialized JSON string.
803 not an already-serialized JSON string.
799
804
800 Scalar types (None, number, string) are not allowed, only dict or list containers.
805 Scalar types (None, number, string) are not allowed, only dict or list containers.
801 """
806 """
802 # wrap data in a property, which warns about passing already-serialized JSON
807 # wrap data in a property, which warns about passing already-serialized JSON
803 _data = None
808 _data = None
804 def _check_data(self):
809 def _check_data(self):
805 if self.data is not None and not isinstance(self.data, (dict, list)):
810 if self.data is not None and not isinstance(self.data, (dict, list)):
806 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
811 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
807
812
808 @property
813 @property
809 def data(self):
814 def data(self):
810 return self._data
815 return self._data
811
816
812 @data.setter
817 @data.setter
813 def data(self, data):
818 def data(self, data):
814 if isinstance(data, string_types):
819 if isinstance(data, string_types):
815 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
820 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
816 data = json.loads(data)
821 data = json.loads(data)
817 self._data = data
822 self._data = data
818
823
819 def _repr_json_(self):
824 def _repr_json_(self):
820 return self.data
825 return self.data
821
826
822 css_t = """$("head").append($("<link/>").attr({
827 css_t = """$("head").append($("<link/>").attr({
823 rel: "stylesheet",
828 rel: "stylesheet",
824 type: "text/css",
829 type: "text/css",
825 href: "%s"
830 href: "%s"
826 }));
831 }));
827 """
832 """
828
833
829 lib_t1 = """$.getScript("%s", function () {
834 lib_t1 = """$.getScript("%s", function () {
830 """
835 """
831 lib_t2 = """});
836 lib_t2 = """});
832 """
837 """
833
838
834 class Javascript(TextDisplayObject):
839 class Javascript(TextDisplayObject):
835
840
836 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
841 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
837 """Create a Javascript display object given raw data.
842 """Create a Javascript display object given raw data.
838
843
839 When this object is returned by an expression or passed to the
844 When this object is returned by an expression or passed to the
840 display function, it will result in the data being displayed
845 display function, it will result in the data being displayed
841 in the frontend. If the data is a URL, the data will first be
846 in the frontend. If the data is a URL, the data will first be
842 downloaded and then displayed.
847 downloaded and then displayed.
843
848
844 In the Notebook, the containing element will be available as `element`,
849 In the Notebook, the containing element will be available as `element`,
845 and jQuery will be available. Content appended to `element` will be
850 and jQuery will be available. Content appended to `element` will be
846 visible in the output area.
851 visible in the output area.
847
852
848 Parameters
853 Parameters
849 ----------
854 ----------
850 data : unicode, str or bytes
855 data : unicode, str or bytes
851 The Javascript source code or a URL to download it from.
856 The Javascript source code or a URL to download it from.
852 url : unicode
857 url : unicode
853 A URL to download the data from.
858 A URL to download the data from.
854 filename : unicode
859 filename : unicode
855 Path to a local file to load the data from.
860 Path to a local file to load the data from.
856 lib : list or str
861 lib : list or str
857 A sequence of Javascript library URLs to load asynchronously before
862 A sequence of Javascript library URLs to load asynchronously before
858 running the source code. The full URLs of the libraries should
863 running the source code. The full URLs of the libraries should
859 be given. A single Javascript library URL can also be given as a
864 be given. A single Javascript library URL can also be given as a
860 string.
865 string.
861 css: : list or str
866 css: : list or str
862 A sequence of css files to load before running the source code.
867 A sequence of css files to load before running the source code.
863 The full URLs of the css files should be given. A single css URL
868 The full URLs of the css files should be given. A single css URL
864 can also be given as a string.
869 can also be given as a string.
865 """
870 """
866 if isinstance(lib, string_types):
871 if isinstance(lib, string_types):
867 lib = [lib]
872 lib = [lib]
868 elif lib is None:
873 elif lib is None:
869 lib = []
874 lib = []
870 if isinstance(css, string_types):
875 if isinstance(css, string_types):
871 css = [css]
876 css = [css]
872 elif css is None:
877 elif css is None:
873 css = []
878 css = []
874 if not isinstance(lib, (list,tuple)):
879 if not isinstance(lib, (list,tuple)):
875 raise TypeError('expected sequence, got: %r' % lib)
880 raise TypeError('expected sequence, got: %r' % lib)
876 if not isinstance(css, (list,tuple)):
881 if not isinstance(css, (list,tuple)):
877 raise TypeError('expected sequence, got: %r' % css)
882 raise TypeError('expected sequence, got: %r' % css)
878 self.lib = lib
883 self.lib = lib
879 self.css = css
884 self.css = css
880 super(Javascript, self).__init__(data=data, url=url, filename=filename)
885 super(Javascript, self).__init__(data=data, url=url, filename=filename)
881
886
882 def _repr_javascript_(self):
887 def _repr_javascript_(self):
883 r = ''
888 r = ''
884 for c in self.css:
889 for c in self.css:
885 r += css_t % c
890 r += css_t % c
886 for l in self.lib:
891 for l in self.lib:
887 r += lib_t1 % l
892 r += lib_t1 % l
888 r += self.data
893 r += self.data
889 r += lib_t2*len(self.lib)
894 r += lib_t2*len(self.lib)
890 return r
895 return r
891
896
892 # constants for identifying png/jpeg data
897 # constants for identifying png/jpeg data
893 _PNG = b'\x89PNG\r\n\x1a\n'
898 _PNG = b'\x89PNG\r\n\x1a\n'
894 _JPEG = b'\xff\xd8'
899 _JPEG = b'\xff\xd8'
895
900
896 def _pngxy(data):
901 def _pngxy(data):
897 """read the (width, height) from a PNG header"""
902 """read the (width, height) from a PNG header"""
898 ihdr = data.index(b'IHDR')
903 ihdr = data.index(b'IHDR')
899 # next 8 bytes are width/height
904 # next 8 bytes are width/height
900 w4h4 = data[ihdr+4:ihdr+12]
905 w4h4 = data[ihdr+4:ihdr+12]
901 return struct.unpack('>ii', w4h4)
906 return struct.unpack('>ii', w4h4)
902
907
903 def _jpegxy(data):
908 def _jpegxy(data):
904 """read the (width, height) from a JPEG header"""
909 """read the (width, height) from a JPEG header"""
905 # adapted from http://www.64lines.com/jpeg-width-height
910 # adapted from http://www.64lines.com/jpeg-width-height
906
911
907 idx = 4
912 idx = 4
908 while True:
913 while True:
909 block_size = struct.unpack('>H', data[idx:idx+2])[0]
914 block_size = struct.unpack('>H', data[idx:idx+2])[0]
910 idx = idx + block_size
915 idx = idx + block_size
911 if data[idx:idx+2] == b'\xFF\xC0':
916 if data[idx:idx+2] == b'\xFF\xC0':
912 # found Start of Frame
917 # found Start of Frame
913 iSOF = idx
918 iSOF = idx
914 break
919 break
915 else:
920 else:
916 # read another block
921 # read another block
917 idx += 2
922 idx += 2
918
923
919 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
924 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
920 return w, h
925 return w, h
921
926
922 class Image(DisplayObject):
927 class Image(DisplayObject):
923
928
924 _read_flags = 'rb'
929 _read_flags = 'rb'
925 _FMT_JPEG = u'jpeg'
930 _FMT_JPEG = u'jpeg'
926 _FMT_PNG = u'png'
931 _FMT_PNG = u'png'
927 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
932 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
928
933
929 def __init__(self, data=None, url=None, filename=None, format=None,
934 def __init__(self, data=None, url=None, filename=None, format=None,
930 embed=None, width=None, height=None, retina=False,
935 embed=None, width=None, height=None, retina=False,
931 unconfined=False, metadata=None):
936 unconfined=False, metadata=None):
932 """Create a PNG/JPEG image object given raw data.
937 """Create a PNG/JPEG image object given raw data.
933
938
934 When this object is returned by an input cell or passed to the
939 When this object is returned by an input cell or passed to the
935 display function, it will result in the image being displayed
940 display function, it will result in the image being displayed
936 in the frontend.
941 in the frontend.
937
942
938 Parameters
943 Parameters
939 ----------
944 ----------
940 data : unicode, str or bytes
945 data : unicode, str or bytes
941 The raw image data or a URL or filename to load the data from.
946 The raw image data or a URL or filename to load the data from.
942 This always results in embedded image data.
947 This always results in embedded image data.
943 url : unicode
948 url : unicode
944 A URL to download the data from. If you specify `url=`,
949 A URL to download the data from. If you specify `url=`,
945 the image data will not be embedded unless you also specify `embed=True`.
950 the image data will not be embedded unless you also specify `embed=True`.
946 filename : unicode
951 filename : unicode
947 Path to a local file to load the data from.
952 Path to a local file to load the data from.
948 Images from a file are always embedded.
953 Images from a file are always embedded.
949 format : unicode
954 format : unicode
950 The format of the image data (png/jpeg/jpg). If a filename or URL is given
955 The format of the image data (png/jpeg/jpg). If a filename or URL is given
951 for format will be inferred from the filename extension.
956 for format will be inferred from the filename extension.
952 embed : bool
957 embed : bool
953 Should the image data be embedded using a data URI (True) or be
958 Should the image data be embedded using a data URI (True) or be
954 loaded using an <img> tag. Set this to True if you want the image
959 loaded using an <img> tag. Set this to True if you want the image
955 to be viewable later with no internet connection in the notebook.
960 to be viewable later with no internet connection in the notebook.
956
961
957 Default is `True`, unless the keyword argument `url` is set, then
962 Default is `True`, unless the keyword argument `url` is set, then
958 default value is `False`.
963 default value is `False`.
959
964
960 Note that QtConsole is not able to display images if `embed` is set to `False`
965 Note that QtConsole is not able to display images if `embed` is set to `False`
961 width : int
966 width : int
962 Width in pixels to which to constrain the image in html
967 Width in pixels to which to constrain the image in html
963 height : int
968 height : int
964 Height in pixels to which to constrain the image in html
969 Height in pixels to which to constrain the image in html
965 retina : bool
970 retina : bool
966 Automatically set the width and height to half of the measured
971 Automatically set the width and height to half of the measured
967 width and height.
972 width and height.
968 This only works for embedded images because it reads the width/height
973 This only works for embedded images because it reads the width/height
969 from image data.
974 from image data.
970 For non-embedded images, you can just set the desired display width
975 For non-embedded images, you can just set the desired display width
971 and height directly.
976 and height directly.
972 unconfined: bool
977 unconfined: bool
973 Set unconfined=True to disable max-width confinement of the image.
978 Set unconfined=True to disable max-width confinement of the image.
974 metadata: dict
979 metadata: dict
975 Specify extra metadata to attach to the image.
980 Specify extra metadata to attach to the image.
976
981
977 Examples
982 Examples
978 --------
983 --------
979 # embedded image data, works in qtconsole and notebook
984 # embedded image data, works in qtconsole and notebook
980 # when passed positionally, the first arg can be any of raw image data,
985 # when passed positionally, the first arg can be any of raw image data,
981 # a URL, or a filename from which to load image data.
986 # a URL, or a filename from which to load image data.
982 # The result is always embedding image data for inline images.
987 # The result is always embedding image data for inline images.
983 Image('http://www.google.fr/images/srpr/logo3w.png')
988 Image('http://www.google.fr/images/srpr/logo3w.png')
984 Image('/path/to/image.jpg')
989 Image('/path/to/image.jpg')
985 Image(b'RAW_PNG_DATA...')
990 Image(b'RAW_PNG_DATA...')
986
991
987 # Specifying Image(url=...) does not embed the image data,
992 # Specifying Image(url=...) does not embed the image data,
988 # it only generates `<img>` tag with a link to the source.
993 # it only generates `<img>` tag with a link to the source.
989 # This will not work in the qtconsole or offline.
994 # This will not work in the qtconsole or offline.
990 Image(url='http://www.google.fr/images/srpr/logo3w.png')
995 Image(url='http://www.google.fr/images/srpr/logo3w.png')
991
996
992 """
997 """
993 if filename is not None:
998 if filename is not None:
994 ext = self._find_ext(filename)
999 ext = self._find_ext(filename)
995 elif url is not None:
1000 elif url is not None:
996 ext = self._find_ext(url)
1001 ext = self._find_ext(url)
997 elif data is None:
1002 elif data is None:
998 raise ValueError("No image data found. Expecting filename, url, or data.")
1003 raise ValueError("No image data found. Expecting filename, url, or data.")
999 elif isinstance(data, string_types) and (
1004 elif isinstance(data, string_types) and (
1000 data.startswith('http') or _safe_exists(data)
1005 data.startswith('http') or _safe_exists(data)
1001 ):
1006 ):
1002 ext = self._find_ext(data)
1007 ext = self._find_ext(data)
1003 else:
1008 else:
1004 ext = None
1009 ext = None
1005
1010
1006 if format is None:
1011 if format is None:
1007 if ext is not None:
1012 if ext is not None:
1008 if ext == u'jpg' or ext == u'jpeg':
1013 if ext == u'jpg' or ext == u'jpeg':
1009 format = self._FMT_JPEG
1014 format = self._FMT_JPEG
1010 elif ext == u'png':
1015 elif ext == u'png':
1011 format = self._FMT_PNG
1016 format = self._FMT_PNG
1012 else:
1017 else:
1013 format = ext.lower()
1018 format = ext.lower()
1014 elif isinstance(data, bytes):
1019 elif isinstance(data, bytes):
1015 # infer image type from image data header,
1020 # infer image type from image data header,
1016 # only if format has not been specified.
1021 # only if format has not been specified.
1017 if data[:2] == _JPEG:
1022 if data[:2] == _JPEG:
1018 format = self._FMT_JPEG
1023 format = self._FMT_JPEG
1019
1024
1020 # failed to detect format, default png
1025 # failed to detect format, default png
1021 if format is None:
1026 if format is None:
1022 format = 'png'
1027 format = 'png'
1023
1028
1024 if format.lower() == 'jpg':
1029 if format.lower() == 'jpg':
1025 # jpg->jpeg
1030 # jpg->jpeg
1026 format = self._FMT_JPEG
1031 format = self._FMT_JPEG
1027
1032
1028 self.format = unicode_type(format).lower()
1033 self.format = unicode_type(format).lower()
1029 self.embed = embed if embed is not None else (url is None)
1034 self.embed = embed if embed is not None else (url is None)
1030
1035
1031 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
1036 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
1032 raise ValueError("Cannot embed the '%s' image format" % (self.format))
1037 raise ValueError("Cannot embed the '%s' image format" % (self.format))
1033 self.width = width
1038 self.width = width
1034 self.height = height
1039 self.height = height
1035 self.retina = retina
1040 self.retina = retina
1036 self.unconfined = unconfined
1041 self.unconfined = unconfined
1037 self.metadata = metadata
1042 self.metadata = metadata
1038 super(Image, self).__init__(data=data, url=url, filename=filename)
1043 super(Image, self).__init__(data=data, url=url, filename=filename)
1039
1044
1040 if retina:
1045 if retina:
1041 self._retina_shape()
1046 self._retina_shape()
1042
1047
1043 def _retina_shape(self):
1048 def _retina_shape(self):
1044 """load pixel-doubled width and height from image data"""
1049 """load pixel-doubled width and height from image data"""
1045 if not self.embed:
1050 if not self.embed:
1046 return
1051 return
1047 if self.format == 'png':
1052 if self.format == 'png':
1048 w, h = _pngxy(self.data)
1053 w, h = _pngxy(self.data)
1049 elif self.format == 'jpeg':
1054 elif self.format == 'jpeg':
1050 w, h = _jpegxy(self.data)
1055 w, h = _jpegxy(self.data)
1051 else:
1056 else:
1052 # retina only supports png
1057 # retina only supports png
1053 return
1058 return
1054 self.width = w // 2
1059 self.width = w // 2
1055 self.height = h // 2
1060 self.height = h // 2
1056
1061
1057 def reload(self):
1062 def reload(self):
1058 """Reload the raw data from file or URL."""
1063 """Reload the raw data from file or URL."""
1059 if self.embed:
1064 if self.embed:
1060 super(Image,self).reload()
1065 super(Image,self).reload()
1061 if self.retina:
1066 if self.retina:
1062 self._retina_shape()
1067 self._retina_shape()
1063
1068
1064 def _repr_html_(self):
1069 def _repr_html_(self):
1065 if not self.embed:
1070 if not self.embed:
1066 width = height = klass = ''
1071 width = height = klass = ''
1067 if self.width:
1072 if self.width:
1068 width = ' width="%d"' % self.width
1073 width = ' width="%d"' % self.width
1069 if self.height:
1074 if self.height:
1070 height = ' height="%d"' % self.height
1075 height = ' height="%d"' % self.height
1071 if self.unconfined:
1076 if self.unconfined:
1072 klass = ' class="unconfined"'
1077 klass = ' class="unconfined"'
1073 return u'<img src="{url}"{width}{height}{klass}/>'.format(
1078 return u'<img src="{url}"{width}{height}{klass}/>'.format(
1074 url=self.url,
1079 url=self.url,
1075 width=width,
1080 width=width,
1076 height=height,
1081 height=height,
1077 klass=klass,
1082 klass=klass,
1078 )
1083 )
1079
1084
1080 def _data_and_metadata(self):
1085 def _data_and_metadata(self):
1081 """shortcut for returning metadata with shape information, if defined"""
1086 """shortcut for returning metadata with shape information, if defined"""
1082 md = {}
1087 md = {}
1083 if self.width:
1088 if self.width:
1084 md['width'] = self.width
1089 md['width'] = self.width
1085 if self.height:
1090 if self.height:
1086 md['height'] = self.height
1091 md['height'] = self.height
1087 if self.unconfined:
1092 if self.unconfined:
1088 md['unconfined'] = self.unconfined
1093 md['unconfined'] = self.unconfined
1089 if self.metadata:
1094 if self.metadata:
1090 md.update(self.metadata)
1095 md.update(self.metadata)
1091 if md:
1096 if md:
1092 return self.data, md
1097 return self.data, md
1093 else:
1098 else:
1094 return self.data
1099 return self.data
1095
1100
1096 def _repr_png_(self):
1101 def _repr_png_(self):
1097 if self.embed and self.format == u'png':
1102 if self.embed and self.format == u'png':
1098 return self._data_and_metadata()
1103 return self._data_and_metadata()
1099
1104
1100 def _repr_jpeg_(self):
1105 def _repr_jpeg_(self):
1101 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
1106 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
1102 return self._data_and_metadata()
1107 return self._data_and_metadata()
1103
1108
1104 def _find_ext(self, s):
1109 def _find_ext(self, s):
1105 return unicode_type(s.split('.')[-1].lower())
1110 return unicode_type(s.split('.')[-1].lower())
1106
1111
1107 class Video(DisplayObject):
1112 class Video(DisplayObject):
1108
1113
1109 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
1114 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
1110 """Create a video object given raw data or an URL.
1115 """Create a video object given raw data or an URL.
1111
1116
1112 When this object is returned by an input cell or passed to the
1117 When this object is returned by an input cell or passed to the
1113 display function, it will result in the video being displayed
1118 display function, it will result in the video being displayed
1114 in the frontend.
1119 in the frontend.
1115
1120
1116 Parameters
1121 Parameters
1117 ----------
1122 ----------
1118 data : unicode, str or bytes
1123 data : unicode, str or bytes
1119 The raw video data or a URL or filename to load the data from.
1124 The raw video data or a URL or filename to load the data from.
1120 Raw data will require passing `embed=True`.
1125 Raw data will require passing `embed=True`.
1121 url : unicode
1126 url : unicode
1122 A URL for the video. If you specify `url=`,
1127 A URL for the video. If you specify `url=`,
1123 the image data will not be embedded.
1128 the image data will not be embedded.
1124 filename : unicode
1129 filename : unicode
1125 Path to a local file containing the video.
1130 Path to a local file containing the video.
1126 Will be interpreted as a local URL unless `embed=True`.
1131 Will be interpreted as a local URL unless `embed=True`.
1127 embed : bool
1132 embed : bool
1128 Should the video be embedded using a data URI (True) or be
1133 Should the video be embedded using a data URI (True) or be
1129 loaded using a <video> tag (False).
1134 loaded using a <video> tag (False).
1130
1135
1131 Since videos are large, embedding them should be avoided, if possible.
1136 Since videos are large, embedding them should be avoided, if possible.
1132 You must confirm embedding as your intention by passing `embed=True`.
1137 You must confirm embedding as your intention by passing `embed=True`.
1133
1138
1134 Local files can be displayed with URLs without embedding the content, via::
1139 Local files can be displayed with URLs without embedding the content, via::
1135
1140
1136 Video('./video.mp4')
1141 Video('./video.mp4')
1137
1142
1138 mimetype: unicode
1143 mimetype: unicode
1139 Specify the mimetype for embedded videos.
1144 Specify the mimetype for embedded videos.
1140 Default will be guessed from file extension, if available.
1145 Default will be guessed from file extension, if available.
1141
1146
1142 Examples
1147 Examples
1143 --------
1148 --------
1144
1149
1145 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
1150 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
1146 Video('path/to/video.mp4')
1151 Video('path/to/video.mp4')
1147 Video('path/to/video.mp4', embed=True)
1152 Video('path/to/video.mp4', embed=True)
1148 Video(b'raw-videodata', embed=True)
1153 Video(b'raw-videodata', embed=True)
1149 """
1154 """
1150 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
1155 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
1151 url = data
1156 url = data
1152 data = None
1157 data = None
1153 elif os.path.exists(data):
1158 elif os.path.exists(data):
1154 filename = data
1159 filename = data
1155 data = None
1160 data = None
1156
1161
1157 if data and not embed:
1162 if data and not embed:
1158 msg = ''.join([
1163 msg = ''.join([
1159 "To embed videos, you must pass embed=True ",
1164 "To embed videos, you must pass embed=True ",
1160 "(this may make your notebook files huge)\n",
1165 "(this may make your notebook files huge)\n",
1161 "Consider passing Video(url='...')",
1166 "Consider passing Video(url='...')",
1162 ])
1167 ])
1163 raise ValueError(msg)
1168 raise ValueError(msg)
1164
1169
1165 self.mimetype = mimetype
1170 self.mimetype = mimetype
1166 self.embed = embed
1171 self.embed = embed
1167 super(Video, self).__init__(data=data, url=url, filename=filename)
1172 super(Video, self).__init__(data=data, url=url, filename=filename)
1168
1173
1169 def _repr_html_(self):
1174 def _repr_html_(self):
1170 # External URLs and potentially local files are not embedded into the
1175 # External URLs and potentially local files are not embedded into the
1171 # notebook output.
1176 # notebook output.
1172 if not self.embed:
1177 if not self.embed:
1173 url = self.url if self.url is not None else self.filename
1178 url = self.url if self.url is not None else self.filename
1174 output = """<video src="{0}" controls>
1179 output = """<video src="{0}" controls>
1175 Your browser does not support the <code>video</code> element.
1180 Your browser does not support the <code>video</code> element.
1176 </video>""".format(url)
1181 </video>""".format(url)
1177 return output
1182 return output
1178
1183
1179 # Embedded videos are base64-encoded.
1184 # Embedded videos are base64-encoded.
1180 mimetype = self.mimetype
1185 mimetype = self.mimetype
1181 if self.filename is not None:
1186 if self.filename is not None:
1182 if not mimetype:
1187 if not mimetype:
1183 mimetype, _ = mimetypes.guess_type(self.filename)
1188 mimetype, _ = mimetypes.guess_type(self.filename)
1184
1189
1185 with open(self.filename, 'rb') as f:
1190 with open(self.filename, 'rb') as f:
1186 video = f.read()
1191 video = f.read()
1187 else:
1192 else:
1188 video = self.data
1193 video = self.data
1189 if isinstance(video, unicode_type):
1194 if isinstance(video, unicode_type):
1190 # unicode input is already b64-encoded
1195 # unicode input is already b64-encoded
1191 b64_video = video
1196 b64_video = video
1192 else:
1197 else:
1193 b64_video = base64_encode(video).decode('ascii').rstrip()
1198 b64_video = base64_encode(video).decode('ascii').rstrip()
1194
1199
1195 output = """<video controls>
1200 output = """<video controls>
1196 <source src="data:{0};base64,{1}" type="{0}">
1201 <source src="data:{0};base64,{1}" type="{0}">
1197 Your browser does not support the video tag.
1202 Your browser does not support the video tag.
1198 </video>""".format(mimetype, b64_video)
1203 </video>""".format(mimetype, b64_video)
1199 return output
1204 return output
1200
1205
1201 def reload(self):
1206 def reload(self):
1202 # TODO
1207 # TODO
1203 pass
1208 pass
1204
1209
1205 def _repr_png_(self):
1210 def _repr_png_(self):
1206 # TODO
1211 # TODO
1207 pass
1212 pass
1208 def _repr_jpeg_(self):
1213 def _repr_jpeg_(self):
1209 # TODO
1214 # TODO
1210 pass
1215 pass
1211
1216
1212 def clear_output(wait=False):
1217 def clear_output(wait=False):
1213 """Clear the output of the current cell receiving output.
1218 """Clear the output of the current cell receiving output.
1214
1219
1215 Parameters
1220 Parameters
1216 ----------
1221 ----------
1217 wait : bool [default: false]
1222 wait : bool [default: false]
1218 Wait to clear the output until new output is available to replace it."""
1223 Wait to clear the output until new output is available to replace it."""
1219 from IPython.core.interactiveshell import InteractiveShell
1224 from IPython.core.interactiveshell import InteractiveShell
1220 if InteractiveShell.initialized():
1225 if InteractiveShell.initialized():
1221 InteractiveShell.instance().display_pub.clear_output(wait)
1226 InteractiveShell.instance().display_pub.clear_output(wait)
1222 else:
1227 else:
1223 print('\033[2K\r', end='')
1228 print('\033[2K\r', end='')
1224 sys.stdout.flush()
1229 sys.stdout.flush()
1225 print('\033[2K\r', end='')
1230 print('\033[2K\r', end='')
1226 sys.stderr.flush()
1231 sys.stderr.flush()
1227
1232
1228
1233
1229 @skip_doctest
1234 @skip_doctest
1230 def set_matplotlib_formats(*formats, **kwargs):
1235 def set_matplotlib_formats(*formats, **kwargs):
1231 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1236 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1232
1237
1233 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1238 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1234
1239
1235 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1240 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1236
1241
1237 To set this in your config files use the following::
1242 To set this in your config files use the following::
1238
1243
1239 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1244 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1240 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1245 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1241
1246
1242 Parameters
1247 Parameters
1243 ----------
1248 ----------
1244 *formats : strs
1249 *formats : strs
1245 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1250 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1246 **kwargs :
1251 **kwargs :
1247 Keyword args will be relayed to ``figure.canvas.print_figure``.
1252 Keyword args will be relayed to ``figure.canvas.print_figure``.
1248 """
1253 """
1249 from IPython.core.interactiveshell import InteractiveShell
1254 from IPython.core.interactiveshell import InteractiveShell
1250 from IPython.core.pylabtools import select_figure_formats
1255 from IPython.core.pylabtools import select_figure_formats
1251 # build kwargs, starting with InlineBackend config
1256 # build kwargs, starting with InlineBackend config
1252 kw = {}
1257 kw = {}
1253 from ipykernel.pylab.config import InlineBackend
1258 from ipykernel.pylab.config import InlineBackend
1254 cfg = InlineBackend.instance()
1259 cfg = InlineBackend.instance()
1255 kw.update(cfg.print_figure_kwargs)
1260 kw.update(cfg.print_figure_kwargs)
1256 kw.update(**kwargs)
1261 kw.update(**kwargs)
1257 shell = InteractiveShell.instance()
1262 shell = InteractiveShell.instance()
1258 select_figure_formats(shell, formats, **kw)
1263 select_figure_formats(shell, formats, **kw)
1259
1264
1260 @skip_doctest
1265 @skip_doctest
1261 def set_matplotlib_close(close=True):
1266 def set_matplotlib_close(close=True):
1262 """Set whether the inline backend closes all figures automatically or not.
1267 """Set whether the inline backend closes all figures automatically or not.
1263
1268
1264 By default, the inline backend used in the IPython Notebook will close all
1269 By default, the inline backend used in the IPython Notebook will close all
1265 matplotlib figures automatically after each cell is run. This means that
1270 matplotlib figures automatically after each cell is run. This means that
1266 plots in different cells won't interfere. Sometimes, you may want to make
1271 plots in different cells won't interfere. Sometimes, you may want to make
1267 a plot in one cell and then refine it in later cells. This can be accomplished
1272 a plot in one cell and then refine it in later cells. This can be accomplished
1268 by::
1273 by::
1269
1274
1270 In [1]: set_matplotlib_close(False)
1275 In [1]: set_matplotlib_close(False)
1271
1276
1272 To set this in your config files use the following::
1277 To set this in your config files use the following::
1273
1278
1274 c.InlineBackend.close_figures = False
1279 c.InlineBackend.close_figures = False
1275
1280
1276 Parameters
1281 Parameters
1277 ----------
1282 ----------
1278 close : bool
1283 close : bool
1279 Should all matplotlib figures be automatically closed after each cell is
1284 Should all matplotlib figures be automatically closed after each cell is
1280 run?
1285 run?
1281 """
1286 """
1282 from ipykernel.pylab.config import InlineBackend
1287 from ipykernel.pylab.config import InlineBackend
1283 cfg = InlineBackend.instance()
1288 cfg = InlineBackend.instance()
1284 cfg.close_figures = close
1289 cfg.close_figures = close
1285
1290
General Comments 0
You need to be logged in to leave comments. Login now