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