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