##// END OF EJS Templates
Merge pull request #5992 from dawehner/display-video...
Min RK -
r18367:7b1ea1a9 merge
parent child Browse files
Show More
@@ -1,859 +1,944 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) 2013 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 import os
23 23 import struct
24 import mimetypes
24 25
25 26 from IPython.core.formatters import _safe_get_formatter_method
26 27 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
27 28 unicode_type)
28 29 from IPython.testing.skipdoctest import skip_doctest
29 30
30 31 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
31 32 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
32 33 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
33 34 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
34 35 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
35 36 'publish_display_data']
36 37
37 38 #-----------------------------------------------------------------------------
38 39 # utility functions
39 40 #-----------------------------------------------------------------------------
40 41
41 42 def _safe_exists(path):
42 43 """Check path, but don't let exceptions raise"""
43 44 try:
44 45 return os.path.exists(path)
45 46 except Exception:
46 47 return False
47 48
48 49 def _merge(d1, d2):
49 50 """Like update, but merges sub-dicts instead of clobbering at the top level.
50 51
51 52 Updates d1 in-place
52 53 """
53 54
54 55 if not isinstance(d2, dict) or not isinstance(d1, dict):
55 56 return d2
56 57 for key, value in d2.items():
57 58 d1[key] = _merge(d1.get(key), value)
58 59 return d1
59 60
60 61 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
61 62 """internal implementation of all display_foo methods
62 63
63 64 Parameters
64 65 ----------
65 66 mimetype : str
66 67 The mimetype to be published (e.g. 'image/png')
67 68 objs : tuple of objects
68 69 The Python objects to display, or if raw=True raw text data to
69 70 display.
70 71 raw : bool
71 72 Are the data objects raw data or Python objects that need to be
72 73 formatted before display? [default: False]
73 74 metadata : dict (optional)
74 75 Metadata to be associated with the specific mimetype output.
75 76 """
76 77 if metadata:
77 78 metadata = {mimetype: metadata}
78 79 if raw:
79 80 # turn list of pngdata into list of { 'image/png': pngdata }
80 81 objs = [ {mimetype: obj} for obj in objs ]
81 82 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
82 83
83 84 #-----------------------------------------------------------------------------
84 85 # Main functions
85 86 #-----------------------------------------------------------------------------
86 87
87 88 def publish_display_data(data, metadata=None, source=None):
88 89 """Publish data and metadata to all frontends.
89 90
90 91 See the ``display_data`` message in the messaging documentation for
91 92 more details about this message type.
92 93
93 94 The following MIME types are currently implemented:
94 95
95 96 * text/plain
96 97 * text/html
97 98 * text/markdown
98 99 * text/latex
99 100 * application/json
100 101 * application/javascript
101 102 * image/png
102 103 * image/jpeg
103 104 * image/svg+xml
104 105
105 106 Parameters
106 107 ----------
107 108 data : dict
108 109 A dictionary having keys that are valid MIME types (like
109 110 'text/plain' or 'image/svg+xml') and values that are the data for
110 111 that MIME type. The data itself must be a JSON'able data
111 112 structure. Minimally all data should have the 'text/plain' data,
112 113 which can be displayed by all frontends. If more than the plain
113 114 text is given, it is up to the frontend to decide which
114 115 representation to use.
115 116 metadata : dict
116 117 A dictionary for metadata related to the data. This can contain
117 118 arbitrary key, value pairs that frontends can use to interpret
118 119 the data. mime-type keys matching those in data can be used
119 120 to specify metadata about particular representations.
120 121 source : str, deprecated
121 122 Unused.
122 123 """
123 124 from IPython.core.interactiveshell import InteractiveShell
124 125 InteractiveShell.instance().display_pub.publish(
125 126 data=data,
126 127 metadata=metadata,
127 128 )
128 129
129 130 def display(*objs, **kwargs):
130 131 """Display a Python object in all frontends.
131 132
132 133 By default all representations will be computed and sent to the frontends.
133 134 Frontends can decide which representation is used and how.
134 135
135 136 Parameters
136 137 ----------
137 138 objs : tuple of objects
138 139 The Python objects to display.
139 140 raw : bool, optional
140 141 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
141 142 or Python objects that need to be formatted before display? [default: False]
142 143 include : list or tuple, optional
143 144 A list of format type strings (MIME types) to include in the
144 145 format data dict. If this is set *only* the format types included
145 146 in this list will be computed.
146 147 exclude : list or tuple, optional
147 148 A list of format type strings (MIME types) to exclude in the format
148 149 data dict. If this is set all format types will be computed,
149 150 except for those included in this argument.
150 151 metadata : dict, optional
151 152 A dictionary of metadata to associate with the output.
152 153 mime-type keys in this dictionary will be associated with the individual
153 154 representation formats, if they exist.
154 155 """
155 156 raw = kwargs.get('raw', False)
156 157 include = kwargs.get('include')
157 158 exclude = kwargs.get('exclude')
158 159 metadata = kwargs.get('metadata')
159 160
160 161 from IPython.core.interactiveshell import InteractiveShell
161 162
162 163 if not raw:
163 164 format = InteractiveShell.instance().display_formatter.format
164 165
165 166 for obj in objs:
166 167
167 168 # If _ipython_display_ is defined, use that to display this object.
168 169 display_method = _safe_get_formatter_method(obj, '_ipython_display_')
169 170 if display_method is not None:
170 171 try:
171 172 display_method(**kwargs)
172 173 except NotImplementedError:
173 174 pass
174 175 else:
175 176 continue
176 177 if raw:
177 178 publish_display_data(data=obj, metadata=metadata)
178 179 else:
179 180 format_dict, md_dict = format(obj, include=include, exclude=exclude)
180 181 if metadata:
181 182 # kwarg-specified metadata gets precedence
182 183 _merge(md_dict, metadata)
183 184 publish_display_data(data=format_dict, metadata=md_dict)
184 185
185 186
186 187 def display_pretty(*objs, **kwargs):
187 188 """Display the pretty (default) representation of an object.
188 189
189 190 Parameters
190 191 ----------
191 192 objs : tuple of objects
192 193 The Python objects to display, or if raw=True raw text data to
193 194 display.
194 195 raw : bool
195 196 Are the data objects raw data or Python objects that need to be
196 197 formatted before display? [default: False]
197 198 metadata : dict (optional)
198 199 Metadata to be associated with the specific mimetype output.
199 200 """
200 201 _display_mimetype('text/plain', objs, **kwargs)
201 202
202 203
203 204 def display_html(*objs, **kwargs):
204 205 """Display the HTML representation of an object.
205 206
206 207 Parameters
207 208 ----------
208 209 objs : tuple of objects
209 210 The Python objects to display, or if raw=True raw HTML data to
210 211 display.
211 212 raw : bool
212 213 Are the data objects raw data or Python objects that need to be
213 214 formatted before display? [default: False]
214 215 metadata : dict (optional)
215 216 Metadata to be associated with the specific mimetype output.
216 217 """
217 218 _display_mimetype('text/html', objs, **kwargs)
218 219
219 220
220 221 def display_markdown(*objs, **kwargs):
221 222 """Displays the Markdown representation of an object.
222 223
223 224 Parameters
224 225 ----------
225 226 objs : tuple of objects
226 227 The Python objects to display, or if raw=True raw markdown data to
227 228 display.
228 229 raw : bool
229 230 Are the data objects raw data or Python objects that need to be
230 231 formatted before display? [default: False]
231 232 metadata : dict (optional)
232 233 Metadata to be associated with the specific mimetype output.
233 234 """
234 235
235 236 _display_mimetype('text/markdown', objs, **kwargs)
236 237
237 238
238 239 def display_svg(*objs, **kwargs):
239 240 """Display the SVG representation of an object.
240 241
241 242 Parameters
242 243 ----------
243 244 objs : tuple of objects
244 245 The Python objects to display, or if raw=True raw svg data to
245 246 display.
246 247 raw : bool
247 248 Are the data objects raw data or Python objects that need to be
248 249 formatted before display? [default: False]
249 250 metadata : dict (optional)
250 251 Metadata to be associated with the specific mimetype output.
251 252 """
252 253 _display_mimetype('image/svg+xml', objs, **kwargs)
253 254
254 255
255 256 def display_png(*objs, **kwargs):
256 257 """Display the PNG representation of an object.
257 258
258 259 Parameters
259 260 ----------
260 261 objs : tuple of objects
261 262 The Python objects to display, or if raw=True raw png data to
262 263 display.
263 264 raw : bool
264 265 Are the data objects raw data or Python objects that need to be
265 266 formatted before display? [default: False]
266 267 metadata : dict (optional)
267 268 Metadata to be associated with the specific mimetype output.
268 269 """
269 270 _display_mimetype('image/png', objs, **kwargs)
270 271
271 272
272 273 def display_jpeg(*objs, **kwargs):
273 274 """Display the JPEG representation of an object.
274 275
275 276 Parameters
276 277 ----------
277 278 objs : tuple of objects
278 279 The Python objects to display, or if raw=True raw JPEG data to
279 280 display.
280 281 raw : bool
281 282 Are the data objects raw data or Python objects that need to be
282 283 formatted before display? [default: False]
283 284 metadata : dict (optional)
284 285 Metadata to be associated with the specific mimetype output.
285 286 """
286 287 _display_mimetype('image/jpeg', objs, **kwargs)
287 288
288 289
289 290 def display_latex(*objs, **kwargs):
290 291 """Display the LaTeX representation of an object.
291 292
292 293 Parameters
293 294 ----------
294 295 objs : tuple of objects
295 296 The Python objects to display, or if raw=True raw latex data to
296 297 display.
297 298 raw : bool
298 299 Are the data objects raw data or Python objects that need to be
299 300 formatted before display? [default: False]
300 301 metadata : dict (optional)
301 302 Metadata to be associated with the specific mimetype output.
302 303 """
303 304 _display_mimetype('text/latex', objs, **kwargs)
304 305
305 306
306 307 def display_json(*objs, **kwargs):
307 308 """Display the JSON representation of an object.
308 309
309 310 Note that not many frontends support displaying JSON.
310 311
311 312 Parameters
312 313 ----------
313 314 objs : tuple of objects
314 315 The Python objects to display, or if raw=True raw json data to
315 316 display.
316 317 raw : bool
317 318 Are the data objects raw data or Python objects that need to be
318 319 formatted before display? [default: False]
319 320 metadata : dict (optional)
320 321 Metadata to be associated with the specific mimetype output.
321 322 """
322 323 _display_mimetype('application/json', objs, **kwargs)
323 324
324 325
325 326 def display_javascript(*objs, **kwargs):
326 327 """Display the Javascript representation of an object.
327 328
328 329 Parameters
329 330 ----------
330 331 objs : tuple of objects
331 332 The Python objects to display, or if raw=True raw javascript data to
332 333 display.
333 334 raw : bool
334 335 Are the data objects raw data or Python objects that need to be
335 336 formatted before display? [default: False]
336 337 metadata : dict (optional)
337 338 Metadata to be associated with the specific mimetype output.
338 339 """
339 340 _display_mimetype('application/javascript', objs, **kwargs)
340 341
341 342
342 343 def display_pdf(*objs, **kwargs):
343 344 """Display the PDF representation of an object.
344 345
345 346 Parameters
346 347 ----------
347 348 objs : tuple of objects
348 349 The Python objects to display, or if raw=True raw javascript data to
349 350 display.
350 351 raw : bool
351 352 Are the data objects raw data or Python objects that need to be
352 353 formatted before display? [default: False]
353 354 metadata : dict (optional)
354 355 Metadata to be associated with the specific mimetype output.
355 356 """
356 357 _display_mimetype('application/pdf', objs, **kwargs)
357 358
358 359
359 360 #-----------------------------------------------------------------------------
360 361 # Smart classes
361 362 #-----------------------------------------------------------------------------
362 363
363 364
364 365 class DisplayObject(object):
365 366 """An object that wraps data to be displayed."""
366 367
367 368 _read_flags = 'r'
368 369 _show_mem_addr = False
369 370
370 371 def __init__(self, data=None, url=None, filename=None):
371 372 """Create a display object given raw data.
372 373
373 374 When this object is returned by an expression or passed to the
374 375 display function, it will result in the data being displayed
375 376 in the frontend. The MIME type of the data should match the
376 377 subclasses used, so the Png subclass should be used for 'image/png'
377 378 data. If the data is a URL, the data will first be downloaded
378 379 and then displayed. If
379 380
380 381 Parameters
381 382 ----------
382 383 data : unicode, str or bytes
383 384 The raw data or a URL or file to load the data from
384 385 url : unicode
385 386 A URL to download the data from.
386 387 filename : unicode
387 388 Path to a local file to load the data from.
388 389 """
389 390 if data is not None and isinstance(data, string_types):
390 391 if data.startswith('http') and url is None:
391 392 url = data
392 393 filename = None
393 394 data = None
394 395 elif _safe_exists(data) and filename is None:
395 396 url = None
396 397 filename = data
397 398 data = None
398 399
399 400 self.data = data
400 401 self.url = url
401 402 self.filename = None if filename is None else unicode_type(filename)
402 403
403 404 self.reload()
404 405 self._check_data()
405 406
406 407 def __repr__(self):
407 408 if not self._show_mem_addr:
408 409 cls = self.__class__
409 410 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
410 411 else:
411 412 r = super(DisplayObject, self).__repr__()
412 413 return r
413 414
414 415 def _check_data(self):
415 416 """Override in subclasses if there's something to check."""
416 417 pass
417 418
418 419 def reload(self):
419 420 """Reload the raw data from file or URL."""
420 421 if self.filename is not None:
421 422 with open(self.filename, self._read_flags) as f:
422 423 self.data = f.read()
423 424 elif self.url is not None:
424 425 try:
425 426 try:
426 427 from urllib.request import urlopen # Py3
427 428 except ImportError:
428 429 from urllib2 import urlopen
429 430 response = urlopen(self.url)
430 431 self.data = response.read()
431 432 # extract encoding from header, if there is one:
432 433 encoding = None
433 434 for sub in response.headers['content-type'].split(';'):
434 435 sub = sub.strip()
435 436 if sub.startswith('charset'):
436 437 encoding = sub.split('=')[-1].strip()
437 438 break
438 439 # decode data, if an encoding was specified
439 440 if encoding:
440 441 self.data = self.data.decode(encoding, 'replace')
441 442 except:
442 443 self.data = None
443 444
444 445 class TextDisplayObject(DisplayObject):
445 446 """Validate that display data is text"""
446 447 def _check_data(self):
447 448 if self.data is not None and not isinstance(self.data, string_types):
448 449 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
449 450
450 451 class Pretty(TextDisplayObject):
451 452
452 453 def _repr_pretty_(self):
453 454 return self.data
454 455
455 456
456 457 class HTML(TextDisplayObject):
457 458
458 459 def _repr_html_(self):
459 460 return self.data
460 461
461 462 def __html__(self):
462 463 """
463 464 This method exists to inform other HTML-using modules (e.g. Markupsafe,
464 465 htmltag, etc) that this object is HTML and does not need things like
465 466 special characters (<>&) escaped.
466 467 """
467 468 return self._repr_html_()
468 469
469 470
470 471 class Markdown(TextDisplayObject):
471 472
472 473 def _repr_markdown_(self):
473 474 return self.data
474 475
475 476
476 477 class Math(TextDisplayObject):
477 478
478 479 def _repr_latex_(self):
479 480 s = self.data.strip('$')
480 481 return "$$%s$$" % s
481 482
482 483
483 484 class Latex(TextDisplayObject):
484 485
485 486 def _repr_latex_(self):
486 487 return self.data
487 488
488 489
489 490 class SVG(DisplayObject):
490 491
491 492 # wrap data in a property, which extracts the <svg> tag, discarding
492 493 # document headers
493 494 _data = None
494 495
495 496 @property
496 497 def data(self):
497 498 return self._data
498 499
499 500 @data.setter
500 501 def data(self, svg):
501 502 if svg is None:
502 503 self._data = None
503 504 return
504 505 # parse into dom object
505 506 from xml.dom import minidom
506 507 svg = cast_bytes_py2(svg)
507 508 x = minidom.parseString(svg)
508 509 # get svg tag (should be 1)
509 510 found_svg = x.getElementsByTagName('svg')
510 511 if found_svg:
511 512 svg = found_svg[0].toxml()
512 513 else:
513 514 # fallback on the input, trust the user
514 515 # but this is probably an error.
515 516 pass
516 517 svg = cast_unicode(svg)
517 518 self._data = svg
518 519
519 520 def _repr_svg_(self):
520 521 return self.data
521 522
522 523
523 524 class JSON(TextDisplayObject):
524 525
525 526 def _repr_json_(self):
526 527 return self.data
527 528
528 529 css_t = """$("head").append($("<link/>").attr({
529 530 rel: "stylesheet",
530 531 type: "text/css",
531 532 href: "%s"
532 533 }));
533 534 """
534 535
535 536 lib_t1 = """$.getScript("%s", function () {
536 537 """
537 538 lib_t2 = """});
538 539 """
539 540
540 541 class Javascript(TextDisplayObject):
541 542
542 543 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
543 544 """Create a Javascript display object given raw data.
544 545
545 546 When this object is returned by an expression or passed to the
546 547 display function, it will result in the data being displayed
547 548 in the frontend. If the data is a URL, the data will first be
548 549 downloaded and then displayed.
549 550
550 551 In the Notebook, the containing element will be available as `element`,
551 552 and jQuery will be available. Content appended to `element` will be
552 553 visible in the output area.
553 554
554 555 Parameters
555 556 ----------
556 557 data : unicode, str or bytes
557 558 The Javascript source code or a URL to download it from.
558 559 url : unicode
559 560 A URL to download the data from.
560 561 filename : unicode
561 562 Path to a local file to load the data from.
562 563 lib : list or str
563 564 A sequence of Javascript library URLs to load asynchronously before
564 565 running the source code. The full URLs of the libraries should
565 566 be given. A single Javascript library URL can also be given as a
566 567 string.
567 568 css: : list or str
568 569 A sequence of css files to load before running the source code.
569 570 The full URLs of the css files should be given. A single css URL
570 571 can also be given as a string.
571 572 """
572 573 if isinstance(lib, string_types):
573 574 lib = [lib]
574 575 elif lib is None:
575 576 lib = []
576 577 if isinstance(css, string_types):
577 578 css = [css]
578 579 elif css is None:
579 580 css = []
580 581 if not isinstance(lib, (list,tuple)):
581 582 raise TypeError('expected sequence, got: %r' % lib)
582 583 if not isinstance(css, (list,tuple)):
583 584 raise TypeError('expected sequence, got: %r' % css)
584 585 self.lib = lib
585 586 self.css = css
586 587 super(Javascript, self).__init__(data=data, url=url, filename=filename)
587 588
588 589 def _repr_javascript_(self):
589 590 r = ''
590 591 for c in self.css:
591 592 r += css_t % c
592 593 for l in self.lib:
593 594 r += lib_t1 % l
594 595 r += self.data
595 596 r += lib_t2*len(self.lib)
596 597 return r
597 598
598 599 # constants for identifying png/jpeg data
599 600 _PNG = b'\x89PNG\r\n\x1a\n'
600 601 _JPEG = b'\xff\xd8'
601 602
602 603 def _pngxy(data):
603 604 """read the (width, height) from a PNG header"""
604 605 ihdr = data.index(b'IHDR')
605 606 # next 8 bytes are width/height
606 607 w4h4 = data[ihdr+4:ihdr+12]
607 608 return struct.unpack('>ii', w4h4)
608 609
609 610 def _jpegxy(data):
610 611 """read the (width, height) from a JPEG header"""
611 612 # adapted from http://www.64lines.com/jpeg-width-height
612 613
613 614 idx = 4
614 615 while True:
615 616 block_size = struct.unpack('>H', data[idx:idx+2])[0]
616 617 idx = idx + block_size
617 618 if data[idx:idx+2] == b'\xFF\xC0':
618 619 # found Start of Frame
619 620 iSOF = idx
620 621 break
621 622 else:
622 623 # read another block
623 624 idx += 2
624 625
625 626 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
626 627 return w, h
627 628
628 629 class Image(DisplayObject):
629 630
630 631 _read_flags = 'rb'
631 632 _FMT_JPEG = u'jpeg'
632 633 _FMT_PNG = u'png'
633 634 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
634 635
635 636 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
636 637 """Create a PNG/JPEG image object given raw data.
637 638
638 639 When this object is returned by an input cell or passed to the
639 640 display function, it will result in the image being displayed
640 641 in the frontend.
641 642
642 643 Parameters
643 644 ----------
644 645 data : unicode, str or bytes
645 646 The raw image data or a URL or filename to load the data from.
646 647 This always results in embedded image data.
647 648 url : unicode
648 649 A URL to download the data from. If you specify `url=`,
649 650 the image data will not be embedded unless you also specify `embed=True`.
650 651 filename : unicode
651 652 Path to a local file to load the data from.
652 653 Images from a file are always embedded.
653 654 format : unicode
654 655 The format of the image data (png/jpeg/jpg). If a filename or URL is given
655 656 for format will be inferred from the filename extension.
656 657 embed : bool
657 658 Should the image data be embedded using a data URI (True) or be
658 659 loaded using an <img> tag. Set this to True if you want the image
659 660 to be viewable later with no internet connection in the notebook.
660 661
661 662 Default is `True`, unless the keyword argument `url` is set, then
662 663 default value is `False`.
663 664
664 665 Note that QtConsole is not able to display images if `embed` is set to `False`
665 666 width : int
666 667 Width to which to constrain the image in html
667 668 height : int
668 669 Height to which to constrain the image in html
669 670 retina : bool
670 671 Automatically set the width and height to half of the measured
671 672 width and height.
672 673 This only works for embedded images because it reads the width/height
673 674 from image data.
674 675 For non-embedded images, you can just set the desired display width
675 676 and height directly.
676 677
677 678 Examples
678 679 --------
679 680 # embedded image data, works in qtconsole and notebook
680 681 # when passed positionally, the first arg can be any of raw image data,
681 682 # a URL, or a filename from which to load image data.
682 683 # The result is always embedding image data for inline images.
683 684 Image('http://www.google.fr/images/srpr/logo3w.png')
684 685 Image('/path/to/image.jpg')
685 686 Image(b'RAW_PNG_DATA...')
686 687
687 688 # Specifying Image(url=...) does not embed the image data,
688 689 # it only generates `<img>` tag with a link to the source.
689 690 # This will not work in the qtconsole or offline.
690 691 Image(url='http://www.google.fr/images/srpr/logo3w.png')
691 692
692 693 """
693 694 if filename is not None:
694 695 ext = self._find_ext(filename)
695 696 elif url is not None:
696 697 ext = self._find_ext(url)
697 698 elif data is None:
698 699 raise ValueError("No image data found. Expecting filename, url, or data.")
699 700 elif isinstance(data, string_types) and (
700 701 data.startswith('http') or _safe_exists(data)
701 702 ):
702 703 ext = self._find_ext(data)
703 704 else:
704 705 ext = None
705 706
706 707 if ext is not None:
707 708 format = ext.lower()
708 709 if ext == u'jpg' or ext == u'jpeg':
709 710 format = self._FMT_JPEG
710 711 if ext == u'png':
711 712 format = self._FMT_PNG
712 713 elif isinstance(data, bytes) and format == 'png':
713 714 # infer image type from image data header,
714 715 # only if format might not have been specified.
715 716 if data[:2] == _JPEG:
716 717 format = 'jpeg'
717 718
718 719 self.format = unicode_type(format).lower()
719 720 self.embed = embed if embed is not None else (url is None)
720 721
721 722 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
722 723 raise ValueError("Cannot embed the '%s' image format" % (self.format))
723 724 self.width = width
724 725 self.height = height
725 726 self.retina = retina
726 727 super(Image, self).__init__(data=data, url=url, filename=filename)
727 728
728 729 if retina:
729 730 self._retina_shape()
730 731
731 732 def _retina_shape(self):
732 733 """load pixel-doubled width and height from image data"""
733 734 if not self.embed:
734 735 return
735 736 if self.format == 'png':
736 737 w, h = _pngxy(self.data)
737 738 elif self.format == 'jpeg':
738 739 w, h = _jpegxy(self.data)
739 740 else:
740 741 # retina only supports png
741 742 return
742 743 self.width = w // 2
743 744 self.height = h // 2
744 745
745 746 def reload(self):
746 747 """Reload the raw data from file or URL."""
747 748 if self.embed:
748 749 super(Image,self).reload()
749 750 if self.retina:
750 751 self._retina_shape()
751 752
752 753 def _repr_html_(self):
753 754 if not self.embed:
754 755 width = height = ''
755 756 if self.width:
756 757 width = ' width="%d"' % self.width
757 758 if self.height:
758 759 height = ' height="%d"' % self.height
759 760 return u'<img src="%s"%s%s/>' % (self.url, width, height)
760 761
761 762 def _data_and_metadata(self):
762 763 """shortcut for returning metadata with shape information, if defined"""
763 764 md = {}
764 765 if self.width:
765 766 md['width'] = self.width
766 767 if self.height:
767 768 md['height'] = self.height
768 769 if md:
769 770 return self.data, md
770 771 else:
771 772 return self.data
772 773
773 774 def _repr_png_(self):
774 775 if self.embed and self.format == u'png':
775 776 return self._data_and_metadata()
776 777
777 778 def _repr_jpeg_(self):
778 779 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
779 780 return self._data_and_metadata()
780 781
781 782 def _find_ext(self, s):
782 783 return unicode_type(s.split('.')[-1].lower())
783 784
785 class Video(DisplayObject):
786
787 def __init__(self, data=None, url=None, filename=None, embed=None, mimetype=None):
788 """Create a video object given raw data or an URL.
789
790 When this object is returned by an input cell or passed to the
791 display function, it will result in the video being displayed
792 in the frontend.
793
794 Parameters
795 ----------
796 data : unicode, str or bytes
797 The raw image data or a URL or filename to load the data from.
798 This always results in embedded image data.
799 url : unicode
800 A URL to download the data from. If you specify `url=`,
801 the image data will not be embedded unless you also specify `embed=True`.
802 filename : unicode
803 Path to a local file to load the data from.
804 Videos from a file are always embedded.
805 embed : bool
806 Should the image data be embedded using a data URI (True) or be
807 loaded using an <img> tag. Set this to True if you want the image
808 to be viewable later with no internet connection in the notebook.
809
810 Default is `True`, unless the keyword argument `url` is set, then
811 default value is `False`.
812
813 Note that QtConsole is not able to display images if `embed` is set to `False`
814 mimetype: unicode
815 Specify the mimetype in case you load in a encoded video.
816 Examples
817 --------
818 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
819 Video('path/to/video.mp4')
820 Video('path/to/video.mp4', embed=False)
821 """
822 if url is None and (data.startswith('http') or data.startswith('https')):
823 url = data
824 data = None
825 embed = False
826 elif os.path.exists(data):
827 filename = data
828 data = None
829
830 self.mimetype = mimetype
831 self.embed = embed if embed is not None else (filename is not None)
832 super(Video, self).__init__(data=data, url=url, filename=filename)
833
834 def _repr_html_(self):
835 # External URLs and potentially local files are not embedded into the
836 # notebook output.
837 if not self.embed:
838 url = self.url if self.url is not None else self.filename
839 output = """<video src="{0}" controls>
840 Your browser does not support the <code>video</code> element.
841 </video>""".format(url)
842 return output
843 # Embedded videos uses base64 encoded videos.
844 if self.filename is not None:
845 mimetypes.init()
846 mimetype, encoding = mimetypes.guess_type(self.filename)
847
848 video = open(self.filename, 'rb').read()
849 video_encoded = video.encode('base64')
850 else:
851 video_encoded = self.data
852 mimetype = self.mimetype
853 output = """<video controls>
854 <source src="data:{0};base64,{1}" type="{0}">
855 Your browser does not support the video tag.
856 </video>""".format(mimetype, video_encoded)
857 return output
858
859 def reload(self):
860 # TODO
861 pass
862
863 def _repr_png_(self):
864 # TODO
865 pass
866 def _repr_jpeg_(self):
867 # TODO
868 pass
784 869
785 870 def clear_output(wait=False):
786 871 """Clear the output of the current cell receiving output.
787 872
788 873 Parameters
789 874 ----------
790 875 wait : bool [default: false]
791 876 Wait to clear the output until new output is available to replace it."""
792 877 from IPython.core.interactiveshell import InteractiveShell
793 878 if InteractiveShell.initialized():
794 879 InteractiveShell.instance().display_pub.clear_output(wait)
795 880 else:
796 881 from IPython.utils import io
797 882 print('\033[2K\r', file=io.stdout, end='')
798 883 io.stdout.flush()
799 884 print('\033[2K\r', file=io.stderr, end='')
800 885 io.stderr.flush()
801 886
802 887
803 888 @skip_doctest
804 889 def set_matplotlib_formats(*formats, **kwargs):
805 890 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
806 891
807 892 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
808 893
809 894 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
810 895
811 896 To set this in your config files use the following::
812 897
813 898 c.InlineBackend.figure_formats = {'png', 'jpeg'}
814 899 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
815 900
816 901 Parameters
817 902 ----------
818 903 *formats : strs
819 904 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
820 905 **kwargs :
821 906 Keyword args will be relayed to ``figure.canvas.print_figure``.
822 907 """
823 908 from IPython.core.interactiveshell import InteractiveShell
824 909 from IPython.core.pylabtools import select_figure_formats
825 910 from IPython.kernel.zmq.pylab.config import InlineBackend
826 911 # build kwargs, starting with InlineBackend config
827 912 kw = {}
828 913 cfg = InlineBackend.instance()
829 914 kw.update(cfg.print_figure_kwargs)
830 915 kw.update(**kwargs)
831 916 shell = InteractiveShell.instance()
832 917 select_figure_formats(shell, formats, **kw)
833 918
834 919 @skip_doctest
835 920 def set_matplotlib_close(close=True):
836 921 """Set whether the inline backend closes all figures automatically or not.
837 922
838 923 By default, the inline backend used in the IPython Notebook will close all
839 924 matplotlib figures automatically after each cell is run. This means that
840 925 plots in different cells won't interfere. Sometimes, you may want to make
841 926 a plot in one cell and then refine it in later cells. This can be accomplished
842 927 by::
843 928
844 929 In [1]: set_matplotlib_close(False)
845 930
846 931 To set this in your config files use the following::
847 932
848 933 c.InlineBackend.close_figures = False
849 934
850 935 Parameters
851 936 ----------
852 937 close : bool
853 938 Should all matplotlib figures be automatically closed after each cell is
854 939 run?
855 940 """
856 941 from IPython.kernel.zmq.pylab.config import InlineBackend
857 942 cfg = InlineBackend.instance()
858 943 cfg.close_figures = close
859 944
General Comments 0
You need to be logged in to leave comments. Login now