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