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