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