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