##// END OF EJS Templates
add metadata to display functions...
MinRK -
Show More
@@ -1,591 +1,614 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 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2013 The IPython Development Team
10 # Copyright (C) 2013 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 import os
22 import os
23
23
24 from IPython.utils.py3compat import string_types
24 from IPython.utils.py3compat import string_types
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # utility functions
27 # utility functions
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 def _safe_exists(path):
30 def _safe_exists(path):
31 """Check path, but don't let exceptions raise"""
31 """Check path, but don't let exceptions raise"""
32 try:
32 try:
33 return os.path.exists(path)
33 return os.path.exists(path)
34 except Exception:
34 except Exception:
35 return False
35 return False
36
36
37 def _publish(data, metadata):
38 """publish a display message"""
39 from IPython.core.interactiveshell import InteractiveShell
40 return InteractiveShell.instance().display_pub.publish(
41 "display", data, metadata
42 )
43
44 def _merge(d1, d2):
45 """Like update, but merges sub-dicts instead of clobbering at the top level.
46
47 Updates d1 in-place
48 """
49
50 if not isinstance(d2, dict) or not isinstance(d1, dict):
51 return d2
52 for key, value in d2.items():
53 d1[key] = _merge(d1.get(key), value)
54 return d1
55
37 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
38 # Main functions
57 # Main functions
39 #-----------------------------------------------------------------------------
58 #-----------------------------------------------------------------------------
40
59
41 def display(*objs, **kwargs):
60 def display(*objs, **kwargs):
42 """Display a Python object in all frontends.
61 """Display a Python object in all frontends.
43
62
44 By default all representations will be computed and sent to the frontends.
63 By default all representations will be computed and sent to the frontends.
45 Frontends can decide which representation is used and how.
64 Frontends can decide which representation is used and how.
46
65
47 Parameters
66 Parameters
48 ----------
67 ----------
49 objs : tuple of objects
68 objs : tuple of objects
50 The Python objects to display.
69 The Python objects to display.
51 include : list or tuple, optional
70 include : list or tuple, optional
52 A list of format type strings (MIME types) to include in the
71 A list of format type strings (MIME types) to include in the
53 format data dict. If this is set *only* the format types included
72 format data dict. If this is set *only* the format types included
54 in this list will be computed.
73 in this list will be computed.
55 exclude : list or tuple, optional
74 exclude : list or tuple, optional
56 A list of format type strings (MIME types) to exclude in the format
75 A list of format type strings (MIME types) to exclude in the format
57 data dict. If this is set all format types will be computed,
76 data dict. If this is set all format types will be computed,
58 except for those included in this argument.
77 except for those included in this argument.
78 metadata : dict, optional
79 A dictionary of metadata to associate with the output.
80 mime-type keys in this dictionary will be associated with the individual
81 representation formats, if they exist.
59 """
82 """
60 include = kwargs.get('include')
83 include = kwargs.get('include')
61 exclude = kwargs.get('exclude')
84 exclude = kwargs.get('exclude')
85 metadata = kwargs.get('metadata')
62
86
63 from IPython.core.interactiveshell import InteractiveShell
87 from IPython.core.interactiveshell import InteractiveShell
64 inst = InteractiveShell.instance()
88 format = InteractiveShell.instance().display_formatter.format
65 format = inst.display_formatter.format
66 publish = inst.display_pub.publish
67
89
68 for obj in objs:
90 for obj in objs:
69 format_dict, md_dict = format(obj, include=include, exclude=exclude)
91 format_dict, md_dict = format(obj, include=include, exclude=exclude)
70 publish('IPython.core.display.display', format_dict, md_dict)
92 if metadata:
71
93 # kwarg-specified metadata gets precedence
94 _merge(md_dict, metadata)
95 _publish(format_dict, md_dict)
72
96
73 def display_pretty(*objs, **kwargs):
97 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
74 """Display the pretty (default) representation of an object.
98 """internal implementation of all display_foo methods
75
99
76 Parameters
100 Parameters
77 ----------
101 ----------
102 mimetype : str
103 The mimetype to be published (e.g. 'image/png')
78 objs : tuple of objects
104 objs : tuple of objects
79 The Python objects to display, or if raw=True raw text data to
105 The Python objects to display, or if raw=True raw text data to
80 display.
106 display.
81 raw : bool
107 raw : bool
82 Are the data objects raw data or Python objects that need to be
108 Are the data objects raw data or Python objects that need to be
83 formatted before display? [default: False]
109 formatted before display? [default: False]
110 metadata : dict (optional)
111 Metadata to be associated with the output.
84 """
112 """
85 raw = kwargs.pop('raw',False)
86 if raw:
113 if raw:
87 for obj in objs:
114 for obj in objs:
88 publish_pretty(obj)
115 _publish({mimetype : obj}, metadata)
89 else:
116 else:
90 display(*objs, include=['text/plain'])
117 display(*objs, metadata=metadata, include=[mimetype])
118
119
120 def display_pretty(*objs, **kwargs):
121 """Display the pretty (default) representation of an object.
122
123 Parameters
124 ----------
125 objs : tuple of objects
126 The Python objects to display, or if raw=True raw text data to
127 display.
128 raw : bool
129 Are the data objects raw data or Python objects that need to be
130 formatted before display? [default: False]
131 metadata : dict (optional)
132 Metadata to be associated with the output.
133 """
134 _display_mimetype('text/plain', objs, **kwargs)
91
135
92
136
93 def display_html(*objs, **kwargs):
137 def display_html(*objs, **kwargs):
94 """Display the HTML representation of an object.
138 """Display the HTML representation of an object.
95
139
96 Parameters
140 Parameters
97 ----------
141 ----------
98 objs : tuple of objects
142 objs : tuple of objects
99 The Python objects to display, or if raw=True raw HTML data to
143 The Python objects to display, or if raw=True raw HTML data to
100 display.
144 display.
101 raw : bool
145 raw : bool
102 Are the data objects raw data or Python objects that need to be
146 Are the data objects raw data or Python objects that need to be
103 formatted before display? [default: False]
147 formatted before display? [default: False]
148 metadata : dict (optional)
149 Metadata to be associated with the output.
104 """
150 """
105 raw = kwargs.pop('raw',False)
151 _display_mimetype('text/html', objs, **kwargs)
106 if raw:
107 for obj in objs:
108 publish_html(obj)
109 else:
110 display(*objs, include=['text/plain','text/html'])
111
152
112
153
113 def display_svg(*objs, **kwargs):
154 def display_svg(*objs, **kwargs):
114 """Display the SVG representation of an object.
155 """Display the SVG representation of an object.
115
156
116 Parameters
157 Parameters
117 ----------
158 ----------
118 objs : tuple of objects
159 objs : tuple of objects
119 The Python objects to display, or if raw=True raw svg data to
160 The Python objects to display, or if raw=True raw svg data to
120 display.
161 display.
121 raw : bool
162 raw : bool
122 Are the data objects raw data or Python objects that need to be
163 Are the data objects raw data or Python objects that need to be
123 formatted before display? [default: False]
164 formatted before display? [default: False]
165 metadata : dict (optional)
166 Metadata to be associated with the output.
124 """
167 """
125 raw = kwargs.pop('raw',False)
168 _display_mimetype('image/svg+xml', objs, **kwargs)
126 if raw:
127 for obj in objs:
128 publish_svg(obj)
129 else:
130 display(*objs, include=['text/plain','image/svg+xml'])
131
169
132
170
133 def display_png(*objs, **kwargs):
171 def display_png(*objs, **kwargs):
134 """Display the PNG representation of an object.
172 """Display the PNG representation of an object.
135
173
136 Parameters
174 Parameters
137 ----------
175 ----------
138 objs : tuple of objects
176 objs : tuple of objects
139 The Python objects to display, or if raw=True raw png data to
177 The Python objects to display, or if raw=True raw png data to
140 display.
178 display.
141 raw : bool
179 raw : bool
142 Are the data objects raw data or Python objects that need to be
180 Are the data objects raw data or Python objects that need to be
143 formatted before display? [default: False]
181 formatted before display? [default: False]
182 metadata : dict (optional)
183 Metadata to be associated with the output.
144 """
184 """
145 raw = kwargs.pop('raw',False)
185 _display_mimetype('image/png', objs, **kwargs)
146 if raw:
147 for obj in objs:
148 publish_png(obj)
149 else:
150 display(*objs, include=['text/plain','image/png'])
151
186
152
187
153 def display_jpeg(*objs, **kwargs):
188 def display_jpeg(*objs, **kwargs):
154 """Display the JPEG representation of an object.
189 """Display the JPEG representation of an object.
155
190
156 Parameters
191 Parameters
157 ----------
192 ----------
158 objs : tuple of objects
193 objs : tuple of objects
159 The Python objects to display, or if raw=True raw JPEG data to
194 The Python objects to display, or if raw=True raw JPEG data to
160 display.
195 display.
161 raw : bool
196 raw : bool
162 Are the data objects raw data or Python objects that need to be
197 Are the data objects raw data or Python objects that need to be
163 formatted before display? [default: False]
198 formatted before display? [default: False]
199 metadata : dict (optional)
200 Metadata to be associated with the output.
164 """
201 """
165 raw = kwargs.pop('raw',False)
202 _display_mimetype('image/jpeg', objs, **kwargs)
166 if raw:
167 for obj in objs:
168 publish_jpeg(obj)
169 else:
170 display(*objs, include=['text/plain','image/jpeg'])
171
203
172
204
173 def display_latex(*objs, **kwargs):
205 def display_latex(*objs, **kwargs):
174 """Display the LaTeX representation of an object.
206 """Display the LaTeX representation of an object.
175
207
176 Parameters
208 Parameters
177 ----------
209 ----------
178 objs : tuple of objects
210 objs : tuple of objects
179 The Python objects to display, or if raw=True raw latex data to
211 The Python objects to display, or if raw=True raw latex data to
180 display.
212 display.
181 raw : bool
213 raw : bool
182 Are the data objects raw data or Python objects that need to be
214 Are the data objects raw data or Python objects that need to be
183 formatted before display? [default: False]
215 formatted before display? [default: False]
216 metadata : dict (optional)
217 Metadata to be associated with the output.
184 """
218 """
185 raw = kwargs.pop('raw',False)
219 _display_mimetype('text/latex', objs, **kwargs)
186 if raw:
187 for obj in objs:
188 publish_latex(obj)
189 else:
190 display(*objs, include=['text/plain','text/latex'])
191
220
192
221
193 def display_json(*objs, **kwargs):
222 def display_json(*objs, **kwargs):
194 """Display the JSON representation of an object.
223 """Display the JSON representation of an object.
195
224
196 Note that not many frontends support displaying JSON.
225 Note that not many frontends support displaying JSON.
197
226
198 Parameters
227 Parameters
199 ----------
228 ----------
200 objs : tuple of objects
229 objs : tuple of objects
201 The Python objects to display, or if raw=True raw json data to
230 The Python objects to display, or if raw=True raw json data to
202 display.
231 display.
203 raw : bool
232 raw : bool
204 Are the data objects raw data or Python objects that need to be
233 Are the data objects raw data or Python objects that need to be
205 formatted before display? [default: False]
234 formatted before display? [default: False]
235 metadata : dict (optional)
236 Metadata to be associated with the output.
206 """
237 """
207 raw = kwargs.pop('raw',False)
238 _display_mimetype('application/json', objs, **kwargs)
208 if raw:
209 for obj in objs:
210 publish_json(obj)
211 else:
212 display(*objs, include=['text/plain','application/json'])
213
239
214
240
215 def display_javascript(*objs, **kwargs):
241 def display_javascript(*objs, **kwargs):
216 """Display the Javascript representation of an object.
242 """Display the Javascript representation of an object.
217
243
218 Parameters
244 Parameters
219 ----------
245 ----------
220 objs : tuple of objects
246 objs : tuple of objects
221 The Python objects to display, or if raw=True raw javascript data to
247 The Python objects to display, or if raw=True raw javascript data to
222 display.
248 display.
223 raw : bool
249 raw : bool
224 Are the data objects raw data or Python objects that need to be
250 Are the data objects raw data or Python objects that need to be
225 formatted before display? [default: False]
251 formatted before display? [default: False]
252 metadata : dict (optional)
253 Metadata to be associated with the output.
226 """
254 """
227 raw = kwargs.pop('raw',False)
255 _display_mimetype('application/javascript', objs, **kwargs)
228 if raw:
229 for obj in objs:
230 publish_javascript(obj)
231 else:
232 display(*objs, include=['text/plain','application/javascript'])
233
256
234 #-----------------------------------------------------------------------------
257 #-----------------------------------------------------------------------------
235 # Smart classes
258 # Smart classes
236 #-----------------------------------------------------------------------------
259 #-----------------------------------------------------------------------------
237
260
238
261
239 class DisplayObject(object):
262 class DisplayObject(object):
240 """An object that wraps data to be displayed."""
263 """An object that wraps data to be displayed."""
241
264
242 _read_flags = 'r'
265 _read_flags = 'r'
243
266
244 def __init__(self, data=None, url=None, filename=None):
267 def __init__(self, data=None, url=None, filename=None):
245 """Create a display object given raw data.
268 """Create a display object given raw data.
246
269
247 When this object is returned by an expression or passed to the
270 When this object is returned by an expression or passed to the
248 display function, it will result in the data being displayed
271 display function, it will result in the data being displayed
249 in the frontend. The MIME type of the data should match the
272 in the frontend. The MIME type of the data should match the
250 subclasses used, so the Png subclass should be used for 'image/png'
273 subclasses used, so the Png subclass should be used for 'image/png'
251 data. If the data is a URL, the data will first be downloaded
274 data. If the data is a URL, the data will first be downloaded
252 and then displayed. If
275 and then displayed. If
253
276
254 Parameters
277 Parameters
255 ----------
278 ----------
256 data : unicode, str or bytes
279 data : unicode, str or bytes
257 The raw data or a URL or file to load the data from
280 The raw data or a URL or file to load the data from
258 url : unicode
281 url : unicode
259 A URL to download the data from.
282 A URL to download the data from.
260 filename : unicode
283 filename : unicode
261 Path to a local file to load the data from.
284 Path to a local file to load the data from.
262 """
285 """
263 if data is not None and isinstance(data, string_types):
286 if data is not None and isinstance(data, string_types):
264 if data.startswith('http') and url is None:
287 if data.startswith('http') and url is None:
265 url = data
288 url = data
266 filename = None
289 filename = None
267 data = None
290 data = None
268 elif _safe_exists(data) and filename is None:
291 elif _safe_exists(data) and filename is None:
269 url = None
292 url = None
270 filename = data
293 filename = data
271 data = None
294 data = None
272
295
273 self.data = data
296 self.data = data
274 self.url = url
297 self.url = url
275 self.filename = None if filename is None else unicode(filename)
298 self.filename = None if filename is None else unicode(filename)
276
299
277 self.reload()
300 self.reload()
278
301
279 def reload(self):
302 def reload(self):
280 """Reload the raw data from file or URL."""
303 """Reload the raw data from file or URL."""
281 if self.filename is not None:
304 if self.filename is not None:
282 with open(self.filename, self._read_flags) as f:
305 with open(self.filename, self._read_flags) as f:
283 self.data = f.read()
306 self.data = f.read()
284 elif self.url is not None:
307 elif self.url is not None:
285 try:
308 try:
286 import urllib2
309 import urllib2
287 response = urllib2.urlopen(self.url)
310 response = urllib2.urlopen(self.url)
288 self.data = response.read()
311 self.data = response.read()
289 # extract encoding from header, if there is one:
312 # extract encoding from header, if there is one:
290 encoding = None
313 encoding = None
291 for sub in response.headers['content-type'].split(';'):
314 for sub in response.headers['content-type'].split(';'):
292 sub = sub.strip()
315 sub = sub.strip()
293 if sub.startswith('charset'):
316 if sub.startswith('charset'):
294 encoding = sub.split('=')[-1].strip()
317 encoding = sub.split('=')[-1].strip()
295 break
318 break
296 # decode data, if an encoding was specified
319 # decode data, if an encoding was specified
297 if encoding:
320 if encoding:
298 self.data = self.data.decode(encoding, 'replace')
321 self.data = self.data.decode(encoding, 'replace')
299 except:
322 except:
300 self.data = None
323 self.data = None
301
324
302 class Pretty(DisplayObject):
325 class Pretty(DisplayObject):
303
326
304 def _repr_pretty_(self):
327 def _repr_pretty_(self):
305 return self.data
328 return self.data
306
329
307
330
308 class HTML(DisplayObject):
331 class HTML(DisplayObject):
309
332
310 def _repr_html_(self):
333 def _repr_html_(self):
311 return self.data
334 return self.data
312
335
313
336
314 class Math(DisplayObject):
337 class Math(DisplayObject):
315
338
316 def _repr_latex_(self):
339 def _repr_latex_(self):
317 s = self.data.strip('$')
340 s = self.data.strip('$')
318 return "$$%s$$" % s
341 return "$$%s$$" % s
319
342
320
343
321 class Latex(DisplayObject):
344 class Latex(DisplayObject):
322
345
323 def _repr_latex_(self):
346 def _repr_latex_(self):
324 return self.data
347 return self.data
325
348
326
349
327 class SVG(DisplayObject):
350 class SVG(DisplayObject):
328
351
329 # wrap data in a property, which extracts the <svg> tag, discarding
352 # wrap data in a property, which extracts the <svg> tag, discarding
330 # document headers
353 # document headers
331 _data = None
354 _data = None
332
355
333 @property
356 @property
334 def data(self):
357 def data(self):
335 return self._data
358 return self._data
336
359
337 @data.setter
360 @data.setter
338 def data(self, svg):
361 def data(self, svg):
339 if svg is None:
362 if svg is None:
340 self._data = None
363 self._data = None
341 return
364 return
342 # parse into dom object
365 # parse into dom object
343 from xml.dom import minidom
366 from xml.dom import minidom
344 x = minidom.parseString(svg)
367 x = minidom.parseString(svg)
345 # get svg tag (should be 1)
368 # get svg tag (should be 1)
346 found_svg = x.getElementsByTagName('svg')
369 found_svg = x.getElementsByTagName('svg')
347 if found_svg:
370 if found_svg:
348 svg = found_svg[0].toxml()
371 svg = found_svg[0].toxml()
349 else:
372 else:
350 # fallback on the input, trust the user
373 # fallback on the input, trust the user
351 # but this is probably an error.
374 # but this is probably an error.
352 pass
375 pass
353 self._data = svg
376 self._data = svg
354
377
355 def _repr_svg_(self):
378 def _repr_svg_(self):
356 return self.data
379 return self.data
357
380
358
381
359 class JSON(DisplayObject):
382 class JSON(DisplayObject):
360
383
361 def _repr_json_(self):
384 def _repr_json_(self):
362 return self.data
385 return self.data
363
386
364 css_t = """$("head").append($("<link/>").attr({
387 css_t = """$("head").append($("<link/>").attr({
365 rel: "stylesheet",
388 rel: "stylesheet",
366 type: "text/css",
389 type: "text/css",
367 href: "%s"
390 href: "%s"
368 }));
391 }));
369 """
392 """
370
393
371 lib_t1 = """$.getScript("%s", function () {
394 lib_t1 = """$.getScript("%s", function () {
372 """
395 """
373 lib_t2 = """});
396 lib_t2 = """});
374 """
397 """
375
398
376 class Javascript(DisplayObject):
399 class Javascript(DisplayObject):
377
400
378 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
401 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
379 """Create a Javascript display object given raw data.
402 """Create a Javascript display object given raw data.
380
403
381 When this object is returned by an expression or passed to the
404 When this object is returned by an expression or passed to the
382 display function, it will result in the data being displayed
405 display function, it will result in the data being displayed
383 in the frontend. If the data is a URL, the data will first be
406 in the frontend. If the data is a URL, the data will first be
384 downloaded and then displayed.
407 downloaded and then displayed.
385
408
386 In the Notebook, the containing element will be available as `element`,
409 In the Notebook, the containing element will be available as `element`,
387 and jQuery will be available. The output area starts hidden, so if
410 and jQuery will be available. The output area starts hidden, so if
388 the js appends content to `element` that should be visible, then
411 the js appends content to `element` that should be visible, then
389 it must call `container.show()` to unhide the area.
412 it must call `container.show()` to unhide the area.
390
413
391 Parameters
414 Parameters
392 ----------
415 ----------
393 data : unicode, str or bytes
416 data : unicode, str or bytes
394 The Javascript source code or a URL to download it from.
417 The Javascript source code or a URL to download it from.
395 url : unicode
418 url : unicode
396 A URL to download the data from.
419 A URL to download the data from.
397 filename : unicode
420 filename : unicode
398 Path to a local file to load the data from.
421 Path to a local file to load the data from.
399 lib : list or str
422 lib : list or str
400 A sequence of Javascript library URLs to load asynchronously before
423 A sequence of Javascript library URLs to load asynchronously before
401 running the source code. The full URLs of the libraries should
424 running the source code. The full URLs of the libraries should
402 be given. A single Javascript library URL can also be given as a
425 be given. A single Javascript library URL can also be given as a
403 string.
426 string.
404 css: : list or str
427 css: : list or str
405 A sequence of css files to load before running the source code.
428 A sequence of css files to load before running the source code.
406 The full URLs of the css files should be given. A single css URL
429 The full URLs of the css files should be given. A single css URL
407 can also be given as a string.
430 can also be given as a string.
408 """
431 """
409 if isinstance(lib, basestring):
432 if isinstance(lib, basestring):
410 lib = [lib]
433 lib = [lib]
411 elif lib is None:
434 elif lib is None:
412 lib = []
435 lib = []
413 if isinstance(css, basestring):
436 if isinstance(css, basestring):
414 css = [css]
437 css = [css]
415 elif css is None:
438 elif css is None:
416 css = []
439 css = []
417 if not isinstance(lib, (list,tuple)):
440 if not isinstance(lib, (list,tuple)):
418 raise TypeError('expected sequence, got: %r' % lib)
441 raise TypeError('expected sequence, got: %r' % lib)
419 if not isinstance(css, (list,tuple)):
442 if not isinstance(css, (list,tuple)):
420 raise TypeError('expected sequence, got: %r' % css)
443 raise TypeError('expected sequence, got: %r' % css)
421 self.lib = lib
444 self.lib = lib
422 self.css = css
445 self.css = css
423 super(Javascript, self).__init__(data=data, url=url, filename=filename)
446 super(Javascript, self).__init__(data=data, url=url, filename=filename)
424
447
425 def _repr_javascript_(self):
448 def _repr_javascript_(self):
426 r = ''
449 r = ''
427 for c in self.css:
450 for c in self.css:
428 r += css_t % c
451 r += css_t % c
429 for l in self.lib:
452 for l in self.lib:
430 r += lib_t1 % l
453 r += lib_t1 % l
431 r += self.data
454 r += self.data
432 r += lib_t2*len(self.lib)
455 r += lib_t2*len(self.lib)
433 return r
456 return r
434
457
435 # constants for identifying png/jpeg data
458 # constants for identifying png/jpeg data
436 _PNG = b'\x89PNG\r\n\x1a\n'
459 _PNG = b'\x89PNG\r\n\x1a\n'
437 _JPEG = b'\xff\xd8'
460 _JPEG = b'\xff\xd8'
438
461
439 class Image(DisplayObject):
462 class Image(DisplayObject):
440
463
441 _read_flags = 'rb'
464 _read_flags = 'rb'
442 _FMT_JPEG = u'jpeg'
465 _FMT_JPEG = u'jpeg'
443 _FMT_PNG = u'png'
466 _FMT_PNG = u'png'
444 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
467 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
445
468
446 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None):
469 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None):
447 """Create a display an PNG/JPEG image given raw data.
470 """Create a display an PNG/JPEG image given raw data.
448
471
449 When this object is returned by an expression or passed to the
472 When this object is returned by an expression or passed to the
450 display function, it will result in the image being displayed
473 display function, it will result in the image being displayed
451 in the frontend.
474 in the frontend.
452
475
453 Parameters
476 Parameters
454 ----------
477 ----------
455 data : unicode, str or bytes
478 data : unicode, str or bytes
456 The raw data or a URL to download the data from.
479 The raw data or a URL to download the data from.
457 url : unicode
480 url : unicode
458 A URL to download the data from.
481 A URL to download the data from.
459 filename : unicode
482 filename : unicode
460 Path to a local file to load the data from.
483 Path to a local file to load the data from.
461 format : unicode
484 format : unicode
462 The format of the image data (png/jpeg/jpg). If a filename or URL is given
485 The format of the image data (png/jpeg/jpg). If a filename or URL is given
463 for format will be inferred from the filename extension.
486 for format will be inferred from the filename extension.
464 embed : bool
487 embed : bool
465 Should the image data be embedded using a data URI (True) or be
488 Should the image data be embedded using a data URI (True) or be
466 loaded using an <img> tag. Set this to True if you want the image
489 loaded using an <img> tag. Set this to True if you want the image
467 to be viewable later with no internet connection in the notebook.
490 to be viewable later with no internet connection in the notebook.
468
491
469 Default is `True`, unless the keyword argument `url` is set, then
492 Default is `True`, unless the keyword argument `url` is set, then
470 default value is `False`.
493 default value is `False`.
471
494
472 Note that QtConsole is not able to display images if `embed` is set to `False`
495 Note that QtConsole is not able to display images if `embed` is set to `False`
473 width : int
496 width : int
474 Width to which to constrain the image in html
497 Width to which to constrain the image in html
475 height : int
498 height : int
476 Height to which to constrain the image in html
499 Height to which to constrain the image in html
477
500
478 Examples
501 Examples
479 --------
502 --------
480 # embed implicitly True, works in qtconsole and notebook
503 # embed implicitly True, works in qtconsole and notebook
481 Image('http://www.google.fr/images/srpr/logo3w.png')
504 Image('http://www.google.fr/images/srpr/logo3w.png')
482
505
483 # embed implicitly False, does not works in qtconsole but works in notebook if
506 # embed implicitly False, does not works in qtconsole but works in notebook if
484 # internet connection available
507 # internet connection available
485 Image(url='http://www.google.fr/images/srpr/logo3w.png')
508 Image(url='http://www.google.fr/images/srpr/logo3w.png')
486
509
487 """
510 """
488 if filename is not None:
511 if filename is not None:
489 ext = self._find_ext(filename)
512 ext = self._find_ext(filename)
490 elif url is not None:
513 elif url is not None:
491 ext = self._find_ext(url)
514 ext = self._find_ext(url)
492 elif data is None:
515 elif data is None:
493 raise ValueError("No image data found. Expecting filename, url, or data.")
516 raise ValueError("No image data found. Expecting filename, url, or data.")
494 elif isinstance(data, string_types) and (
517 elif isinstance(data, string_types) and (
495 data.startswith('http') or _safe_exists(data)
518 data.startswith('http') or _safe_exists(data)
496 ):
519 ):
497 ext = self._find_ext(data)
520 ext = self._find_ext(data)
498 else:
521 else:
499 ext = None
522 ext = None
500
523
501 if ext is not None:
524 if ext is not None:
502 format = ext.lower()
525 format = ext.lower()
503 if ext == u'jpg' or ext == u'jpeg':
526 if ext == u'jpg' or ext == u'jpeg':
504 format = self._FMT_JPEG
527 format = self._FMT_JPEG
505 if ext == u'png':
528 if ext == u'png':
506 format = self._FMT_PNG
529 format = self._FMT_PNG
507 elif isinstance(data, bytes) and format == 'png':
530 elif isinstance(data, bytes) and format == 'png':
508 # infer image type from image data header,
531 # infer image type from image data header,
509 # only if format might not have been specified.
532 # only if format might not have been specified.
510 if data[:2] == _JPEG:
533 if data[:2] == _JPEG:
511 format = 'jpeg'
534 format = 'jpeg'
512
535
513 self.format = unicode(format).lower()
536 self.format = unicode(format).lower()
514 self.embed = embed if embed is not None else (url is None)
537 self.embed = embed if embed is not None else (url is None)
515
538
516 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
539 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
517 raise ValueError("Cannot embed the '%s' image format" % (self.format))
540 raise ValueError("Cannot embed the '%s' image format" % (self.format))
518 self.width = width
541 self.width = width
519 self.height = height
542 self.height = height
520 super(Image, self).__init__(data=data, url=url, filename=filename)
543 super(Image, self).__init__(data=data, url=url, filename=filename)
521
544
522 def reload(self):
545 def reload(self):
523 """Reload the raw data from file or URL."""
546 """Reload the raw data from file or URL."""
524 if self.embed:
547 if self.embed:
525 super(Image,self).reload()
548 super(Image,self).reload()
526
549
527 def _repr_html_(self):
550 def _repr_html_(self):
528 if not self.embed:
551 if not self.embed:
529 width = height = ''
552 width = height = ''
530 if self.width:
553 if self.width:
531 width = ' width="%d"' % self.width
554 width = ' width="%d"' % self.width
532 if self.height:
555 if self.height:
533 height = ' height="%d"' % self.height
556 height = ' height="%d"' % self.height
534 return u'<img src="%s"%s%s/>' % (self.url, width, height)
557 return u'<img src="%s"%s%s/>' % (self.url, width, height)
535
558
536 def _data_and_metadata(self):
559 def _data_and_metadata(self):
537 """shortcut for returning metadata with shape information, if defined"""
560 """shortcut for returning metadata with shape information, if defined"""
538 md = {}
561 md = {}
539 if self.width:
562 if self.width:
540 md['width'] = self.width
563 md['width'] = self.width
541 if self.height:
564 if self.height:
542 md['height'] = self.height
565 md['height'] = self.height
543 if md:
566 if md:
544 return self.data, md
567 return self.data, md
545 else:
568 else:
546 return self.data
569 return self.data
547
570
548 def _repr_png_(self):
571 def _repr_png_(self):
549 if self.embed and self.format == u'png':
572 if self.embed and self.format == u'png':
550 return self._data_and_metadata()
573 return self._data_and_metadata()
551
574
552 def _repr_jpeg_(self):
575 def _repr_jpeg_(self):
553 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
576 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
554 return self._data_and_metadata()
577 return self._data_and_metadata()
555
578
556 def _find_ext(self, s):
579 def _find_ext(self, s):
557 return unicode(s.split('.')[-1].lower())
580 return unicode(s.split('.')[-1].lower())
558
581
559
582
560 def clear_output(stdout=True, stderr=True, other=True):
583 def clear_output(stdout=True, stderr=True, other=True):
561 """Clear the output of the current cell receiving output.
584 """Clear the output of the current cell receiving output.
562
585
563 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
586 Optionally, each of stdout/stderr or other non-stream data (e.g. anything
564 produced by display()) can be excluded from the clear event.
587 produced by display()) can be excluded from the clear event.
565
588
566 By default, everything is cleared.
589 By default, everything is cleared.
567
590
568 Parameters
591 Parameters
569 ----------
592 ----------
570 stdout : bool [default: True]
593 stdout : bool [default: True]
571 Whether to clear stdout.
594 Whether to clear stdout.
572 stderr : bool [default: True]
595 stderr : bool [default: True]
573 Whether to clear stderr.
596 Whether to clear stderr.
574 other : bool [default: True]
597 other : bool [default: True]
575 Whether to clear everything else that is not stdout/stderr
598 Whether to clear everything else that is not stdout/stderr
576 (e.g. figures,images,HTML, any result of display()).
599 (e.g. figures,images,HTML, any result of display()).
577 """
600 """
578 from IPython.core.interactiveshell import InteractiveShell
601 from IPython.core.interactiveshell import InteractiveShell
579 if InteractiveShell.initialized():
602 if InteractiveShell.initialized():
580 InteractiveShell.instance().display_pub.clear_output(
603 InteractiveShell.instance().display_pub.clear_output(
581 stdout=stdout, stderr=stderr, other=other,
604 stdout=stdout, stderr=stderr, other=other,
582 )
605 )
583 else:
606 else:
584 from IPython.utils import io
607 from IPython.utils import io
585 if stdout:
608 if stdout:
586 print('\033[2K\r', file=io.stdout, end='')
609 print('\033[2K\r', file=io.stdout, end='')
587 io.stdout.flush()
610 io.stdout.flush()
588 if stderr:
611 if stderr:
589 print('\033[2K\r', file=io.stderr, end='')
612 print('\033[2K\r', file=io.stderr, end='')
590 io.stderr.flush()
613 io.stderr.flush()
591
614
General Comments 0
You need to be logged in to leave comments. Login now