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