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