##// END OF EJS Templates
Add next() for Python 2 compatibility.
Matthias Bussonnier -
Show More
@@ -1,1281 +1,1285
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 raw = kwargs.pop('raw', False)
280 raw = kwargs.pop('raw', False)
281 include = kwargs.pop('include', None)
281 include = kwargs.pop('include', None)
282 exclude = kwargs.pop('exclude', None)
282 exclude = kwargs.pop('exclude', None)
283 metadata = kwargs.pop('metadata', None)
283 metadata = kwargs.pop('metadata', None)
284 transient = kwargs.pop('transient', None)
284 transient = kwargs.pop('transient', None)
285 display_id = kwargs.pop('display_id', None)
285 display_id = kwargs.pop('display_id', None)
286 if transient is None:
286 if transient is None:
287 transient = {}
287 transient = {}
288 if display_id:
288 if display_id:
289 if display_id is True:
289 if display_id is True:
290 display_id = _new_id()
290 display_id = _new_id()
291 transient['display_id'] = display_id
291 transient['display_id'] = display_id
292 if kwargs.get('update') and 'display_id' not in transient:
292 if kwargs.get('update') and 'display_id' not in transient:
293 raise TypeError('display_id required for update_display')
293 raise TypeError('display_id required for update_display')
294 if transient:
294 if transient:
295 kwargs['transient'] = transient
295 kwargs['transient'] = transient
296
296
297 from IPython.core.interactiveshell import InteractiveShell
297 from IPython.core.interactiveshell import InteractiveShell
298
298
299 if not raw:
299 if not raw:
300 format = InteractiveShell.instance().display_formatter.format
300 format = InteractiveShell.instance().display_formatter.format
301
301
302 for obj in objs:
302 for obj in objs:
303 if raw:
303 if raw:
304 publish_display_data(data=obj, metadata=metadata, **kwargs)
304 publish_display_data(data=obj, metadata=metadata, **kwargs)
305 else:
305 else:
306 format_dict, md_dict = format(obj, include=include, exclude=exclude)
306 format_dict, md_dict = format(obj, include=include, exclude=exclude)
307 if not format_dict:
307 if not format_dict:
308 # nothing to display (e.g. _ipython_display_ took over)
308 # nothing to display (e.g. _ipython_display_ took over)
309 continue
309 continue
310 if metadata:
310 if metadata:
311 # kwarg-specified metadata gets precedence
311 # kwarg-specified metadata gets precedence
312 _merge(md_dict, metadata)
312 _merge(md_dict, metadata)
313 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
313 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
314 if display_id:
314 if display_id:
315 return DisplayHandle(display_id)
315 return DisplayHandle(display_id)
316
316
317
317
318 # use * for keyword-only display_id arg
318 # use * for keyword-only display_id arg
319 def update_display(obj, **kwargs):
319 def update_display(obj, **kwargs):
320 """Update an existing display by id
320 """Update an existing display by id
321
321
322 Parameters
322 Parameters
323 ----------
323 ----------
324
324
325 obj:
325 obj:
326 The object with which to update the display
326 The object with which to update the display
327 display_id: keyword-only
327 display_id: keyword-only
328 The id of the display to update
328 The id of the display to update
329
329
330 See Also
330 See Also
331 --------
331 --------
332
332
333 :func:`display`
333 :func:`display`
334 """
334 """
335 sentinel = object()
335 sentinel = object()
336 display_id = kwargs.pop('display_id', sentinel)
336 display_id = kwargs.pop('display_id', sentinel)
337 if display_id is sentinel:
337 if display_id is sentinel:
338 raise TypeError("update_display() missing 1 required keyword-only argument: 'display_id'")
338 raise TypeError("update_display() missing 1 required keyword-only argument: 'display_id'")
339 kwargs['update'] = True
339 kwargs['update'] = True
340 display(obj, display_id=display_id, **kwargs)
340 display(obj, display_id=display_id, **kwargs)
341
341
342
342
343 class DisplayHandle(object):
343 class DisplayHandle(object):
344 """A handle on an updatable display
344 """A handle on an updatable display
345
345
346 Call `.update(obj)` to display a new object.
346 Call `.update(obj)` to display a new object.
347
347
348 Call `.display(obj`) to add a new instance of this display,
348 Call `.display(obj`) to add a new instance of this display,
349 and update existing instances.
349 and update existing instances.
350
350
351 See Also
351 See Also
352 --------
352 --------
353
353
354 :func:`display`, :func:`update_display`
354 :func:`display`, :func:`update_display`
355
355
356 """
356 """
357
357
358 def __init__(self, display_id=None):
358 def __init__(self, display_id=None):
359 if display_id is None:
359 if display_id is None:
360 display_id = _new_id()
360 display_id = _new_id()
361 self.display_id = display_id
361 self.display_id = display_id
362
362
363 def __repr__(self):
363 def __repr__(self):
364 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
364 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
365
365
366 def display(self, obj, **kwargs):
366 def display(self, obj, **kwargs):
367 """Make a new display with my id, updating existing instances.
367 """Make a new display with my id, updating existing instances.
368
368
369 Parameters
369 Parameters
370 ----------
370 ----------
371
371
372 obj:
372 obj:
373 object to display
373 object to display
374 **kwargs:
374 **kwargs:
375 additional keyword arguments passed to display
375 additional keyword arguments passed to display
376 """
376 """
377 display(obj, display_id=self.display_id, **kwargs)
377 display(obj, display_id=self.display_id, **kwargs)
378
378
379 def update(self, obj, **kwargs):
379 def update(self, obj, **kwargs):
380 """Update existing displays with my id
380 """Update existing displays with my id
381
381
382 Parameters
382 Parameters
383 ----------
383 ----------
384
384
385 obj:
385 obj:
386 object to display
386 object to display
387 **kwargs:
387 **kwargs:
388 additional keyword arguments passed to update_display
388 additional keyword arguments passed to update_display
389 """
389 """
390 update_display(obj, display_id=self.display_id, **kwargs)
390 update_display(obj, display_id=self.display_id, **kwargs)
391
391
392
392
393 def display_pretty(*objs, **kwargs):
393 def display_pretty(*objs, **kwargs):
394 """Display the pretty (default) representation of an object.
394 """Display the pretty (default) representation of an object.
395
395
396 Parameters
396 Parameters
397 ----------
397 ----------
398 objs : tuple of objects
398 objs : tuple of objects
399 The Python objects to display, or if raw=True raw text data to
399 The Python objects to display, or if raw=True raw text data to
400 display.
400 display.
401 raw : bool
401 raw : bool
402 Are the data objects raw data or Python objects that need to be
402 Are the data objects raw data or Python objects that need to be
403 formatted before display? [default: False]
403 formatted before display? [default: False]
404 metadata : dict (optional)
404 metadata : dict (optional)
405 Metadata to be associated with the specific mimetype output.
405 Metadata to be associated with the specific mimetype output.
406 """
406 """
407 _display_mimetype('text/plain', objs, **kwargs)
407 _display_mimetype('text/plain', objs, **kwargs)
408
408
409
409
410 def display_html(*objs, **kwargs):
410 def display_html(*objs, **kwargs):
411 """Display the HTML representation of an object.
411 """Display the HTML representation of an object.
412
412
413 Note: If raw=False and the object does not have a HTML
413 Note: If raw=False and the object does not have a HTML
414 representation, no HTML will be shown.
414 representation, no HTML will be shown.
415
415
416 Parameters
416 Parameters
417 ----------
417 ----------
418 objs : tuple of objects
418 objs : tuple of objects
419 The Python objects to display, or if raw=True raw HTML data to
419 The Python objects to display, or if raw=True raw HTML data to
420 display.
420 display.
421 raw : bool
421 raw : bool
422 Are the data objects raw data or Python objects that need to be
422 Are the data objects raw data or Python objects that need to be
423 formatted before display? [default: False]
423 formatted before display? [default: False]
424 metadata : dict (optional)
424 metadata : dict (optional)
425 Metadata to be associated with the specific mimetype output.
425 Metadata to be associated with the specific mimetype output.
426 """
426 """
427 _display_mimetype('text/html', objs, **kwargs)
427 _display_mimetype('text/html', objs, **kwargs)
428
428
429
429
430 def display_markdown(*objs, **kwargs):
430 def display_markdown(*objs, **kwargs):
431 """Displays the Markdown representation of an object.
431 """Displays the Markdown representation of an object.
432
432
433 Parameters
433 Parameters
434 ----------
434 ----------
435 objs : tuple of objects
435 objs : tuple of objects
436 The Python objects to display, or if raw=True raw markdown data to
436 The Python objects to display, or if raw=True raw markdown data to
437 display.
437 display.
438 raw : bool
438 raw : bool
439 Are the data objects raw data or Python objects that need to be
439 Are the data objects raw data or Python objects that need to be
440 formatted before display? [default: False]
440 formatted before display? [default: False]
441 metadata : dict (optional)
441 metadata : dict (optional)
442 Metadata to be associated with the specific mimetype output.
442 Metadata to be associated with the specific mimetype output.
443 """
443 """
444
444
445 _display_mimetype('text/markdown', objs, **kwargs)
445 _display_mimetype('text/markdown', objs, **kwargs)
446
446
447
447
448 def display_svg(*objs, **kwargs):
448 def display_svg(*objs, **kwargs):
449 """Display the SVG representation of an object.
449 """Display the SVG representation of an object.
450
450
451 Parameters
451 Parameters
452 ----------
452 ----------
453 objs : tuple of objects
453 objs : tuple of objects
454 The Python objects to display, or if raw=True raw svg data to
454 The Python objects to display, or if raw=True raw svg data to
455 display.
455 display.
456 raw : bool
456 raw : bool
457 Are the data objects raw data or Python objects that need to be
457 Are the data objects raw data or Python objects that need to be
458 formatted before display? [default: False]
458 formatted before display? [default: False]
459 metadata : dict (optional)
459 metadata : dict (optional)
460 Metadata to be associated with the specific mimetype output.
460 Metadata to be associated with the specific mimetype output.
461 """
461 """
462 _display_mimetype('image/svg+xml', objs, **kwargs)
462 _display_mimetype('image/svg+xml', objs, **kwargs)
463
463
464
464
465 def display_png(*objs, **kwargs):
465 def display_png(*objs, **kwargs):
466 """Display the PNG representation of an object.
466 """Display the PNG representation of an object.
467
467
468 Parameters
468 Parameters
469 ----------
469 ----------
470 objs : tuple of objects
470 objs : tuple of objects
471 The Python objects to display, or if raw=True raw png data to
471 The Python objects to display, or if raw=True raw png data to
472 display.
472 display.
473 raw : bool
473 raw : bool
474 Are the data objects raw data or Python objects that need to be
474 Are the data objects raw data or Python objects that need to be
475 formatted before display? [default: False]
475 formatted before display? [default: False]
476 metadata : dict (optional)
476 metadata : dict (optional)
477 Metadata to be associated with the specific mimetype output.
477 Metadata to be associated with the specific mimetype output.
478 """
478 """
479 _display_mimetype('image/png', objs, **kwargs)
479 _display_mimetype('image/png', objs, **kwargs)
480
480
481
481
482 def display_jpeg(*objs, **kwargs):
482 def display_jpeg(*objs, **kwargs):
483 """Display the JPEG representation of an object.
483 """Display the JPEG representation of an object.
484
484
485 Parameters
485 Parameters
486 ----------
486 ----------
487 objs : tuple of objects
487 objs : tuple of objects
488 The Python objects to display, or if raw=True raw JPEG data to
488 The Python objects to display, or if raw=True raw JPEG data to
489 display.
489 display.
490 raw : bool
490 raw : bool
491 Are the data objects raw data or Python objects that need to be
491 Are the data objects raw data or Python objects that need to be
492 formatted before display? [default: False]
492 formatted before display? [default: False]
493 metadata : dict (optional)
493 metadata : dict (optional)
494 Metadata to be associated with the specific mimetype output.
494 Metadata to be associated with the specific mimetype output.
495 """
495 """
496 _display_mimetype('image/jpeg', objs, **kwargs)
496 _display_mimetype('image/jpeg', objs, **kwargs)
497
497
498
498
499 def display_latex(*objs, **kwargs):
499 def display_latex(*objs, **kwargs):
500 """Display the LaTeX representation of an object.
500 """Display the LaTeX representation of an object.
501
501
502 Parameters
502 Parameters
503 ----------
503 ----------
504 objs : tuple of objects
504 objs : tuple of objects
505 The Python objects to display, or if raw=True raw latex data to
505 The Python objects to display, or if raw=True raw latex data to
506 display.
506 display.
507 raw : bool
507 raw : bool
508 Are the data objects raw data or Python objects that need to be
508 Are the data objects raw data or Python objects that need to be
509 formatted before display? [default: False]
509 formatted before display? [default: False]
510 metadata : dict (optional)
510 metadata : dict (optional)
511 Metadata to be associated with the specific mimetype output.
511 Metadata to be associated with the specific mimetype output.
512 """
512 """
513 _display_mimetype('text/latex', objs, **kwargs)
513 _display_mimetype('text/latex', objs, **kwargs)
514
514
515
515
516 def display_json(*objs, **kwargs):
516 def display_json(*objs, **kwargs):
517 """Display the JSON representation of an object.
517 """Display the JSON representation of an object.
518
518
519 Note that not many frontends support displaying JSON.
519 Note that not many frontends support displaying JSON.
520
520
521 Parameters
521 Parameters
522 ----------
522 ----------
523 objs : tuple of objects
523 objs : tuple of objects
524 The Python objects to display, or if raw=True raw json data to
524 The Python objects to display, or if raw=True raw json data to
525 display.
525 display.
526 raw : bool
526 raw : bool
527 Are the data objects raw data or Python objects that need to be
527 Are the data objects raw data or Python objects that need to be
528 formatted before display? [default: False]
528 formatted before display? [default: False]
529 metadata : dict (optional)
529 metadata : dict (optional)
530 Metadata to be associated with the specific mimetype output.
530 Metadata to be associated with the specific mimetype output.
531 """
531 """
532 _display_mimetype('application/json', objs, **kwargs)
532 _display_mimetype('application/json', objs, **kwargs)
533
533
534
534
535 def display_javascript(*objs, **kwargs):
535 def display_javascript(*objs, **kwargs):
536 """Display the Javascript representation of an object.
536 """Display the Javascript representation of an object.
537
537
538 Parameters
538 Parameters
539 ----------
539 ----------
540 objs : tuple of objects
540 objs : tuple of objects
541 The Python objects to display, or if raw=True raw javascript data to
541 The Python objects to display, or if raw=True raw javascript data to
542 display.
542 display.
543 raw : bool
543 raw : bool
544 Are the data objects raw data or Python objects that need to be
544 Are the data objects raw data or Python objects that need to be
545 formatted before display? [default: False]
545 formatted before display? [default: False]
546 metadata : dict (optional)
546 metadata : dict (optional)
547 Metadata to be associated with the specific mimetype output.
547 Metadata to be associated with the specific mimetype output.
548 """
548 """
549 _display_mimetype('application/javascript', objs, **kwargs)
549 _display_mimetype('application/javascript', objs, **kwargs)
550
550
551
551
552 def display_pdf(*objs, **kwargs):
552 def display_pdf(*objs, **kwargs):
553 """Display the PDF representation of an object.
553 """Display the PDF representation of an object.
554
554
555 Parameters
555 Parameters
556 ----------
556 ----------
557 objs : tuple of objects
557 objs : tuple of objects
558 The Python objects to display, or if raw=True raw javascript data to
558 The Python objects to display, or if raw=True raw javascript data to
559 display.
559 display.
560 raw : bool
560 raw : bool
561 Are the data objects raw data or Python objects that need to be
561 Are the data objects raw data or Python objects that need to be
562 formatted before display? [default: False]
562 formatted before display? [default: False]
563 metadata : dict (optional)
563 metadata : dict (optional)
564 Metadata to be associated with the specific mimetype output.
564 Metadata to be associated with the specific mimetype output.
565 """
565 """
566 _display_mimetype('application/pdf', objs, **kwargs)
566 _display_mimetype('application/pdf', objs, **kwargs)
567
567
568
568
569 #-----------------------------------------------------------------------------
569 #-----------------------------------------------------------------------------
570 # Smart classes
570 # Smart classes
571 #-----------------------------------------------------------------------------
571 #-----------------------------------------------------------------------------
572
572
573
573
574 class DisplayObject(object):
574 class DisplayObject(object):
575 """An object that wraps data to be displayed."""
575 """An object that wraps data to be displayed."""
576
576
577 _read_flags = 'r'
577 _read_flags = 'r'
578 _show_mem_addr = False
578 _show_mem_addr = False
579
579
580 def __init__(self, data=None, url=None, filename=None):
580 def __init__(self, data=None, url=None, filename=None):
581 """Create a display object given raw data.
581 """Create a display object given raw data.
582
582
583 When this object is returned by an expression or passed to the
583 When this object is returned by an expression or passed to the
584 display function, it will result in the data being displayed
584 display function, it will result in the data being displayed
585 in the frontend. The MIME type of the data should match the
585 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'
586 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
587 data. If the data is a URL, the data will first be downloaded
588 and then displayed. If
588 and then displayed. If
589
589
590 Parameters
590 Parameters
591 ----------
591 ----------
592 data : unicode, str or bytes
592 data : unicode, str or bytes
593 The raw data or a URL or file to load the data from
593 The raw data or a URL or file to load the data from
594 url : unicode
594 url : unicode
595 A URL to download the data from.
595 A URL to download the data from.
596 filename : unicode
596 filename : unicode
597 Path to a local file to load the data from.
597 Path to a local file to load the data from.
598 """
598 """
599 if data is not None and isinstance(data, string_types):
599 if data is not None and isinstance(data, string_types):
600 if data.startswith('http') and url is None:
600 if data.startswith('http') and url is None:
601 url = data
601 url = data
602 filename = None
602 filename = None
603 data = None
603 data = None
604 elif _safe_exists(data) and filename is None:
604 elif _safe_exists(data) and filename is None:
605 url = None
605 url = None
606 filename = data
606 filename = data
607 data = None
607 data = None
608
608
609 self.data = data
609 self.data = data
610 self.url = url
610 self.url = url
611 self.filename = None if filename is None else unicode_type(filename)
611 self.filename = None if filename is None else unicode_type(filename)
612
612
613 self.reload()
613 self.reload()
614 self._check_data()
614 self._check_data()
615
615
616 def __repr__(self):
616 def __repr__(self):
617 if not self._show_mem_addr:
617 if not self._show_mem_addr:
618 cls = self.__class__
618 cls = self.__class__
619 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
619 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
620 else:
620 else:
621 r = super(DisplayObject, self).__repr__()
621 r = super(DisplayObject, self).__repr__()
622 return r
622 return r
623
623
624 def _check_data(self):
624 def _check_data(self):
625 """Override in subclasses if there's something to check."""
625 """Override in subclasses if there's something to check."""
626 pass
626 pass
627
627
628 def reload(self):
628 def reload(self):
629 """Reload the raw data from file or URL."""
629 """Reload the raw data from file or URL."""
630 if self.filename is not None:
630 if self.filename is not None:
631 with open(self.filename, self._read_flags) as f:
631 with open(self.filename, self._read_flags) as f:
632 self.data = f.read()
632 self.data = f.read()
633 elif self.url is not None:
633 elif self.url is not None:
634 try:
634 try:
635 try:
635 try:
636 from urllib.request import urlopen # Py3
636 from urllib.request import urlopen # Py3
637 except ImportError:
637 except ImportError:
638 from urllib2 import urlopen
638 from urllib2 import urlopen
639 response = urlopen(self.url)
639 response = urlopen(self.url)
640 self.data = response.read()
640 self.data = response.read()
641 # extract encoding from header, if there is one:
641 # extract encoding from header, if there is one:
642 encoding = None
642 encoding = None
643 for sub in response.headers['content-type'].split(';'):
643 for sub in response.headers['content-type'].split(';'):
644 sub = sub.strip()
644 sub = sub.strip()
645 if sub.startswith('charset'):
645 if sub.startswith('charset'):
646 encoding = sub.split('=')[-1].strip()
646 encoding = sub.split('=')[-1].strip()
647 break
647 break
648 # decode data, if an encoding was specified
648 # decode data, if an encoding was specified
649 if encoding:
649 if encoding:
650 self.data = self.data.decode(encoding, 'replace')
650 self.data = self.data.decode(encoding, 'replace')
651 except:
651 except:
652 self.data = None
652 self.data = None
653
653
654 class TextDisplayObject(DisplayObject):
654 class TextDisplayObject(DisplayObject):
655 """Validate that display data is text"""
655 """Validate that display data is text"""
656 def _check_data(self):
656 def _check_data(self):
657 if self.data is not None and not isinstance(self.data, string_types):
657 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))
658 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
659
659
660 class Pretty(TextDisplayObject):
660 class Pretty(TextDisplayObject):
661
661
662 def _repr_pretty_(self, pp, cycle):
662 def _repr_pretty_(self, pp, cycle):
663 return pp.text(self.data)
663 return pp.text(self.data)
664
664
665
665
666 class HTML(TextDisplayObject):
666 class HTML(TextDisplayObject):
667
667
668 def _repr_html_(self):
668 def _repr_html_(self):
669 return self.data
669 return self.data
670
670
671 def __html__(self):
671 def __html__(self):
672 """
672 """
673 This method exists to inform other HTML-using modules (e.g. Markupsafe,
673 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
674 htmltag, etc) that this object is HTML and does not need things like
675 special characters (<>&) escaped.
675 special characters (<>&) escaped.
676 """
676 """
677 return self._repr_html_()
677 return self._repr_html_()
678
678
679
679
680 class Markdown(TextDisplayObject):
680 class Markdown(TextDisplayObject):
681
681
682 def _repr_markdown_(self):
682 def _repr_markdown_(self):
683 return self.data
683 return self.data
684
684
685
685
686 class Math(TextDisplayObject):
686 class Math(TextDisplayObject):
687
687
688 def _repr_latex_(self):
688 def _repr_latex_(self):
689 s = self.data.strip('$')
689 s = self.data.strip('$')
690 return "$$%s$$" % s
690 return "$$%s$$" % s
691
691
692
692
693 class Latex(TextDisplayObject):
693 class Latex(TextDisplayObject):
694
694
695 def _repr_latex_(self):
695 def _repr_latex_(self):
696 return self.data
696 return self.data
697
697
698
698
699 class SVG(DisplayObject):
699 class SVG(DisplayObject):
700
700
701 _read_flags = 'rb'
701 _read_flags = 'rb'
702 # wrap data in a property, which extracts the <svg> tag, discarding
702 # wrap data in a property, which extracts the <svg> tag, discarding
703 # document headers
703 # document headers
704 _data = None
704 _data = None
705
705
706 @property
706 @property
707 def data(self):
707 def data(self):
708 return self._data
708 return self._data
709
709
710 @data.setter
710 @data.setter
711 def data(self, svg):
711 def data(self, svg):
712 if svg is None:
712 if svg is None:
713 self._data = None
713 self._data = None
714 return
714 return
715 # parse into dom object
715 # parse into dom object
716 from xml.dom import minidom
716 from xml.dom import minidom
717 svg = cast_bytes_py2(svg)
717 svg = cast_bytes_py2(svg)
718 x = minidom.parseString(svg)
718 x = minidom.parseString(svg)
719 # get svg tag (should be 1)
719 # get svg tag (should be 1)
720 found_svg = x.getElementsByTagName('svg')
720 found_svg = x.getElementsByTagName('svg')
721 if found_svg:
721 if found_svg:
722 svg = found_svg[0].toxml()
722 svg = found_svg[0].toxml()
723 else:
723 else:
724 # fallback on the input, trust the user
724 # fallback on the input, trust the user
725 # but this is probably an error.
725 # but this is probably an error.
726 pass
726 pass
727 svg = cast_unicode(svg)
727 svg = cast_unicode(svg)
728 self._data = svg
728 self._data = svg
729
729
730 def _repr_svg_(self):
730 def _repr_svg_(self):
731 return self.data
731 return self.data
732
732
733 class ProgressBar(DisplayObject):
733 class ProgressBar(DisplayObject):
734 """Progressbar supports displaying a progressbar like element
734 """Progressbar supports displaying a progressbar like element
735 """
735 """
736 def __init__(self, total):
736 def __init__(self, total):
737 """Creates a new progressbar
737 """Creates a new progressbar
738
738
739 Parameters
739 Parameters
740 ----------
740 ----------
741 total : int
741 total : int
742 maximum size of the progressbar
742 maximum size of the progressbar
743 """
743 """
744 self.total = total
744 self.total = total
745 self._progress = 0
745 self._progress = 0
746 self.html_width = '60ex'
746 self.html_width = '60ex'
747 self.text_width = 60
747 self.text_width = 60
748 self._display_id = hexlify(os.urandom(8)).decode('ascii')
748 self._display_id = hexlify(os.urandom(8)).decode('ascii')
749
749
750 def __repr__(self):
750 def __repr__(self):
751 fraction = self.progress / self.total
751 fraction = self.progress / self.total
752 filled = '=' * int(fraction * self.text_width)
752 filled = '=' * int(fraction * self.text_width)
753 rest = ' ' * (self.text_width - len(filled))
753 rest = ' ' * (self.text_width - len(filled))
754 return '[{}{}] {}/{}'.format(
754 return '[{}{}] {}/{}'.format(
755 filled, rest,
755 filled, rest,
756 self.progress, self.total,
756 self.progress, self.total,
757 )
757 )
758
758
759 def _repr_html_(self):
759 def _repr_html_(self):
760 return "<progress style='width:{}' max='{}' value='{}'></progress>".format(
760 return "<progress style='width:{}' max='{}' value='{}'></progress>".format(
761 self.html_width, self.total, self.progress)
761 self.html_width, self.total, self.progress)
762
762
763 def display(self):
763 def display(self):
764 display(self, display_id=self._display_id)
764 display(self, display_id=self._display_id)
765
765
766 def update(self):
766 def update(self):
767 display(self, display_id=self._display_id, update=True)
767 display(self, display_id=self._display_id, update=True)
768
768
769 @property
769 @property
770 def progress(self):
770 def progress(self):
771 return self._progress
771 return self._progress
772
772
773 @progress.setter
773 @progress.setter
774 def progress(self, value):
774 def progress(self, value):
775 self._progress = value
775 self._progress = value
776 self.update()
776 self.update()
777
777
778 def __iter__(self):
778 def __iter__(self):
779 self.display()
779 self.display()
780 self._progress = -1 # First iteration is 0
780 self._progress = -1 # First iteration is 0
781 return self
781 return self
782
782
783 def __next__(self):
783 def __next__(self):
784 """Returns current value and increments display by one."""
784 """Returns current value and increments display by one."""
785 self.progress += 1
785 self.progress += 1
786 if self.progress < self.total:
786 if self.progress < self.total:
787 return self.progress
787 return self.progress
788 else:
788 else:
789 raise StopIteration()
789 raise StopIteration()
790
791 def next(self):
792 """Python 2 compatibility"""
793 returun self.__next__()
790
794
791 class JSON(DisplayObject):
795 class JSON(DisplayObject):
792 """JSON expects a JSON-able dict or list
796 """JSON expects a JSON-able dict or list
793
797
794 not an already-serialized JSON string.
798 not an already-serialized JSON string.
795
799
796 Scalar types (None, number, string) are not allowed, only dict or list containers.
800 Scalar types (None, number, string) are not allowed, only dict or list containers.
797 """
801 """
798 # wrap data in a property, which warns about passing already-serialized JSON
802 # wrap data in a property, which warns about passing already-serialized JSON
799 _data = None
803 _data = None
800 def _check_data(self):
804 def _check_data(self):
801 if self.data is not None and not isinstance(self.data, (dict, list)):
805 if self.data is not None and not isinstance(self.data, (dict, list)):
802 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
806 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
803
807
804 @property
808 @property
805 def data(self):
809 def data(self):
806 return self._data
810 return self._data
807
811
808 @data.setter
812 @data.setter
809 def data(self, data):
813 def data(self, data):
810 if isinstance(data, string_types):
814 if isinstance(data, string_types):
811 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
815 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
812 data = json.loads(data)
816 data = json.loads(data)
813 self._data = data
817 self._data = data
814
818
815 def _repr_json_(self):
819 def _repr_json_(self):
816 return self.data
820 return self.data
817
821
818 css_t = """$("head").append($("<link/>").attr({
822 css_t = """$("head").append($("<link/>").attr({
819 rel: "stylesheet",
823 rel: "stylesheet",
820 type: "text/css",
824 type: "text/css",
821 href: "%s"
825 href: "%s"
822 }));
826 }));
823 """
827 """
824
828
825 lib_t1 = """$.getScript("%s", function () {
829 lib_t1 = """$.getScript("%s", function () {
826 """
830 """
827 lib_t2 = """});
831 lib_t2 = """});
828 """
832 """
829
833
830 class Javascript(TextDisplayObject):
834 class Javascript(TextDisplayObject):
831
835
832 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
836 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
833 """Create a Javascript display object given raw data.
837 """Create a Javascript display object given raw data.
834
838
835 When this object is returned by an expression or passed to the
839 When this object is returned by an expression or passed to the
836 display function, it will result in the data being displayed
840 display function, it will result in the data being displayed
837 in the frontend. If the data is a URL, the data will first be
841 in the frontend. If the data is a URL, the data will first be
838 downloaded and then displayed.
842 downloaded and then displayed.
839
843
840 In the Notebook, the containing element will be available as `element`,
844 In the Notebook, the containing element will be available as `element`,
841 and jQuery will be available. Content appended to `element` will be
845 and jQuery will be available. Content appended to `element` will be
842 visible in the output area.
846 visible in the output area.
843
847
844 Parameters
848 Parameters
845 ----------
849 ----------
846 data : unicode, str or bytes
850 data : unicode, str or bytes
847 The Javascript source code or a URL to download it from.
851 The Javascript source code or a URL to download it from.
848 url : unicode
852 url : unicode
849 A URL to download the data from.
853 A URL to download the data from.
850 filename : unicode
854 filename : unicode
851 Path to a local file to load the data from.
855 Path to a local file to load the data from.
852 lib : list or str
856 lib : list or str
853 A sequence of Javascript library URLs to load asynchronously before
857 A sequence of Javascript library URLs to load asynchronously before
854 running the source code. The full URLs of the libraries should
858 running the source code. The full URLs of the libraries should
855 be given. A single Javascript library URL can also be given as a
859 be given. A single Javascript library URL can also be given as a
856 string.
860 string.
857 css: : list or str
861 css: : list or str
858 A sequence of css files to load before running the source code.
862 A sequence of css files to load before running the source code.
859 The full URLs of the css files should be given. A single css URL
863 The full URLs of the css files should be given. A single css URL
860 can also be given as a string.
864 can also be given as a string.
861 """
865 """
862 if isinstance(lib, string_types):
866 if isinstance(lib, string_types):
863 lib = [lib]
867 lib = [lib]
864 elif lib is None:
868 elif lib is None:
865 lib = []
869 lib = []
866 if isinstance(css, string_types):
870 if isinstance(css, string_types):
867 css = [css]
871 css = [css]
868 elif css is None:
872 elif css is None:
869 css = []
873 css = []
870 if not isinstance(lib, (list,tuple)):
874 if not isinstance(lib, (list,tuple)):
871 raise TypeError('expected sequence, got: %r' % lib)
875 raise TypeError('expected sequence, got: %r' % lib)
872 if not isinstance(css, (list,tuple)):
876 if not isinstance(css, (list,tuple)):
873 raise TypeError('expected sequence, got: %r' % css)
877 raise TypeError('expected sequence, got: %r' % css)
874 self.lib = lib
878 self.lib = lib
875 self.css = css
879 self.css = css
876 super(Javascript, self).__init__(data=data, url=url, filename=filename)
880 super(Javascript, self).__init__(data=data, url=url, filename=filename)
877
881
878 def _repr_javascript_(self):
882 def _repr_javascript_(self):
879 r = ''
883 r = ''
880 for c in self.css:
884 for c in self.css:
881 r += css_t % c
885 r += css_t % c
882 for l in self.lib:
886 for l in self.lib:
883 r += lib_t1 % l
887 r += lib_t1 % l
884 r += self.data
888 r += self.data
885 r += lib_t2*len(self.lib)
889 r += lib_t2*len(self.lib)
886 return r
890 return r
887
891
888 # constants for identifying png/jpeg data
892 # constants for identifying png/jpeg data
889 _PNG = b'\x89PNG\r\n\x1a\n'
893 _PNG = b'\x89PNG\r\n\x1a\n'
890 _JPEG = b'\xff\xd8'
894 _JPEG = b'\xff\xd8'
891
895
892 def _pngxy(data):
896 def _pngxy(data):
893 """read the (width, height) from a PNG header"""
897 """read the (width, height) from a PNG header"""
894 ihdr = data.index(b'IHDR')
898 ihdr = data.index(b'IHDR')
895 # next 8 bytes are width/height
899 # next 8 bytes are width/height
896 w4h4 = data[ihdr+4:ihdr+12]
900 w4h4 = data[ihdr+4:ihdr+12]
897 return struct.unpack('>ii', w4h4)
901 return struct.unpack('>ii', w4h4)
898
902
899 def _jpegxy(data):
903 def _jpegxy(data):
900 """read the (width, height) from a JPEG header"""
904 """read the (width, height) from a JPEG header"""
901 # adapted from http://www.64lines.com/jpeg-width-height
905 # adapted from http://www.64lines.com/jpeg-width-height
902
906
903 idx = 4
907 idx = 4
904 while True:
908 while True:
905 block_size = struct.unpack('>H', data[idx:idx+2])[0]
909 block_size = struct.unpack('>H', data[idx:idx+2])[0]
906 idx = idx + block_size
910 idx = idx + block_size
907 if data[idx:idx+2] == b'\xFF\xC0':
911 if data[idx:idx+2] == b'\xFF\xC0':
908 # found Start of Frame
912 # found Start of Frame
909 iSOF = idx
913 iSOF = idx
910 break
914 break
911 else:
915 else:
912 # read another block
916 # read another block
913 idx += 2
917 idx += 2
914
918
915 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
919 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
916 return w, h
920 return w, h
917
921
918 class Image(DisplayObject):
922 class Image(DisplayObject):
919
923
920 _read_flags = 'rb'
924 _read_flags = 'rb'
921 _FMT_JPEG = u'jpeg'
925 _FMT_JPEG = u'jpeg'
922 _FMT_PNG = u'png'
926 _FMT_PNG = u'png'
923 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
927 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
924
928
925 def __init__(self, data=None, url=None, filename=None, format=None,
929 def __init__(self, data=None, url=None, filename=None, format=None,
926 embed=None, width=None, height=None, retina=False,
930 embed=None, width=None, height=None, retina=False,
927 unconfined=False, metadata=None):
931 unconfined=False, metadata=None):
928 """Create a PNG/JPEG image object given raw data.
932 """Create a PNG/JPEG image object given raw data.
929
933
930 When this object is returned by an input cell or passed to the
934 When this object is returned by an input cell or passed to the
931 display function, it will result in the image being displayed
935 display function, it will result in the image being displayed
932 in the frontend.
936 in the frontend.
933
937
934 Parameters
938 Parameters
935 ----------
939 ----------
936 data : unicode, str or bytes
940 data : unicode, str or bytes
937 The raw image data or a URL or filename to load the data from.
941 The raw image data or a URL or filename to load the data from.
938 This always results in embedded image data.
942 This always results in embedded image data.
939 url : unicode
943 url : unicode
940 A URL to download the data from. If you specify `url=`,
944 A URL to download the data from. If you specify `url=`,
941 the image data will not be embedded unless you also specify `embed=True`.
945 the image data will not be embedded unless you also specify `embed=True`.
942 filename : unicode
946 filename : unicode
943 Path to a local file to load the data from.
947 Path to a local file to load the data from.
944 Images from a file are always embedded.
948 Images from a file are always embedded.
945 format : unicode
949 format : unicode
946 The format of the image data (png/jpeg/jpg). If a filename or URL is given
950 The format of the image data (png/jpeg/jpg). If a filename or URL is given
947 for format will be inferred from the filename extension.
951 for format will be inferred from the filename extension.
948 embed : bool
952 embed : bool
949 Should the image data be embedded using a data URI (True) or be
953 Should the image data be embedded using a data URI (True) or be
950 loaded using an <img> tag. Set this to True if you want the image
954 loaded using an <img> tag. Set this to True if you want the image
951 to be viewable later with no internet connection in the notebook.
955 to be viewable later with no internet connection in the notebook.
952
956
953 Default is `True`, unless the keyword argument `url` is set, then
957 Default is `True`, unless the keyword argument `url` is set, then
954 default value is `False`.
958 default value is `False`.
955
959
956 Note that QtConsole is not able to display images if `embed` is set to `False`
960 Note that QtConsole is not able to display images if `embed` is set to `False`
957 width : int
961 width : int
958 Width in pixels to which to constrain the image in html
962 Width in pixels to which to constrain the image in html
959 height : int
963 height : int
960 Height in pixels to which to constrain the image in html
964 Height in pixels to which to constrain the image in html
961 retina : bool
965 retina : bool
962 Automatically set the width and height to half of the measured
966 Automatically set the width and height to half of the measured
963 width and height.
967 width and height.
964 This only works for embedded images because it reads the width/height
968 This only works for embedded images because it reads the width/height
965 from image data.
969 from image data.
966 For non-embedded images, you can just set the desired display width
970 For non-embedded images, you can just set the desired display width
967 and height directly.
971 and height directly.
968 unconfined: bool
972 unconfined: bool
969 Set unconfined=True to disable max-width confinement of the image.
973 Set unconfined=True to disable max-width confinement of the image.
970 metadata: dict
974 metadata: dict
971 Specify extra metadata to attach to the image.
975 Specify extra metadata to attach to the image.
972
976
973 Examples
977 Examples
974 --------
978 --------
975 # embedded image data, works in qtconsole and notebook
979 # embedded image data, works in qtconsole and notebook
976 # when passed positionally, the first arg can be any of raw image data,
980 # when passed positionally, the first arg can be any of raw image data,
977 # a URL, or a filename from which to load image data.
981 # a URL, or a filename from which to load image data.
978 # The result is always embedding image data for inline images.
982 # The result is always embedding image data for inline images.
979 Image('http://www.google.fr/images/srpr/logo3w.png')
983 Image('http://www.google.fr/images/srpr/logo3w.png')
980 Image('/path/to/image.jpg')
984 Image('/path/to/image.jpg')
981 Image(b'RAW_PNG_DATA...')
985 Image(b'RAW_PNG_DATA...')
982
986
983 # Specifying Image(url=...) does not embed the image data,
987 # Specifying Image(url=...) does not embed the image data,
984 # it only generates `<img>` tag with a link to the source.
988 # it only generates `<img>` tag with a link to the source.
985 # This will not work in the qtconsole or offline.
989 # This will not work in the qtconsole or offline.
986 Image(url='http://www.google.fr/images/srpr/logo3w.png')
990 Image(url='http://www.google.fr/images/srpr/logo3w.png')
987
991
988 """
992 """
989 if filename is not None:
993 if filename is not None:
990 ext = self._find_ext(filename)
994 ext = self._find_ext(filename)
991 elif url is not None:
995 elif url is not None:
992 ext = self._find_ext(url)
996 ext = self._find_ext(url)
993 elif data is None:
997 elif data is None:
994 raise ValueError("No image data found. Expecting filename, url, or data.")
998 raise ValueError("No image data found. Expecting filename, url, or data.")
995 elif isinstance(data, string_types) and (
999 elif isinstance(data, string_types) and (
996 data.startswith('http') or _safe_exists(data)
1000 data.startswith('http') or _safe_exists(data)
997 ):
1001 ):
998 ext = self._find_ext(data)
1002 ext = self._find_ext(data)
999 else:
1003 else:
1000 ext = None
1004 ext = None
1001
1005
1002 if format is None:
1006 if format is None:
1003 if ext is not None:
1007 if ext is not None:
1004 if ext == u'jpg' or ext == u'jpeg':
1008 if ext == u'jpg' or ext == u'jpeg':
1005 format = self._FMT_JPEG
1009 format = self._FMT_JPEG
1006 elif ext == u'png':
1010 elif ext == u'png':
1007 format = self._FMT_PNG
1011 format = self._FMT_PNG
1008 else:
1012 else:
1009 format = ext.lower()
1013 format = ext.lower()
1010 elif isinstance(data, bytes):
1014 elif isinstance(data, bytes):
1011 # infer image type from image data header,
1015 # infer image type from image data header,
1012 # only if format has not been specified.
1016 # only if format has not been specified.
1013 if data[:2] == _JPEG:
1017 if data[:2] == _JPEG:
1014 format = self._FMT_JPEG
1018 format = self._FMT_JPEG
1015
1019
1016 # failed to detect format, default png
1020 # failed to detect format, default png
1017 if format is None:
1021 if format is None:
1018 format = 'png'
1022 format = 'png'
1019
1023
1020 if format.lower() == 'jpg':
1024 if format.lower() == 'jpg':
1021 # jpg->jpeg
1025 # jpg->jpeg
1022 format = self._FMT_JPEG
1026 format = self._FMT_JPEG
1023
1027
1024 self.format = unicode_type(format).lower()
1028 self.format = unicode_type(format).lower()
1025 self.embed = embed if embed is not None else (url is None)
1029 self.embed = embed if embed is not None else (url is None)
1026
1030
1027 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
1031 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
1028 raise ValueError("Cannot embed the '%s' image format" % (self.format))
1032 raise ValueError("Cannot embed the '%s' image format" % (self.format))
1029 self.width = width
1033 self.width = width
1030 self.height = height
1034 self.height = height
1031 self.retina = retina
1035 self.retina = retina
1032 self.unconfined = unconfined
1036 self.unconfined = unconfined
1033 self.metadata = metadata
1037 self.metadata = metadata
1034 super(Image, self).__init__(data=data, url=url, filename=filename)
1038 super(Image, self).__init__(data=data, url=url, filename=filename)
1035
1039
1036 if retina:
1040 if retina:
1037 self._retina_shape()
1041 self._retina_shape()
1038
1042
1039 def _retina_shape(self):
1043 def _retina_shape(self):
1040 """load pixel-doubled width and height from image data"""
1044 """load pixel-doubled width and height from image data"""
1041 if not self.embed:
1045 if not self.embed:
1042 return
1046 return
1043 if self.format == 'png':
1047 if self.format == 'png':
1044 w, h = _pngxy(self.data)
1048 w, h = _pngxy(self.data)
1045 elif self.format == 'jpeg':
1049 elif self.format == 'jpeg':
1046 w, h = _jpegxy(self.data)
1050 w, h = _jpegxy(self.data)
1047 else:
1051 else:
1048 # retina only supports png
1052 # retina only supports png
1049 return
1053 return
1050 self.width = w // 2
1054 self.width = w // 2
1051 self.height = h // 2
1055 self.height = h // 2
1052
1056
1053 def reload(self):
1057 def reload(self):
1054 """Reload the raw data from file or URL."""
1058 """Reload the raw data from file or URL."""
1055 if self.embed:
1059 if self.embed:
1056 super(Image,self).reload()
1060 super(Image,self).reload()
1057 if self.retina:
1061 if self.retina:
1058 self._retina_shape()
1062 self._retina_shape()
1059
1063
1060 def _repr_html_(self):
1064 def _repr_html_(self):
1061 if not self.embed:
1065 if not self.embed:
1062 width = height = klass = ''
1066 width = height = klass = ''
1063 if self.width:
1067 if self.width:
1064 width = ' width="%d"' % self.width
1068 width = ' width="%d"' % self.width
1065 if self.height:
1069 if self.height:
1066 height = ' height="%d"' % self.height
1070 height = ' height="%d"' % self.height
1067 if self.unconfined:
1071 if self.unconfined:
1068 klass = ' class="unconfined"'
1072 klass = ' class="unconfined"'
1069 return u'<img src="{url}"{width}{height}{klass}/>'.format(
1073 return u'<img src="{url}"{width}{height}{klass}/>'.format(
1070 url=self.url,
1074 url=self.url,
1071 width=width,
1075 width=width,
1072 height=height,
1076 height=height,
1073 klass=klass,
1077 klass=klass,
1074 )
1078 )
1075
1079
1076 def _data_and_metadata(self):
1080 def _data_and_metadata(self):
1077 """shortcut for returning metadata with shape information, if defined"""
1081 """shortcut for returning metadata with shape information, if defined"""
1078 md = {}
1082 md = {}
1079 if self.width:
1083 if self.width:
1080 md['width'] = self.width
1084 md['width'] = self.width
1081 if self.height:
1085 if self.height:
1082 md['height'] = self.height
1086 md['height'] = self.height
1083 if self.unconfined:
1087 if self.unconfined:
1084 md['unconfined'] = self.unconfined
1088 md['unconfined'] = self.unconfined
1085 if self.metadata:
1089 if self.metadata:
1086 md.update(self.metadata)
1090 md.update(self.metadata)
1087 if md:
1091 if md:
1088 return self.data, md
1092 return self.data, md
1089 else:
1093 else:
1090 return self.data
1094 return self.data
1091
1095
1092 def _repr_png_(self):
1096 def _repr_png_(self):
1093 if self.embed and self.format == u'png':
1097 if self.embed and self.format == u'png':
1094 return self._data_and_metadata()
1098 return self._data_and_metadata()
1095
1099
1096 def _repr_jpeg_(self):
1100 def _repr_jpeg_(self):
1097 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
1101 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
1098 return self._data_and_metadata()
1102 return self._data_and_metadata()
1099
1103
1100 def _find_ext(self, s):
1104 def _find_ext(self, s):
1101 return unicode_type(s.split('.')[-1].lower())
1105 return unicode_type(s.split('.')[-1].lower())
1102
1106
1103 class Video(DisplayObject):
1107 class Video(DisplayObject):
1104
1108
1105 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
1109 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
1106 """Create a video object given raw data or an URL.
1110 """Create a video object given raw data or an URL.
1107
1111
1108 When this object is returned by an input cell or passed to the
1112 When this object is returned by an input cell or passed to the
1109 display function, it will result in the video being displayed
1113 display function, it will result in the video being displayed
1110 in the frontend.
1114 in the frontend.
1111
1115
1112 Parameters
1116 Parameters
1113 ----------
1117 ----------
1114 data : unicode, str or bytes
1118 data : unicode, str or bytes
1115 The raw video data or a URL or filename to load the data from.
1119 The raw video data or a URL or filename to load the data from.
1116 Raw data will require passing `embed=True`.
1120 Raw data will require passing `embed=True`.
1117 url : unicode
1121 url : unicode
1118 A URL for the video. If you specify `url=`,
1122 A URL for the video. If you specify `url=`,
1119 the image data will not be embedded.
1123 the image data will not be embedded.
1120 filename : unicode
1124 filename : unicode
1121 Path to a local file containing the video.
1125 Path to a local file containing the video.
1122 Will be interpreted as a local URL unless `embed=True`.
1126 Will be interpreted as a local URL unless `embed=True`.
1123 embed : bool
1127 embed : bool
1124 Should the video be embedded using a data URI (True) or be
1128 Should the video be embedded using a data URI (True) or be
1125 loaded using a <video> tag (False).
1129 loaded using a <video> tag (False).
1126
1130
1127 Since videos are large, embedding them should be avoided, if possible.
1131 Since videos are large, embedding them should be avoided, if possible.
1128 You must confirm embedding as your intention by passing `embed=True`.
1132 You must confirm embedding as your intention by passing `embed=True`.
1129
1133
1130 Local files can be displayed with URLs without embedding the content, via::
1134 Local files can be displayed with URLs without embedding the content, via::
1131
1135
1132 Video('./video.mp4')
1136 Video('./video.mp4')
1133
1137
1134 mimetype: unicode
1138 mimetype: unicode
1135 Specify the mimetype for embedded videos.
1139 Specify the mimetype for embedded videos.
1136 Default will be guessed from file extension, if available.
1140 Default will be guessed from file extension, if available.
1137
1141
1138 Examples
1142 Examples
1139 --------
1143 --------
1140
1144
1141 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
1145 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
1142 Video('path/to/video.mp4')
1146 Video('path/to/video.mp4')
1143 Video('path/to/video.mp4', embed=True)
1147 Video('path/to/video.mp4', embed=True)
1144 Video(b'raw-videodata', embed=True)
1148 Video(b'raw-videodata', embed=True)
1145 """
1149 """
1146 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
1150 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
1147 url = data
1151 url = data
1148 data = None
1152 data = None
1149 elif os.path.exists(data):
1153 elif os.path.exists(data):
1150 filename = data
1154 filename = data
1151 data = None
1155 data = None
1152
1156
1153 if data and not embed:
1157 if data and not embed:
1154 msg = ''.join([
1158 msg = ''.join([
1155 "To embed videos, you must pass embed=True ",
1159 "To embed videos, you must pass embed=True ",
1156 "(this may make your notebook files huge)\n",
1160 "(this may make your notebook files huge)\n",
1157 "Consider passing Video(url='...')",
1161 "Consider passing Video(url='...')",
1158 ])
1162 ])
1159 raise ValueError(msg)
1163 raise ValueError(msg)
1160
1164
1161 self.mimetype = mimetype
1165 self.mimetype = mimetype
1162 self.embed = embed
1166 self.embed = embed
1163 super(Video, self).__init__(data=data, url=url, filename=filename)
1167 super(Video, self).__init__(data=data, url=url, filename=filename)
1164
1168
1165 def _repr_html_(self):
1169 def _repr_html_(self):
1166 # External URLs and potentially local files are not embedded into the
1170 # External URLs and potentially local files are not embedded into the
1167 # notebook output.
1171 # notebook output.
1168 if not self.embed:
1172 if not self.embed:
1169 url = self.url if self.url is not None else self.filename
1173 url = self.url if self.url is not None else self.filename
1170 output = """<video src="{0}" controls>
1174 output = """<video src="{0}" controls>
1171 Your browser does not support the <code>video</code> element.
1175 Your browser does not support the <code>video</code> element.
1172 </video>""".format(url)
1176 </video>""".format(url)
1173 return output
1177 return output
1174
1178
1175 # Embedded videos are base64-encoded.
1179 # Embedded videos are base64-encoded.
1176 mimetype = self.mimetype
1180 mimetype = self.mimetype
1177 if self.filename is not None:
1181 if self.filename is not None:
1178 if not mimetype:
1182 if not mimetype:
1179 mimetype, _ = mimetypes.guess_type(self.filename)
1183 mimetype, _ = mimetypes.guess_type(self.filename)
1180
1184
1181 with open(self.filename, 'rb') as f:
1185 with open(self.filename, 'rb') as f:
1182 video = f.read()
1186 video = f.read()
1183 else:
1187 else:
1184 video = self.data
1188 video = self.data
1185 if isinstance(video, unicode_type):
1189 if isinstance(video, unicode_type):
1186 # unicode input is already b64-encoded
1190 # unicode input is already b64-encoded
1187 b64_video = video
1191 b64_video = video
1188 else:
1192 else:
1189 b64_video = base64_encode(video).decode('ascii').rstrip()
1193 b64_video = base64_encode(video).decode('ascii').rstrip()
1190
1194
1191 output = """<video controls>
1195 output = """<video controls>
1192 <source src="data:{0};base64,{1}" type="{0}">
1196 <source src="data:{0};base64,{1}" type="{0}">
1193 Your browser does not support the video tag.
1197 Your browser does not support the video tag.
1194 </video>""".format(mimetype, b64_video)
1198 </video>""".format(mimetype, b64_video)
1195 return output
1199 return output
1196
1200
1197 def reload(self):
1201 def reload(self):
1198 # TODO
1202 # TODO
1199 pass
1203 pass
1200
1204
1201 def _repr_png_(self):
1205 def _repr_png_(self):
1202 # TODO
1206 # TODO
1203 pass
1207 pass
1204 def _repr_jpeg_(self):
1208 def _repr_jpeg_(self):
1205 # TODO
1209 # TODO
1206 pass
1210 pass
1207
1211
1208 def clear_output(wait=False):
1212 def clear_output(wait=False):
1209 """Clear the output of the current cell receiving output.
1213 """Clear the output of the current cell receiving output.
1210
1214
1211 Parameters
1215 Parameters
1212 ----------
1216 ----------
1213 wait : bool [default: false]
1217 wait : bool [default: false]
1214 Wait to clear the output until new output is available to replace it."""
1218 Wait to clear the output until new output is available to replace it."""
1215 from IPython.core.interactiveshell import InteractiveShell
1219 from IPython.core.interactiveshell import InteractiveShell
1216 if InteractiveShell.initialized():
1220 if InteractiveShell.initialized():
1217 InteractiveShell.instance().display_pub.clear_output(wait)
1221 InteractiveShell.instance().display_pub.clear_output(wait)
1218 else:
1222 else:
1219 print('\033[2K\r', end='')
1223 print('\033[2K\r', end='')
1220 sys.stdout.flush()
1224 sys.stdout.flush()
1221 print('\033[2K\r', end='')
1225 print('\033[2K\r', end='')
1222 sys.stderr.flush()
1226 sys.stderr.flush()
1223
1227
1224
1228
1225 @skip_doctest
1229 @skip_doctest
1226 def set_matplotlib_formats(*formats, **kwargs):
1230 def set_matplotlib_formats(*formats, **kwargs):
1227 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1231 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1228
1232
1229 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1233 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1230
1234
1231 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1235 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1232
1236
1233 To set this in your config files use the following::
1237 To set this in your config files use the following::
1234
1238
1235 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1239 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1236 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1240 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1237
1241
1238 Parameters
1242 Parameters
1239 ----------
1243 ----------
1240 *formats : strs
1244 *formats : strs
1241 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1245 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1242 **kwargs :
1246 **kwargs :
1243 Keyword args will be relayed to ``figure.canvas.print_figure``.
1247 Keyword args will be relayed to ``figure.canvas.print_figure``.
1244 """
1248 """
1245 from IPython.core.interactiveshell import InteractiveShell
1249 from IPython.core.interactiveshell import InteractiveShell
1246 from IPython.core.pylabtools import select_figure_formats
1250 from IPython.core.pylabtools import select_figure_formats
1247 # build kwargs, starting with InlineBackend config
1251 # build kwargs, starting with InlineBackend config
1248 kw = {}
1252 kw = {}
1249 from ipykernel.pylab.config import InlineBackend
1253 from ipykernel.pylab.config import InlineBackend
1250 cfg = InlineBackend.instance()
1254 cfg = InlineBackend.instance()
1251 kw.update(cfg.print_figure_kwargs)
1255 kw.update(cfg.print_figure_kwargs)
1252 kw.update(**kwargs)
1256 kw.update(**kwargs)
1253 shell = InteractiveShell.instance()
1257 shell = InteractiveShell.instance()
1254 select_figure_formats(shell, formats, **kw)
1258 select_figure_formats(shell, formats, **kw)
1255
1259
1256 @skip_doctest
1260 @skip_doctest
1257 def set_matplotlib_close(close=True):
1261 def set_matplotlib_close(close=True):
1258 """Set whether the inline backend closes all figures automatically or not.
1262 """Set whether the inline backend closes all figures automatically or not.
1259
1263
1260 By default, the inline backend used in the IPython Notebook will close all
1264 By default, the inline backend used in the IPython Notebook will close all
1261 matplotlib figures automatically after each cell is run. This means that
1265 matplotlib figures automatically after each cell is run. This means that
1262 plots in different cells won't interfere. Sometimes, you may want to make
1266 plots in different cells won't interfere. Sometimes, you may want to make
1263 a plot in one cell and then refine it in later cells. This can be accomplished
1267 a plot in one cell and then refine it in later cells. This can be accomplished
1264 by::
1268 by::
1265
1269
1266 In [1]: set_matplotlib_close(False)
1270 In [1]: set_matplotlib_close(False)
1267
1271
1268 To set this in your config files use the following::
1272 To set this in your config files use the following::
1269
1273
1270 c.InlineBackend.close_figures = False
1274 c.InlineBackend.close_figures = False
1271
1275
1272 Parameters
1276 Parameters
1273 ----------
1277 ----------
1274 close : bool
1278 close : bool
1275 Should all matplotlib figures be automatically closed after each cell is
1279 Should all matplotlib figures be automatically closed after each cell is
1276 run?
1280 run?
1277 """
1281 """
1278 from ipykernel.pylab.config import InlineBackend
1282 from ipykernel.pylab.config import InlineBackend
1279 cfg = InlineBackend.instance()
1283 cfg = InlineBackend.instance()
1280 cfg.close_figures = close
1284 cfg.close_figures = close
1281
1285
General Comments 0
You need to be logged in to leave comments. Login now