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