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