##// END OF EJS Templates
Merge pull request #10890 from takluyver/doc-more-display-fmt...
Matthias Bussonnier -
r24045:43994e7b merge
parent child Browse files
Show More
@@ -1,1412 +1,1413 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
8 8 from binascii import b2a_hex, b2a_base64, hexlify
9 9 import json
10 10 import mimetypes
11 11 import os
12 12 import struct
13 13 import sys
14 14 import warnings
15 15 from copy import deepcopy
16 16
17 17 from IPython.utils.py3compat import cast_unicode
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', 'ProgressBar', 'JSON',
24 24 'GeoJSON', 'Javascript', 'Image', 'clear_output', 'set_matplotlib_formats',
25 25 'set_matplotlib_close', 'publish_display_data', 'update_display', 'DisplayHandle',
26 26 'Video']
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # utility functions
30 30 #-----------------------------------------------------------------------------
31 31
32 32 def _safe_exists(path):
33 33 """Check path, but don't let exceptions raise"""
34 34 try:
35 35 return os.path.exists(path)
36 36 except Exception:
37 37 return False
38 38
39 39 def _merge(d1, d2):
40 40 """Like update, but merges sub-dicts instead of clobbering at the top level.
41 41
42 42 Updates d1 in-place
43 43 """
44 44
45 45 if not isinstance(d2, dict) or not isinstance(d1, dict):
46 46 return d2
47 47 for key, value in d2.items():
48 48 d1[key] = _merge(d1.get(key), value)
49 49 return d1
50 50
51 51 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
52 52 """internal implementation of all display_foo methods
53 53
54 54 Parameters
55 55 ----------
56 56 mimetype : str
57 57 The mimetype to be published (e.g. 'image/png')
58 58 objs : tuple of objects
59 59 The Python objects to display, or if raw=True raw text data to
60 60 display.
61 61 raw : bool
62 62 Are the data objects raw data or Python objects that need to be
63 63 formatted before display? [default: False]
64 64 metadata : dict (optional)
65 65 Metadata to be associated with the specific mimetype output.
66 66 """
67 67 if metadata:
68 68 metadata = {mimetype: metadata}
69 69 if raw:
70 70 # turn list of pngdata into list of { 'image/png': pngdata }
71 71 objs = [ {mimetype: obj} for obj in objs ]
72 72 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
73 73
74 74 #-----------------------------------------------------------------------------
75 75 # Main functions
76 76 #-----------------------------------------------------------------------------
77 77
78 78 # use * to indicate transient is keyword-only
79 79 def publish_display_data(data, metadata=None, source=None, *, transient=None, **kwargs):
80 80 """Publish data and metadata to all frontends.
81 81
82 82 See the ``display_data`` message in the messaging documentation for
83 83 more details about this message type.
84 84
85 85 Keys of data and metadata can be any mime-type.
86 86
87 87 Parameters
88 88 ----------
89 89 data : dict
90 90 A dictionary having keys that are valid MIME types (like
91 91 'text/plain' or 'image/svg+xml') and values that are the data for
92 92 that MIME type. The data itself must be a JSON'able data
93 93 structure. Minimally all data should have the 'text/plain' data,
94 94 which can be displayed by all frontends. If more than the plain
95 95 text is given, it is up to the frontend to decide which
96 96 representation to use.
97 97 metadata : dict
98 98 A dictionary for metadata related to the data. This can contain
99 99 arbitrary key, value pairs that frontends can use to interpret
100 100 the data. mime-type keys matching those in data can be used
101 101 to specify metadata about particular representations.
102 102 source : str, deprecated
103 103 Unused.
104 104 transient : dict, keyword-only
105 105 A dictionary of transient data, such as display_id.
106 106 """
107 107 from IPython.core.interactiveshell import InteractiveShell
108 108
109 109 display_pub = InteractiveShell.instance().display_pub
110 110
111 111 # only pass transient if supplied,
112 112 # to avoid errors with older ipykernel.
113 113 # TODO: We could check for ipykernel version and provide a detailed upgrade message.
114 114 if transient:
115 115 kwargs['transient'] = transient
116 116
117 117 display_pub.publish(
118 118 data=data,
119 119 metadata=metadata,
120 120 **kwargs
121 121 )
122 122
123 123
124 124 def _new_id():
125 125 """Generate a new random text id with urandom"""
126 126 return b2a_hex(os.urandom(16)).decode('ascii')
127 127
128 128
129 129 def display(*objs, include=None, exclude=None, metadata=None, transient=None, display_id=None, **kwargs):
130 130 """Display a Python object in all frontends.
131 131
132 132 By default all representations will be computed and sent to the frontends.
133 133 Frontends can decide which representation is used and how.
134 134
135 135 In terminal IPython this will be similar to using :func:`print`, for use in richer
136 136 frontends see Jupyter notebook examples with rich display logic.
137 137
138 138 Parameters
139 139 ----------
140 140 objs : tuple of objects
141 141 The Python objects to display.
142 142 raw : bool, optional
143 143 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
144 144 or Python objects that need to be formatted before display? [default: False]
145 145 include : list, tuple or set, optional
146 146 A list of format type strings (MIME types) to include in the
147 147 format data dict. If this is set *only* the format types included
148 148 in this list will be computed.
149 149 exclude : list, tuple or set, optional
150 150 A list of format type strings (MIME types) to exclude in the format
151 151 data dict. If this is set all format types will be computed,
152 152 except for those included in this argument.
153 153 metadata : dict, optional
154 154 A dictionary of metadata to associate with the output.
155 155 mime-type keys in this dictionary will be associated with the individual
156 156 representation formats, if they exist.
157 157 transient : dict, optional
158 158 A dictionary of transient data to associate with the output.
159 159 Data in this dict should not be persisted to files (e.g. notebooks).
160 160 display_id : str, bool optional
161 161 Set an id for the display.
162 162 This id can be used for updating this display area later via update_display.
163 163 If given as `True`, generate a new `display_id`
164 164 kwargs: additional keyword-args, optional
165 165 Additional keyword-arguments are passed through to the display publisher.
166 166
167 167 Returns
168 168 -------
169 169
170 170 handle: DisplayHandle
171 171 Returns a handle on updatable displays for use with :func:`update_display`,
172 172 if `display_id` is given. Returns :any:`None` if no `display_id` is given
173 173 (default).
174 174
175 175 Examples
176 176 --------
177 177
178 178 >>> class Json(object):
179 179 ... def __init__(self, json):
180 180 ... self.json = json
181 181 ... def _repr_pretty_(self, pp, cycle):
182 182 ... import json
183 183 ... pp.text(json.dumps(self.json, indent=2))
184 184 ... def __repr__(self):
185 185 ... return str(self.json)
186 186 ...
187 187
188 188 >>> d = Json({1:2, 3: {4:5}})
189 189
190 190 >>> print(d)
191 191 {1: 2, 3: {4: 5}}
192 192
193 193 >>> display(d)
194 194 {
195 195 "1": 2,
196 196 "3": {
197 197 "4": 5
198 198 }
199 199 }
200 200
201 201 >>> def int_formatter(integer, pp, cycle):
202 202 ... pp.text('I'*integer)
203 203
204 204 >>> plain = get_ipython().display_formatter.formatters['text/plain']
205 205 >>> plain.for_type(int, int_formatter)
206 206 <function _repr_pprint at 0x...>
207 207 >>> display(7-5)
208 208 II
209 209
210 210 >>> del plain.type_printers[int]
211 211 >>> display(7-5)
212 212 2
213 213
214 214 See Also
215 215 --------
216 216
217 217 :func:`update_display`
218 218
219 219 Notes
220 220 -----
221 221
222 222 In Python, objects can declare their textual representation using the
223 223 `__repr__` method. IPython expands on this idea and allows objects to declare
224 224 other, rich representations including:
225 225
226 226 - HTML
227 227 - JSON
228 228 - PNG
229 229 - JPEG
230 230 - SVG
231 231 - LaTeX
232 232
233 233 A single object can declare some or all of these representations; all are
234 234 handled by IPython's display system.
235 235
236 236 The main idea of the first approach is that you have to implement special
237 237 display methods when you define your class, one for each representation you
238 238 want to use. Here is a list of the names of the special methods and the
239 239 values they must return:
240 240
241 241 - `_repr_html_`: return raw HTML as a string
242 242 - `_repr_json_`: return a JSONable dict
243 243 - `_repr_jpeg_`: return raw JPEG data
244 244 - `_repr_png_`: return raw PNG data
245 245 - `_repr_svg_`: return raw SVG data as a string
246 246 - `_repr_latex_`: return LaTeX commands in a string surrounded by "$".
247 247 - `_repr_mimebundle_`: return a full mimebundle containing the mapping
248 248 from all mimetypes to data.
249 249 Use this for any mime-type not listed above.
250 250
251 251 When you are directly writing your own classes, you can adapt them for
252 252 display in IPython by following the above approach. But in practice, you
253 253 often need to work with existing classes that you can't easily modify.
254 254
255 You can refer to the documentation on IPython display formatters in order to
256 register custom formatters for already existing types.
255 You can refer to the documentation on integrating with the display system in
256 order to register custom formatters for already existing types
257 (:ref:`integrating_rich_display`).
257 258
258 259 .. versionadded:: 5.4 display available without import
259 260 .. versionadded:: 6.1 display available without import
260 261
261 262 Since IPython 5.4 and 6.1 :func:`display` is automatically made available to
262 263 the user without import. If you are using display in a document that might
263 264 be used in a pure python context or with older version of IPython, use the
264 265 following import at the top of your file::
265 266
266 267 from IPython.display import display
267 268
268 269 """
269 270 from IPython.core.interactiveshell import InteractiveShell
270 271
271 272 if not InteractiveShell.initialized():
272 273 # Directly print objects.
273 274 print(*objs)
274 275 return
275 276
276 277 raw = kwargs.pop('raw', False)
277 278 if transient is None:
278 279 transient = {}
279 280 if metadata is None:
280 281 metadata={}
281 282 if display_id:
282 283 if display_id is True:
283 284 display_id = _new_id()
284 285 transient['display_id'] = display_id
285 286 if kwargs.get('update') and 'display_id' not in transient:
286 287 raise TypeError('display_id required for update_display')
287 288 if transient:
288 289 kwargs['transient'] = transient
289 290
290 291 if not raw:
291 292 format = InteractiveShell.instance().display_formatter.format
292 293
293 294 for obj in objs:
294 295 if raw:
295 296 publish_display_data(data=obj, metadata=metadata, **kwargs)
296 297 else:
297 298 format_dict, md_dict = format(obj, include=include, exclude=exclude)
298 299 if not format_dict:
299 300 # nothing to display (e.g. _ipython_display_ took over)
300 301 continue
301 302 if metadata:
302 303 # kwarg-specified metadata gets precedence
303 304 _merge(md_dict, metadata)
304 305 publish_display_data(data=format_dict, metadata=md_dict, **kwargs)
305 306 if display_id:
306 307 return DisplayHandle(display_id)
307 308
308 309
309 310 # use * for keyword-only display_id arg
310 311 def update_display(obj, *, display_id, **kwargs):
311 312 """Update an existing display by id
312 313
313 314 Parameters
314 315 ----------
315 316
316 317 obj:
317 318 The object with which to update the display
318 319 display_id: keyword-only
319 320 The id of the display to update
320 321
321 322 See Also
322 323 --------
323 324
324 325 :func:`display`
325 326 """
326 327 kwargs['update'] = True
327 328 display(obj, display_id=display_id, **kwargs)
328 329
329 330
330 331 class DisplayHandle(object):
331 332 """A handle on an updatable display
332 333
333 334 Call `.update(obj)` to display a new object.
334 335
335 336 Call `.display(obj`) to add a new instance of this display,
336 337 and update existing instances.
337 338
338 339 See Also
339 340 --------
340 341
341 342 :func:`display`, :func:`update_display`
342 343
343 344 """
344 345
345 346 def __init__(self, display_id=None):
346 347 if display_id is None:
347 348 display_id = _new_id()
348 349 self.display_id = display_id
349 350
350 351 def __repr__(self):
351 352 return "<%s display_id=%s>" % (self.__class__.__name__, self.display_id)
352 353
353 354 def display(self, obj, **kwargs):
354 355 """Make a new display with my id, updating existing instances.
355 356
356 357 Parameters
357 358 ----------
358 359
359 360 obj:
360 361 object to display
361 362 **kwargs:
362 363 additional keyword arguments passed to display
363 364 """
364 365 display(obj, display_id=self.display_id, **kwargs)
365 366
366 367 def update(self, obj, **kwargs):
367 368 """Update existing displays with my id
368 369
369 370 Parameters
370 371 ----------
371 372
372 373 obj:
373 374 object to display
374 375 **kwargs:
375 376 additional keyword arguments passed to update_display
376 377 """
377 378 update_display(obj, display_id=self.display_id, **kwargs)
378 379
379 380
380 381 def display_pretty(*objs, **kwargs):
381 382 """Display the pretty (default) representation of an object.
382 383
383 384 Parameters
384 385 ----------
385 386 objs : tuple of objects
386 387 The Python objects to display, or if raw=True raw text data to
387 388 display.
388 389 raw : bool
389 390 Are the data objects raw data or Python objects that need to be
390 391 formatted before display? [default: False]
391 392 metadata : dict (optional)
392 393 Metadata to be associated with the specific mimetype output.
393 394 """
394 395 _display_mimetype('text/plain', objs, **kwargs)
395 396
396 397
397 398 def display_html(*objs, **kwargs):
398 399 """Display the HTML representation of an object.
399 400
400 401 Note: If raw=False and the object does not have a HTML
401 402 representation, no HTML will be shown.
402 403
403 404 Parameters
404 405 ----------
405 406 objs : tuple of objects
406 407 The Python objects to display, or if raw=True raw HTML data to
407 408 display.
408 409 raw : bool
409 410 Are the data objects raw data or Python objects that need to be
410 411 formatted before display? [default: False]
411 412 metadata : dict (optional)
412 413 Metadata to be associated with the specific mimetype output.
413 414 """
414 415 _display_mimetype('text/html', objs, **kwargs)
415 416
416 417
417 418 def display_markdown(*objs, **kwargs):
418 419 """Displays the Markdown representation of an object.
419 420
420 421 Parameters
421 422 ----------
422 423 objs : tuple of objects
423 424 The Python objects to display, or if raw=True raw markdown data to
424 425 display.
425 426 raw : bool
426 427 Are the data objects raw data or Python objects that need to be
427 428 formatted before display? [default: False]
428 429 metadata : dict (optional)
429 430 Metadata to be associated with the specific mimetype output.
430 431 """
431 432
432 433 _display_mimetype('text/markdown', objs, **kwargs)
433 434
434 435
435 436 def display_svg(*objs, **kwargs):
436 437 """Display the SVG representation of an object.
437 438
438 439 Parameters
439 440 ----------
440 441 objs : tuple of objects
441 442 The Python objects to display, or if raw=True raw svg data to
442 443 display.
443 444 raw : bool
444 445 Are the data objects raw data or Python objects that need to be
445 446 formatted before display? [default: False]
446 447 metadata : dict (optional)
447 448 Metadata to be associated with the specific mimetype output.
448 449 """
449 450 _display_mimetype('image/svg+xml', objs, **kwargs)
450 451
451 452
452 453 def display_png(*objs, **kwargs):
453 454 """Display the PNG representation of an object.
454 455
455 456 Parameters
456 457 ----------
457 458 objs : tuple of objects
458 459 The Python objects to display, or if raw=True raw png data to
459 460 display.
460 461 raw : bool
461 462 Are the data objects raw data or Python objects that need to be
462 463 formatted before display? [default: False]
463 464 metadata : dict (optional)
464 465 Metadata to be associated with the specific mimetype output.
465 466 """
466 467 _display_mimetype('image/png', objs, **kwargs)
467 468
468 469
469 470 def display_jpeg(*objs, **kwargs):
470 471 """Display the JPEG representation of an object.
471 472
472 473 Parameters
473 474 ----------
474 475 objs : tuple of objects
475 476 The Python objects to display, or if raw=True raw JPEG data to
476 477 display.
477 478 raw : bool
478 479 Are the data objects raw data or Python objects that need to be
479 480 formatted before display? [default: False]
480 481 metadata : dict (optional)
481 482 Metadata to be associated with the specific mimetype output.
482 483 """
483 484 _display_mimetype('image/jpeg', objs, **kwargs)
484 485
485 486
486 487 def display_latex(*objs, **kwargs):
487 488 """Display the LaTeX representation of an object.
488 489
489 490 Parameters
490 491 ----------
491 492 objs : tuple of objects
492 493 The Python objects to display, or if raw=True raw latex data to
493 494 display.
494 495 raw : bool
495 496 Are the data objects raw data or Python objects that need to be
496 497 formatted before display? [default: False]
497 498 metadata : dict (optional)
498 499 Metadata to be associated with the specific mimetype output.
499 500 """
500 501 _display_mimetype('text/latex', objs, **kwargs)
501 502
502 503
503 504 def display_json(*objs, **kwargs):
504 505 """Display the JSON representation of an object.
505 506
506 507 Note that not many frontends support displaying JSON.
507 508
508 509 Parameters
509 510 ----------
510 511 objs : tuple of objects
511 512 The Python objects to display, or if raw=True raw json data to
512 513 display.
513 514 raw : bool
514 515 Are the data objects raw data or Python objects that need to be
515 516 formatted before display? [default: False]
516 517 metadata : dict (optional)
517 518 Metadata to be associated with the specific mimetype output.
518 519 """
519 520 _display_mimetype('application/json', objs, **kwargs)
520 521
521 522
522 523 def display_javascript(*objs, **kwargs):
523 524 """Display the Javascript representation of an object.
524 525
525 526 Parameters
526 527 ----------
527 528 objs : tuple of objects
528 529 The Python objects to display, or if raw=True raw javascript data to
529 530 display.
530 531 raw : bool
531 532 Are the data objects raw data or Python objects that need to be
532 533 formatted before display? [default: False]
533 534 metadata : dict (optional)
534 535 Metadata to be associated with the specific mimetype output.
535 536 """
536 537 _display_mimetype('application/javascript', objs, **kwargs)
537 538
538 539
539 540 def display_pdf(*objs, **kwargs):
540 541 """Display the PDF representation of an object.
541 542
542 543 Parameters
543 544 ----------
544 545 objs : tuple of objects
545 546 The Python objects to display, or if raw=True raw javascript data to
546 547 display.
547 548 raw : bool
548 549 Are the data objects raw data or Python objects that need to be
549 550 formatted before display? [default: False]
550 551 metadata : dict (optional)
551 552 Metadata to be associated with the specific mimetype output.
552 553 """
553 554 _display_mimetype('application/pdf', objs, **kwargs)
554 555
555 556
556 557 #-----------------------------------------------------------------------------
557 558 # Smart classes
558 559 #-----------------------------------------------------------------------------
559 560
560 561
561 562 class DisplayObject(object):
562 563 """An object that wraps data to be displayed."""
563 564
564 565 _read_flags = 'r'
565 566 _show_mem_addr = False
566 567 metadata = None
567 568
568 569 def __init__(self, data=None, url=None, filename=None, metadata=None):
569 570 """Create a display object given raw data.
570 571
571 572 When this object is returned by an expression or passed to the
572 573 display function, it will result in the data being displayed
573 574 in the frontend. The MIME type of the data should match the
574 575 subclasses used, so the Png subclass should be used for 'image/png'
575 576 data. If the data is a URL, the data will first be downloaded
576 577 and then displayed. If
577 578
578 579 Parameters
579 580 ----------
580 581 data : unicode, str or bytes
581 582 The raw data or a URL or file to load the data from
582 583 url : unicode
583 584 A URL to download the data from.
584 585 filename : unicode
585 586 Path to a local file to load the data from.
586 587 metadata : dict
587 588 Dict of metadata associated to be the object when displayed
588 589 """
589 590 if data is not None and isinstance(data, str):
590 591 if data.startswith('http') and url is None:
591 592 url = data
592 593 filename = None
593 594 data = None
594 595 elif _safe_exists(data) and filename is None:
595 596 url = None
596 597 filename = data
597 598 data = None
598 599
599 600 self.data = data
600 601 self.url = url
601 602 self.filename = filename
602 603
603 604 if metadata is not None:
604 605 self.metadata = metadata
605 606 elif self.metadata is None:
606 607 self.metadata = {}
607 608
608 609 self.reload()
609 610 self._check_data()
610 611
611 612 def __repr__(self):
612 613 if not self._show_mem_addr:
613 614 cls = self.__class__
614 615 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
615 616 else:
616 617 r = super(DisplayObject, self).__repr__()
617 618 return r
618 619
619 620 def _check_data(self):
620 621 """Override in subclasses if there's something to check."""
621 622 pass
622 623
623 624 def _data_and_metadata(self):
624 625 """shortcut for returning metadata with shape information, if defined"""
625 626 if self.metadata:
626 627 return self.data, deepcopy(self.metadata)
627 628 else:
628 629 return self.data
629 630
630 631 def reload(self):
631 632 """Reload the raw data from file or URL."""
632 633 if self.filename is not None:
633 634 with open(self.filename, self._read_flags) as f:
634 635 self.data = f.read()
635 636 elif self.url is not None:
636 637 try:
637 638 # Deferred import
638 639 from urllib.request import urlopen
639 640 response = urlopen(self.url)
640 641 self.data = response.read()
641 642 # extract encoding from header, if there is one:
642 643 encoding = None
643 644 for sub in response.headers['content-type'].split(';'):
644 645 sub = sub.strip()
645 646 if sub.startswith('charset'):
646 647 encoding = sub.split('=')[-1].strip()
647 648 break
648 649 # decode data, if an encoding was specified
649 650 if encoding:
650 651 self.data = self.data.decode(encoding, 'replace')
651 652 except:
652 653 self.data = None
653 654
654 655 class TextDisplayObject(DisplayObject):
655 656 """Validate that display data is text"""
656 657 def _check_data(self):
657 658 if self.data is not None and not isinstance(self.data, str):
658 659 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
659 660
660 661 class Pretty(TextDisplayObject):
661 662
662 663 def _repr_pretty_(self, pp, cycle):
663 664 return pp.text(self.data)
664 665
665 666
666 667 class HTML(TextDisplayObject):
667 668
668 669 def _repr_html_(self):
669 670 return self.data
670 671
671 672 def __html__(self):
672 673 """
673 674 This method exists to inform other HTML-using modules (e.g. Markupsafe,
674 675 htmltag, etc) that this object is HTML and does not need things like
675 676 special characters (<>&) escaped.
676 677 """
677 678 return self._repr_html_()
678 679
679 680
680 681 class Markdown(TextDisplayObject):
681 682
682 683 def _repr_markdown_(self):
683 684 return self.data
684 685
685 686
686 687 class Math(TextDisplayObject):
687 688
688 689 def _repr_latex_(self):
689 690 s = self.data.strip('$')
690 691 return "$$%s$$" % s
691 692
692 693
693 694 class Latex(TextDisplayObject):
694 695
695 696 def _repr_latex_(self):
696 697 return self.data
697 698
698 699
699 700 class SVG(DisplayObject):
700 701
701 702 _read_flags = 'rb'
702 703 # wrap data in a property, which extracts the <svg> tag, discarding
703 704 # document headers
704 705 _data = None
705 706
706 707 @property
707 708 def data(self):
708 709 return self._data
709 710
710 711 @data.setter
711 712 def data(self, svg):
712 713 if svg is None:
713 714 self._data = None
714 715 return
715 716 # parse into dom object
716 717 from xml.dom import minidom
717 718 x = minidom.parseString(svg)
718 719 # get svg tag (should be 1)
719 720 found_svg = x.getElementsByTagName('svg')
720 721 if found_svg:
721 722 svg = found_svg[0].toxml()
722 723 else:
723 724 # fallback on the input, trust the user
724 725 # but this is probably an error.
725 726 pass
726 727 svg = cast_unicode(svg)
727 728 self._data = svg
728 729
729 730 def _repr_svg_(self):
730 731 return self._data_and_metadata()
731 732
732 733 class ProgressBar(DisplayObject):
733 734 """Progressbar supports displaying a progressbar like element
734 735 """
735 736 def __init__(self, total):
736 737 """Creates a new progressbar
737 738
738 739 Parameters
739 740 ----------
740 741 total : int
741 742 maximum size of the progressbar
742 743 """
743 744 self.total = total
744 745 self._progress = 0
745 746 self.html_width = '60ex'
746 747 self.text_width = 60
747 748 self._display_id = hexlify(os.urandom(8)).decode('ascii')
748 749
749 750 def __repr__(self):
750 751 fraction = self.progress / self.total
751 752 filled = '=' * int(fraction * self.text_width)
752 753 rest = ' ' * (self.text_width - len(filled))
753 754 return '[{}{}] {}/{}'.format(
754 755 filled, rest,
755 756 self.progress, self.total,
756 757 )
757 758
758 759 def _repr_html_(self):
759 760 return "<progress style='width:{}' max='{}' value='{}'></progress>".format(
760 761 self.html_width, self.total, self.progress)
761 762
762 763 def display(self):
763 764 display(self, display_id=self._display_id)
764 765
765 766 def update(self):
766 767 display(self, display_id=self._display_id, update=True)
767 768
768 769 @property
769 770 def progress(self):
770 771 return self._progress
771 772
772 773 @progress.setter
773 774 def progress(self, value):
774 775 self._progress = value
775 776 self.update()
776 777
777 778 def __iter__(self):
778 779 self.display()
779 780 self._progress = -1 # First iteration is 0
780 781 return self
781 782
782 783 def __next__(self):
783 784 """Returns current value and increments display by one."""
784 785 self.progress += 1
785 786 if self.progress < self.total:
786 787 return self.progress
787 788 else:
788 789 raise StopIteration()
789 790
790 791 class JSON(DisplayObject):
791 792 """JSON expects a JSON-able dict or list
792 793
793 794 not an already-serialized JSON string.
794 795
795 796 Scalar types (None, number, string) are not allowed, only dict or list containers.
796 797 """
797 798 # wrap data in a property, which warns about passing already-serialized JSON
798 799 _data = None
799 800 def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None, **kwargs):
800 801 """Create a JSON display object given raw data.
801 802
802 803 Parameters
803 804 ----------
804 805 data : dict or list
805 806 JSON data to display. Not an already-serialized JSON string.
806 807 Scalar types (None, number, string) are not allowed, only dict
807 808 or list containers.
808 809 url : unicode
809 810 A URL to download the data from.
810 811 filename : unicode
811 812 Path to a local file to load the data from.
812 813 expanded : boolean
813 814 Metadata to control whether a JSON display component is expanded.
814 815 metadata: dict
815 816 Specify extra metadata to attach to the json display object.
816 817 """
817 818 self.metadata = {'expanded': expanded}
818 819 if metadata:
819 820 self.metadata.update(metadata)
820 821 if kwargs:
821 822 self.metadata.update(kwargs)
822 823 super(JSON, self).__init__(data=data, url=url, filename=filename)
823 824
824 825 def _check_data(self):
825 826 if self.data is not None and not isinstance(self.data, (dict, list)):
826 827 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
827 828
828 829 @property
829 830 def data(self):
830 831 return self._data
831 832
832 833 @data.setter
833 834 def data(self, data):
834 835 if isinstance(data, str):
835 836 if getattr(self, 'filename', None) is None:
836 837 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
837 838 data = json.loads(data)
838 839 self._data = data
839 840
840 841 def _data_and_metadata(self):
841 842 return self.data, self.metadata
842 843
843 844 def _repr_json_(self):
844 845 return self._data_and_metadata()
845 846
846 847 _css_t = """$("head").append($("<link/>").attr({
847 848 rel: "stylesheet",
848 849 type: "text/css",
849 850 href: "%s"
850 851 }));
851 852 """
852 853
853 854 _lib_t1 = """$.getScript("%s", function () {
854 855 """
855 856 _lib_t2 = """});
856 857 """
857 858
858 859 class GeoJSON(JSON):
859 860 """GeoJSON expects JSON-able dict
860 861
861 862 not an already-serialized JSON string.
862 863
863 864 Scalar types (None, number, string) are not allowed, only dict containers.
864 865 """
865 866
866 867 def __init__(self, *args, **kwargs):
867 868 """Create a GeoJSON display object given raw data.
868 869
869 870 Parameters
870 871 ----------
871 872 data : dict or list
872 873 VegaLite data. Not an already-serialized JSON string.
873 874 Scalar types (None, number, string) are not allowed, only dict
874 875 or list containers.
875 876 url_template : string
876 877 Leaflet TileLayer URL template: http://leafletjs.com/reference.html#url-template
877 878 layer_options : dict
878 879 Leaflet TileLayer options: http://leafletjs.com/reference.html#tilelayer-options
879 880 url : unicode
880 881 A URL to download the data from.
881 882 filename : unicode
882 883 Path to a local file to load the data from.
883 884 metadata: dict
884 885 Specify extra metadata to attach to the json display object.
885 886
886 887 Examples
887 888 --------
888 889
889 890 The following will display an interactive map of Mars with a point of
890 891 interest on frontend that do support GeoJSON display.
891 892
892 893 >>> from IPython.display import GeoJSON
893 894
894 895 >>> GeoJSON(data={
895 896 ... "type": "Feature",
896 897 ... "geometry": {
897 898 ... "type": "Point",
898 899 ... "coordinates": [-81.327, 296.038]
899 900 ... }
900 901 ... },
901 902 ... url_template="http://s3-eu-west-1.amazonaws.com/whereonmars.cartodb.net/{basemap_id}/{z}/{x}/{y}.png",
902 903 ... layer_options={
903 904 ... "basemap_id": "celestia_mars-shaded-16k_global",
904 905 ... "attribution" : "Celestia/praesepe",
905 906 ... "minZoom" : 0,
906 907 ... "maxZoom" : 18,
907 908 ... })
908 909 <IPython.core.display.GeoJSON object>
909 910
910 911 In the terminal IPython, you will only see the text representation of
911 912 the GeoJSON object.
912 913
913 914 """
914 915
915 916 super(GeoJSON, self).__init__(*args, **kwargs)
916 917
917 918
918 919 def _ipython_display_(self):
919 920 bundle = {
920 921 'application/geo+json': self.data,
921 922 'text/plain': '<IPython.display.GeoJSON object>'
922 923 }
923 924 metadata = {
924 925 'application/geo+json': self.metadata
925 926 }
926 927 display(bundle, metadata=metadata, raw=True)
927 928
928 929 class Javascript(TextDisplayObject):
929 930
930 931 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
931 932 """Create a Javascript display object given raw data.
932 933
933 934 When this object is returned by an expression or passed to the
934 935 display function, it will result in the data being displayed
935 936 in the frontend. If the data is a URL, the data will first be
936 937 downloaded and then displayed.
937 938
938 939 In the Notebook, the containing element will be available as `element`,
939 940 and jQuery will be available. Content appended to `element` will be
940 941 visible in the output area.
941 942
942 943 Parameters
943 944 ----------
944 945 data : unicode, str or bytes
945 946 The Javascript source code or a URL to download it from.
946 947 url : unicode
947 948 A URL to download the data from.
948 949 filename : unicode
949 950 Path to a local file to load the data from.
950 951 lib : list or str
951 952 A sequence of Javascript library URLs to load asynchronously before
952 953 running the source code. The full URLs of the libraries should
953 954 be given. A single Javascript library URL can also be given as a
954 955 string.
955 956 css: : list or str
956 957 A sequence of css files to load before running the source code.
957 958 The full URLs of the css files should be given. A single css URL
958 959 can also be given as a string.
959 960 """
960 961 if isinstance(lib, str):
961 962 lib = [lib]
962 963 elif lib is None:
963 964 lib = []
964 965 if isinstance(css, str):
965 966 css = [css]
966 967 elif css is None:
967 968 css = []
968 969 if not isinstance(lib, (list,tuple)):
969 970 raise TypeError('expected sequence, got: %r' % lib)
970 971 if not isinstance(css, (list,tuple)):
971 972 raise TypeError('expected sequence, got: %r' % css)
972 973 self.lib = lib
973 974 self.css = css
974 975 super(Javascript, self).__init__(data=data, url=url, filename=filename)
975 976
976 977 def _repr_javascript_(self):
977 978 r = ''
978 979 for c in self.css:
979 980 r += _css_t % c
980 981 for l in self.lib:
981 982 r += _lib_t1 % l
982 983 r += self.data
983 984 r += _lib_t2*len(self.lib)
984 985 return r
985 986
986 987 # constants for identifying png/jpeg data
987 988 _PNG = b'\x89PNG\r\n\x1a\n'
988 989 _JPEG = b'\xff\xd8'
989 990
990 991 def _pngxy(data):
991 992 """read the (width, height) from a PNG header"""
992 993 ihdr = data.index(b'IHDR')
993 994 # next 8 bytes are width/height
994 995 return struct.unpack('>ii', data[ihdr+4:ihdr+12])
995 996
996 997 def _jpegxy(data):
997 998 """read the (width, height) from a JPEG header"""
998 999 # adapted from http://www.64lines.com/jpeg-width-height
999 1000
1000 1001 idx = 4
1001 1002 while True:
1002 1003 block_size = struct.unpack('>H', data[idx:idx+2])[0]
1003 1004 idx = idx + block_size
1004 1005 if data[idx:idx+2] == b'\xFF\xC0':
1005 1006 # found Start of Frame
1006 1007 iSOF = idx
1007 1008 break
1008 1009 else:
1009 1010 # read another block
1010 1011 idx += 2
1011 1012
1012 1013 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
1013 1014 return w, h
1014 1015
1015 1016 def _gifxy(data):
1016 1017 """read the (width, height) from a GIF header"""
1017 1018 return struct.unpack('<HH', data[6:10])
1018 1019
1019 1020
1020 1021 class Image(DisplayObject):
1021 1022
1022 1023 _read_flags = 'rb'
1023 1024 _FMT_JPEG = u'jpeg'
1024 1025 _FMT_PNG = u'png'
1025 1026 _FMT_GIF = u'gif'
1026 1027 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG, _FMT_GIF]
1027 1028 _MIMETYPES = {
1028 1029 _FMT_PNG: 'image/png',
1029 1030 _FMT_JPEG: 'image/jpeg',
1030 1031 _FMT_GIF: 'image/gif',
1031 1032 }
1032 1033
1033 1034 def __init__(self, data=None, url=None, filename=None, format=None,
1034 1035 embed=None, width=None, height=None, retina=False,
1035 1036 unconfined=False, metadata=None):
1036 1037 """Create a PNG/JPEG/GIF image object given raw data.
1037 1038
1038 1039 When this object is returned by an input cell or passed to the
1039 1040 display function, it will result in the image being displayed
1040 1041 in the frontend.
1041 1042
1042 1043 Parameters
1043 1044 ----------
1044 1045 data : unicode, str or bytes
1045 1046 The raw image data or a URL or filename to load the data from.
1046 1047 This always results in embedded image data.
1047 1048 url : unicode
1048 1049 A URL to download the data from. If you specify `url=`,
1049 1050 the image data will not be embedded unless you also specify `embed=True`.
1050 1051 filename : unicode
1051 1052 Path to a local file to load the data from.
1052 1053 Images from a file are always embedded.
1053 1054 format : unicode
1054 1055 The format of the image data (png/jpeg/jpg/gif). If a filename or URL is given
1055 1056 for format will be inferred from the filename extension.
1056 1057 embed : bool
1057 1058 Should the image data be embedded using a data URI (True) or be
1058 1059 loaded using an <img> tag. Set this to True if you want the image
1059 1060 to be viewable later with no internet connection in the notebook.
1060 1061
1061 1062 Default is `True`, unless the keyword argument `url` is set, then
1062 1063 default value is `False`.
1063 1064
1064 1065 Note that QtConsole is not able to display images if `embed` is set to `False`
1065 1066 width : int
1066 1067 Width in pixels to which to constrain the image in html
1067 1068 height : int
1068 1069 Height in pixels to which to constrain the image in html
1069 1070 retina : bool
1070 1071 Automatically set the width and height to half of the measured
1071 1072 width and height.
1072 1073 This only works for embedded images because it reads the width/height
1073 1074 from image data.
1074 1075 For non-embedded images, you can just set the desired display width
1075 1076 and height directly.
1076 1077 unconfined: bool
1077 1078 Set unconfined=True to disable max-width confinement of the image.
1078 1079 metadata: dict
1079 1080 Specify extra metadata to attach to the image.
1080 1081
1081 1082 Examples
1082 1083 --------
1083 1084 # embedded image data, works in qtconsole and notebook
1084 1085 # when passed positionally, the first arg can be any of raw image data,
1085 1086 # a URL, or a filename from which to load image data.
1086 1087 # The result is always embedding image data for inline images.
1087 1088 Image('http://www.google.fr/images/srpr/logo3w.png')
1088 1089 Image('/path/to/image.jpg')
1089 1090 Image(b'RAW_PNG_DATA...')
1090 1091
1091 1092 # Specifying Image(url=...) does not embed the image data,
1092 1093 # it only generates `<img>` tag with a link to the source.
1093 1094 # This will not work in the qtconsole or offline.
1094 1095 Image(url='http://www.google.fr/images/srpr/logo3w.png')
1095 1096
1096 1097 """
1097 1098 if filename is not None:
1098 1099 ext = self._find_ext(filename)
1099 1100 elif url is not None:
1100 1101 ext = self._find_ext(url)
1101 1102 elif data is None:
1102 1103 raise ValueError("No image data found. Expecting filename, url, or data.")
1103 1104 elif isinstance(data, str) and (
1104 1105 data.startswith('http') or _safe_exists(data)
1105 1106 ):
1106 1107 ext = self._find_ext(data)
1107 1108 else:
1108 1109 ext = None
1109 1110
1110 1111 if format is None:
1111 1112 if ext is not None:
1112 1113 if ext == u'jpg' or ext == u'jpeg':
1113 1114 format = self._FMT_JPEG
1114 1115 elif ext == u'png':
1115 1116 format = self._FMT_PNG
1116 1117 elif ext == u'gif':
1117 1118 format = self._FMT_GIF
1118 1119 else:
1119 1120 format = ext.lower()
1120 1121 elif isinstance(data, bytes):
1121 1122 # infer image type from image data header,
1122 1123 # only if format has not been specified.
1123 1124 if data[:2] == _JPEG:
1124 1125 format = self._FMT_JPEG
1125 1126
1126 1127 # failed to detect format, default png
1127 1128 if format is None:
1128 1129 format = self._FMT_PNG
1129 1130
1130 1131 if format.lower() == 'jpg':
1131 1132 # jpg->jpeg
1132 1133 format = self._FMT_JPEG
1133 1134
1134 1135 self.format = format.lower()
1135 1136 self.embed = embed if embed is not None else (url is None)
1136 1137
1137 1138 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
1138 1139 raise ValueError("Cannot embed the '%s' image format" % (self.format))
1139 1140 if self.embed:
1140 1141 self._mimetype = self._MIMETYPES.get(self.format)
1141 1142
1142 1143 self.width = width
1143 1144 self.height = height
1144 1145 self.retina = retina
1145 1146 self.unconfined = unconfined
1146 1147 super(Image, self).__init__(data=data, url=url, filename=filename,
1147 1148 metadata=metadata)
1148 1149
1149 1150 if self.width is None and self.metadata.get('width', {}):
1150 1151 self.width = metadata['width']
1151 1152
1152 1153 if self.height is None and self.metadata.get('height', {}):
1153 1154 self.height = metadata['height']
1154 1155
1155 1156 if retina:
1156 1157 self._retina_shape()
1157 1158
1158 1159
1159 1160 def _retina_shape(self):
1160 1161 """load pixel-doubled width and height from image data"""
1161 1162 if not self.embed:
1162 1163 return
1163 1164 if self.format == self._FMT_PNG:
1164 1165 w, h = _pngxy(self.data)
1165 1166 elif self.format == self._FMT_JPEG:
1166 1167 w, h = _jpegxy(self.data)
1167 1168 elif self.format == self._FMT_GIF:
1168 1169 w, h = _gifxy(self.data)
1169 1170 else:
1170 1171 # retina only supports png
1171 1172 return
1172 1173 self.width = w // 2
1173 1174 self.height = h // 2
1174 1175
1175 1176 def reload(self):
1176 1177 """Reload the raw data from file or URL."""
1177 1178 if self.embed:
1178 1179 super(Image,self).reload()
1179 1180 if self.retina:
1180 1181 self._retina_shape()
1181 1182
1182 1183 def _repr_html_(self):
1183 1184 if not self.embed:
1184 1185 width = height = klass = ''
1185 1186 if self.width:
1186 1187 width = ' width="%d"' % self.width
1187 1188 if self.height:
1188 1189 height = ' height="%d"' % self.height
1189 1190 if self.unconfined:
1190 1191 klass = ' class="unconfined"'
1191 1192 return u'<img src="{url}"{width}{height}{klass}/>'.format(
1192 1193 url=self.url,
1193 1194 width=width,
1194 1195 height=height,
1195 1196 klass=klass,
1196 1197 )
1197 1198
1198 1199 def _repr_mimebundle_(self, include=None, exclude=None):
1199 1200 """Return the image as a mimebundle
1200 1201
1201 1202 Any new mimetype support should be implemented here.
1202 1203 """
1203 1204 if self.embed:
1204 1205 mimetype = self._mimetype
1205 1206 data, metadata = self._data_and_metadata(always_both=True)
1206 1207 if metadata:
1207 1208 metadata = {mimetype: metadata}
1208 1209 return {mimetype: data}, metadata
1209 1210 else:
1210 1211 return {'text/html': self._repr_html_()}
1211 1212
1212 1213 def _data_and_metadata(self, always_both=False):
1213 1214 """shortcut for returning metadata with shape information, if defined"""
1214 1215 b64_data = b2a_base64(self.data).decode('ascii')
1215 1216 md = {}
1216 1217 if self.metadata:
1217 1218 md.update(self.metadata)
1218 1219 if self.width:
1219 1220 md['width'] = self.width
1220 1221 if self.height:
1221 1222 md['height'] = self.height
1222 1223 if self.unconfined:
1223 1224 md['unconfined'] = self.unconfined
1224 1225 if md or always_both:
1225 1226 return b64_data, md
1226 1227 else:
1227 1228 return b64_data
1228 1229
1229 1230 def _repr_png_(self):
1230 1231 if self.embed and self.format == self._FMT_PNG:
1231 1232 return self._data_and_metadata()
1232 1233
1233 1234 def _repr_jpeg_(self):
1234 1235 if self.embed and self.format == self._FMT_JPEG:
1235 1236 return self._data_and_metadata()
1236 1237
1237 1238 def _find_ext(self, s):
1238 1239 return s.split('.')[-1].lower()
1239 1240
1240 1241
1241 1242 class Video(DisplayObject):
1242 1243
1243 1244 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
1244 1245 """Create a video object given raw data or an URL.
1245 1246
1246 1247 When this object is returned by an input cell or passed to the
1247 1248 display function, it will result in the video being displayed
1248 1249 in the frontend.
1249 1250
1250 1251 Parameters
1251 1252 ----------
1252 1253 data : unicode, str or bytes
1253 1254 The raw video data or a URL or filename to load the data from.
1254 1255 Raw data will require passing `embed=True`.
1255 1256 url : unicode
1256 1257 A URL for the video. If you specify `url=`,
1257 1258 the image data will not be embedded.
1258 1259 filename : unicode
1259 1260 Path to a local file containing the video.
1260 1261 Will be interpreted as a local URL unless `embed=True`.
1261 1262 embed : bool
1262 1263 Should the video be embedded using a data URI (True) or be
1263 1264 loaded using a <video> tag (False).
1264 1265
1265 1266 Since videos are large, embedding them should be avoided, if possible.
1266 1267 You must confirm embedding as your intention by passing `embed=True`.
1267 1268
1268 1269 Local files can be displayed with URLs without embedding the content, via::
1269 1270
1270 1271 Video('./video.mp4')
1271 1272
1272 1273 mimetype: unicode
1273 1274 Specify the mimetype for embedded videos.
1274 1275 Default will be guessed from file extension, if available.
1275 1276
1276 1277 Examples
1277 1278 --------
1278 1279
1279 1280 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
1280 1281 Video('path/to/video.mp4')
1281 1282 Video('path/to/video.mp4', embed=True)
1282 1283 Video(b'raw-videodata', embed=True)
1283 1284 """
1284 1285 if url is None and isinstance(data, str) and data.startswith(('http:', 'https:')):
1285 1286 url = data
1286 1287 data = None
1287 1288 elif os.path.exists(data):
1288 1289 filename = data
1289 1290 data = None
1290 1291
1291 1292 if data and not embed:
1292 1293 msg = ''.join([
1293 1294 "To embed videos, you must pass embed=True ",
1294 1295 "(this may make your notebook files huge)\n",
1295 1296 "Consider passing Video(url='...')",
1296 1297 ])
1297 1298 raise ValueError(msg)
1298 1299
1299 1300 self.mimetype = mimetype
1300 1301 self.embed = embed
1301 1302 super(Video, self).__init__(data=data, url=url, filename=filename)
1302 1303
1303 1304 def _repr_html_(self):
1304 1305 # External URLs and potentially local files are not embedded into the
1305 1306 # notebook output.
1306 1307 if not self.embed:
1307 1308 url = self.url if self.url is not None else self.filename
1308 1309 output = """<video src="{0}" controls>
1309 1310 Your browser does not support the <code>video</code> element.
1310 1311 </video>""".format(url)
1311 1312 return output
1312 1313
1313 1314 # Embedded videos are base64-encoded.
1314 1315 mimetype = self.mimetype
1315 1316 if self.filename is not None:
1316 1317 if not mimetype:
1317 1318 mimetype, _ = mimetypes.guess_type(self.filename)
1318 1319
1319 1320 with open(self.filename, 'rb') as f:
1320 1321 video = f.read()
1321 1322 else:
1322 1323 video = self.data
1323 1324 if isinstance(video, str):
1324 1325 # unicode input is already b64-encoded
1325 1326 b64_video = video
1326 1327 else:
1327 1328 b64_video = b2a_base64(video).decode('ascii').rstrip()
1328 1329
1329 1330 output = """<video controls>
1330 1331 <source src="data:{0};base64,{1}" type="{0}">
1331 1332 Your browser does not support the video tag.
1332 1333 </video>""".format(mimetype, b64_video)
1333 1334 return output
1334 1335
1335 1336 def reload(self):
1336 1337 # TODO
1337 1338 pass
1338 1339
1339 1340
1340 1341 def clear_output(wait=False):
1341 1342 """Clear the output of the current cell receiving output.
1342 1343
1343 1344 Parameters
1344 1345 ----------
1345 1346 wait : bool [default: false]
1346 1347 Wait to clear the output until new output is available to replace it."""
1347 1348 from IPython.core.interactiveshell import InteractiveShell
1348 1349 if InteractiveShell.initialized():
1349 1350 InteractiveShell.instance().display_pub.clear_output(wait)
1350 1351 else:
1351 1352 print('\033[2K\r', end='')
1352 1353 sys.stdout.flush()
1353 1354 print('\033[2K\r', end='')
1354 1355 sys.stderr.flush()
1355 1356
1356 1357
1357 1358 @skip_doctest
1358 1359 def set_matplotlib_formats(*formats, **kwargs):
1359 1360 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
1360 1361
1361 1362 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
1362 1363
1363 1364 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
1364 1365
1365 1366 To set this in your config files use the following::
1366 1367
1367 1368 c.InlineBackend.figure_formats = {'png', 'jpeg'}
1368 1369 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
1369 1370
1370 1371 Parameters
1371 1372 ----------
1372 1373 *formats : strs
1373 1374 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
1374 1375 **kwargs :
1375 1376 Keyword args will be relayed to ``figure.canvas.print_figure``.
1376 1377 """
1377 1378 from IPython.core.interactiveshell import InteractiveShell
1378 1379 from IPython.core.pylabtools import select_figure_formats
1379 1380 # build kwargs, starting with InlineBackend config
1380 1381 kw = {}
1381 1382 from ipykernel.pylab.config import InlineBackend
1382 1383 cfg = InlineBackend.instance()
1383 1384 kw.update(cfg.print_figure_kwargs)
1384 1385 kw.update(**kwargs)
1385 1386 shell = InteractiveShell.instance()
1386 1387 select_figure_formats(shell, formats, **kw)
1387 1388
1388 1389 @skip_doctest
1389 1390 def set_matplotlib_close(close=True):
1390 1391 """Set whether the inline backend closes all figures automatically or not.
1391 1392
1392 1393 By default, the inline backend used in the IPython Notebook will close all
1393 1394 matplotlib figures automatically after each cell is run. This means that
1394 1395 plots in different cells won't interfere. Sometimes, you may want to make
1395 1396 a plot in one cell and then refine it in later cells. This can be accomplished
1396 1397 by::
1397 1398
1398 1399 In [1]: set_matplotlib_close(False)
1399 1400
1400 1401 To set this in your config files use the following::
1401 1402
1402 1403 c.InlineBackend.close_figures = False
1403 1404
1404 1405 Parameters
1405 1406 ----------
1406 1407 close : bool
1407 1408 Should all matplotlib figures be automatically closed after each cell is
1408 1409 run?
1409 1410 """
1410 1411 from ipykernel.pylab.config import InlineBackend
1411 1412 cfg = InlineBackend.instance()
1412 1413 cfg.close_figures = close
@@ -1,54 +1,88 b''
1 1 .. _integrating:
2 2
3 3 =====================================
4 4 Integrating your objects with IPython
5 5 =====================================
6 6
7 7 Tab completion
8 8 ==============
9 9
10 10 To change the attributes displayed by tab-completing your object, define a
11 11 ``__dir__(self)`` method for it. For more details, see the documentation of the
12 12 built-in `dir() function <http://docs.python.org/library/functions.html#dir>`_.
13 13
14 14 You can also customise key completions for your objects, e.g. pressing tab after
15 15 ``obj["a``. To do so, define a method ``_ipython_key_completions_()``, which
16 16 returns a list of objects which are possible keys in a subscript expression
17 17 ``obj[key]``.
18 18
19 19 .. versionadded:: 5.0
20 20 Custom key completions
21 21
22 .. _integrating_rich_display:
23
22 24 Rich display
23 25 ============
24 26
25 27 The notebook and the Qt console can display richer representations of objects.
26 28 To use this, you can define any of a number of ``_repr_*_()`` methods. Note that
27 29 these are surrounded by single, not double underscores.
28 30
29 31 Both the notebook and the Qt console can display ``svg``, ``png`` and ``jpeg``
30 32 representations. The notebook can also display ``html``, ``javascript``,
31 and ``latex``. If the methods don't exist, or return ``None``, it falls
32 back to a standard ``repr()``.
33 ``markdown`` and ``latex``. If the methods don't exist, or return ``None``, it
34 falls back to a standard ``repr()``.
33 35
34 36 For example::
35 37
36 38 class Shout(object):
37 39 def __init__(self, text):
38 40 self.text = text
39 41
40 42 def _repr_html_(self):
41 43 return "<h1>" + self.text + "</h1>"
42 44
45 There are also two more powerful display methods:
46
47 .. class:: MyObject
48
49 .. method:: _repr_mimebundle_(include=None, exclude=None)
50
51 Should return a dictionary of multiple formats, keyed by mimetype, or a tuple
52 of two dictionaries: *data, metadata*. If this returns something, other
53 ``_repr_*_`` methods are ignored. The method should take keyword arguments
54 ``include`` and ``exclude``, though it is not required to respect them.
55
56 .. method:: _ipython_display_()
57
58 Displays the object as a side effect; the return value is ignored. If this
59 is defined, all other display methods are ignored.
60
61 Formatters for third-party types
62 --------------------------------
63
64 The user can also register formatters for types without modifying the class::
65
66 from bar import Foo
67
68 def foo_html(obj):
69 return '<marquee>Foo object %s</marquee>' % obj.name
70
71 html_formatter = get_ipython().display_formatter.formatters['text/html']
72 html_formatter.for_type(Foo, foo_html)
73
74 # Or register a type without importing it - this does the same as above:
75 html_formatter.for_type_by_name('bar.Foo', foo_html)
76
43 77 Custom exception tracebacks
44 78 ===========================
45 79
46 80 Rarely, you might want to display a custom traceback when reporting an
47 81 exception. To do this, define the custom traceback using
48 82 `_render_traceback_(self)` method which returns a list of strings, one string
49 83 for each line of the traceback. For example, the `ipyparallel
50 84 <http://ipyparallel.readthedocs.io/>`__ a parallel computing framework for
51 85 IPython, does this to display errors from multiple engines.
52 86
53 87 Please be conservative in using this feature; by replacing the default traceback
54 88 you may hide important information from the user.
General Comments 0
You need to be logged in to leave comments. Login now