##// END OF EJS Templates
Merge pull request #5110 from minrk/bbox_inches...
Brian E. Granger -
r15412:3d365194 merge
parent child Browse files
Show More
@@ -0,0 +1,3
1 * added ``InlineBackend.print_figure_kwargs`` to allow passing keyword arguments
2 to matplotlib's ``Canvas.print_figure``. This can be used to change the value of
3 ``bbox_inches``, which is 'tight' by default, or set the quality of JPEG figures.
@@ -1,772 +1,778
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 Authors:
4 Authors:
5
5
6 * Brian Granger
6 * Brian Granger
7 """
7 """
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2013 The IPython Development Team
10 # Copyright (C) 2013 The IPython Development Team
11 #
11 #
12 # Distributed under the terms of the BSD License. The full license is in
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 # Imports
17 # Imports
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 from __future__ import print_function
20 from __future__ import print_function
21
21
22 import os
22 import os
23 import struct
23 import struct
24
24
25 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
25 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
26 unicode_type)
26 unicode_type)
27 from IPython.testing.skipdoctest import skip_doctest
27 from IPython.testing.skipdoctest import skip_doctest
28 from .displaypub import publish_display_data
28 from .displaypub import publish_display_data
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # utility functions
31 # utility functions
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 def _safe_exists(path):
34 def _safe_exists(path):
35 """Check path, but don't let exceptions raise"""
35 """Check path, but don't let exceptions raise"""
36 try:
36 try:
37 return os.path.exists(path)
37 return os.path.exists(path)
38 except Exception:
38 except Exception:
39 return False
39 return False
40
40
41 def _merge(d1, d2):
41 def _merge(d1, d2):
42 """Like update, but merges sub-dicts instead of clobbering at the top level.
42 """Like update, but merges sub-dicts instead of clobbering at the top level.
43
43
44 Updates d1 in-place
44 Updates d1 in-place
45 """
45 """
46
46
47 if not isinstance(d2, dict) or not isinstance(d1, dict):
47 if not isinstance(d2, dict) or not isinstance(d1, dict):
48 return d2
48 return d2
49 for key, value in d2.items():
49 for key, value in d2.items():
50 d1[key] = _merge(d1.get(key), value)
50 d1[key] = _merge(d1.get(key), value)
51 return d1
51 return d1
52
52
53 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
53 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
54 """internal implementation of all display_foo methods
54 """internal implementation of all display_foo methods
55
55
56 Parameters
56 Parameters
57 ----------
57 ----------
58 mimetype : str
58 mimetype : str
59 The mimetype to be published (e.g. 'image/png')
59 The mimetype to be published (e.g. 'image/png')
60 objs : tuple of objects
60 objs : tuple of objects
61 The Python objects to display, or if raw=True raw text data to
61 The Python objects to display, or if raw=True raw text data to
62 display.
62 display.
63 raw : bool
63 raw : bool
64 Are the data objects raw data or Python objects that need to be
64 Are the data objects raw data or Python objects that need to be
65 formatted before display? [default: False]
65 formatted before display? [default: False]
66 metadata : dict (optional)
66 metadata : dict (optional)
67 Metadata to be associated with the specific mimetype output.
67 Metadata to be associated with the specific mimetype output.
68 """
68 """
69 if metadata:
69 if metadata:
70 metadata = {mimetype: metadata}
70 metadata = {mimetype: metadata}
71 if raw:
71 if raw:
72 # turn list of pngdata into list of { 'image/png': pngdata }
72 # turn list of pngdata into list of { 'image/png': pngdata }
73 objs = [ {mimetype: obj} for obj in objs ]
73 objs = [ {mimetype: obj} for obj in objs ]
74 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
74 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
75
75
76 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
77 # Main functions
77 # Main functions
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79
79
80 def display(*objs, **kwargs):
80 def display(*objs, **kwargs):
81 """Display a Python object in all frontends.
81 """Display a Python object in all frontends.
82
82
83 By default all representations will be computed and sent to the frontends.
83 By default all representations will be computed and sent to the frontends.
84 Frontends can decide which representation is used and how.
84 Frontends can decide which representation is used and how.
85
85
86 Parameters
86 Parameters
87 ----------
87 ----------
88 objs : tuple of objects
88 objs : tuple of objects
89 The Python objects to display.
89 The Python objects to display.
90 raw : bool, optional
90 raw : bool, optional
91 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
91 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
92 or Python objects that need to be formatted before display? [default: False]
92 or Python objects that need to be formatted before display? [default: False]
93 include : list or tuple, optional
93 include : list or tuple, optional
94 A list of format type strings (MIME types) to include in the
94 A list of format type strings (MIME types) to include in the
95 format data dict. If this is set *only* the format types included
95 format data dict. If this is set *only* the format types included
96 in this list will be computed.
96 in this list will be computed.
97 exclude : list or tuple, optional
97 exclude : list or tuple, optional
98 A list of format type strings (MIME types) to exclude in the format
98 A list of format type strings (MIME types) to exclude in the format
99 data dict. If this is set all format types will be computed,
99 data dict. If this is set all format types will be computed,
100 except for those included in this argument.
100 except for those included in this argument.
101 metadata : dict, optional
101 metadata : dict, optional
102 A dictionary of metadata to associate with the output.
102 A dictionary of metadata to associate with the output.
103 mime-type keys in this dictionary will be associated with the individual
103 mime-type keys in this dictionary will be associated with the individual
104 representation formats, if they exist.
104 representation formats, if they exist.
105 """
105 """
106 raw = kwargs.get('raw', False)
106 raw = kwargs.get('raw', False)
107 include = kwargs.get('include')
107 include = kwargs.get('include')
108 exclude = kwargs.get('exclude')
108 exclude = kwargs.get('exclude')
109 metadata = kwargs.get('metadata')
109 metadata = kwargs.get('metadata')
110
110
111 from IPython.core.interactiveshell import InteractiveShell
111 from IPython.core.interactiveshell import InteractiveShell
112
112
113 if not raw:
113 if not raw:
114 format = InteractiveShell.instance().display_formatter.format
114 format = InteractiveShell.instance().display_formatter.format
115
115
116 for obj in objs:
116 for obj in objs:
117
117
118 # If _ipython_display_ is defined, use that to display this object.
118 # If _ipython_display_ is defined, use that to display this object.
119 display_method = getattr(obj, '_ipython_display_', None)
119 display_method = getattr(obj, '_ipython_display_', None)
120 if display_method is not None:
120 if display_method is not None:
121 try:
121 try:
122 display_method(**kwargs)
122 display_method(**kwargs)
123 except NotImplementedError:
123 except NotImplementedError:
124 pass
124 pass
125 else:
125 else:
126 continue
126 continue
127 if raw:
127 if raw:
128 publish_display_data('display', obj, metadata)
128 publish_display_data('display', obj, metadata)
129 else:
129 else:
130 format_dict, md_dict = format(obj, include=include, exclude=exclude)
130 format_dict, md_dict = format(obj, include=include, exclude=exclude)
131 if metadata:
131 if metadata:
132 # kwarg-specified metadata gets precedence
132 # kwarg-specified metadata gets precedence
133 _merge(md_dict, metadata)
133 _merge(md_dict, metadata)
134 publish_display_data('display', format_dict, md_dict)
134 publish_display_data('display', format_dict, md_dict)
135
135
136
136
137 def display_pretty(*objs, **kwargs):
137 def display_pretty(*objs, **kwargs):
138 """Display the pretty (default) representation of an object.
138 """Display the pretty (default) representation of an object.
139
139
140 Parameters
140 Parameters
141 ----------
141 ----------
142 objs : tuple of objects
142 objs : tuple of objects
143 The Python objects to display, or if raw=True raw text data to
143 The Python objects to display, or if raw=True raw text data to
144 display.
144 display.
145 raw : bool
145 raw : bool
146 Are the data objects raw data or Python objects that need to be
146 Are the data objects raw data or Python objects that need to be
147 formatted before display? [default: False]
147 formatted before display? [default: False]
148 metadata : dict (optional)
148 metadata : dict (optional)
149 Metadata to be associated with the specific mimetype output.
149 Metadata to be associated with the specific mimetype output.
150 """
150 """
151 _display_mimetype('text/plain', objs, **kwargs)
151 _display_mimetype('text/plain', objs, **kwargs)
152
152
153
153
154 def display_html(*objs, **kwargs):
154 def display_html(*objs, **kwargs):
155 """Display the HTML representation of an object.
155 """Display the HTML representation of an object.
156
156
157 Parameters
157 Parameters
158 ----------
158 ----------
159 objs : tuple of objects
159 objs : tuple of objects
160 The Python objects to display, or if raw=True raw HTML data to
160 The Python objects to display, or if raw=True raw HTML data to
161 display.
161 display.
162 raw : bool
162 raw : bool
163 Are the data objects raw data or Python objects that need to be
163 Are the data objects raw data or Python objects that need to be
164 formatted before display? [default: False]
164 formatted before display? [default: False]
165 metadata : dict (optional)
165 metadata : dict (optional)
166 Metadata to be associated with the specific mimetype output.
166 Metadata to be associated with the specific mimetype output.
167 """
167 """
168 _display_mimetype('text/html', objs, **kwargs)
168 _display_mimetype('text/html', objs, **kwargs)
169
169
170
170
171 def display_svg(*objs, **kwargs):
171 def display_svg(*objs, **kwargs):
172 """Display the SVG representation of an object.
172 """Display the SVG representation of an object.
173
173
174 Parameters
174 Parameters
175 ----------
175 ----------
176 objs : tuple of objects
176 objs : tuple of objects
177 The Python objects to display, or if raw=True raw svg data to
177 The Python objects to display, or if raw=True raw svg data to
178 display.
178 display.
179 raw : bool
179 raw : bool
180 Are the data objects raw data or Python objects that need to be
180 Are the data objects raw data or Python objects that need to be
181 formatted before display? [default: False]
181 formatted before display? [default: False]
182 metadata : dict (optional)
182 metadata : dict (optional)
183 Metadata to be associated with the specific mimetype output.
183 Metadata to be associated with the specific mimetype output.
184 """
184 """
185 _display_mimetype('image/svg+xml', objs, **kwargs)
185 _display_mimetype('image/svg+xml', objs, **kwargs)
186
186
187
187
188 def display_png(*objs, **kwargs):
188 def display_png(*objs, **kwargs):
189 """Display the PNG representation of an object.
189 """Display the PNG representation of an object.
190
190
191 Parameters
191 Parameters
192 ----------
192 ----------
193 objs : tuple of objects
193 objs : tuple of objects
194 The Python objects to display, or if raw=True raw png data to
194 The Python objects to display, or if raw=True raw png data to
195 display.
195 display.
196 raw : bool
196 raw : bool
197 Are the data objects raw data or Python objects that need to be
197 Are the data objects raw data or Python objects that need to be
198 formatted before display? [default: False]
198 formatted before display? [default: False]
199 metadata : dict (optional)
199 metadata : dict (optional)
200 Metadata to be associated with the specific mimetype output.
200 Metadata to be associated with the specific mimetype output.
201 """
201 """
202 _display_mimetype('image/png', objs, **kwargs)
202 _display_mimetype('image/png', objs, **kwargs)
203
203
204
204
205 def display_jpeg(*objs, **kwargs):
205 def display_jpeg(*objs, **kwargs):
206 """Display the JPEG representation of an object.
206 """Display the JPEG representation of an object.
207
207
208 Parameters
208 Parameters
209 ----------
209 ----------
210 objs : tuple of objects
210 objs : tuple of objects
211 The Python objects to display, or if raw=True raw JPEG data to
211 The Python objects to display, or if raw=True raw JPEG data to
212 display.
212 display.
213 raw : bool
213 raw : bool
214 Are the data objects raw data or Python objects that need to be
214 Are the data objects raw data or Python objects that need to be
215 formatted before display? [default: False]
215 formatted before display? [default: False]
216 metadata : dict (optional)
216 metadata : dict (optional)
217 Metadata to be associated with the specific mimetype output.
217 Metadata to be associated with the specific mimetype output.
218 """
218 """
219 _display_mimetype('image/jpeg', objs, **kwargs)
219 _display_mimetype('image/jpeg', objs, **kwargs)
220
220
221
221
222 def display_latex(*objs, **kwargs):
222 def display_latex(*objs, **kwargs):
223 """Display the LaTeX representation of an object.
223 """Display the LaTeX representation of an object.
224
224
225 Parameters
225 Parameters
226 ----------
226 ----------
227 objs : tuple of objects
227 objs : tuple of objects
228 The Python objects to display, or if raw=True raw latex data to
228 The Python objects to display, or if raw=True raw latex data to
229 display.
229 display.
230 raw : bool
230 raw : bool
231 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
232 formatted before display? [default: False]
232 formatted before display? [default: False]
233 metadata : dict (optional)
233 metadata : dict (optional)
234 Metadata to be associated with the specific mimetype output.
234 Metadata to be associated with the specific mimetype output.
235 """
235 """
236 _display_mimetype('text/latex', objs, **kwargs)
236 _display_mimetype('text/latex', objs, **kwargs)
237
237
238
238
239 def display_json(*objs, **kwargs):
239 def display_json(*objs, **kwargs):
240 """Display the JSON representation of an object.
240 """Display the JSON representation of an object.
241
241
242 Note that not many frontends support displaying JSON.
242 Note that not many frontends support displaying JSON.
243
243
244 Parameters
244 Parameters
245 ----------
245 ----------
246 objs : tuple of objects
246 objs : tuple of objects
247 The Python objects to display, or if raw=True raw json data to
247 The Python objects to display, or if raw=True raw json data to
248 display.
248 display.
249 raw : bool
249 raw : bool
250 Are the data objects raw data or Python objects that need to be
250 Are the data objects raw data or Python objects that need to be
251 formatted before display? [default: False]
251 formatted before display? [default: False]
252 metadata : dict (optional)
252 metadata : dict (optional)
253 Metadata to be associated with the specific mimetype output.
253 Metadata to be associated with the specific mimetype output.
254 """
254 """
255 _display_mimetype('application/json', objs, **kwargs)
255 _display_mimetype('application/json', objs, **kwargs)
256
256
257
257
258 def display_javascript(*objs, **kwargs):
258 def display_javascript(*objs, **kwargs):
259 """Display the Javascript representation of an object.
259 """Display the Javascript representation of an object.
260
260
261 Parameters
261 Parameters
262 ----------
262 ----------
263 objs : tuple of objects
263 objs : tuple of objects
264 The Python objects to display, or if raw=True raw javascript data to
264 The Python objects to display, or if raw=True raw javascript data to
265 display.
265 display.
266 raw : bool
266 raw : bool
267 Are the data objects raw data or Python objects that need to be
267 Are the data objects raw data or Python objects that need to be
268 formatted before display? [default: False]
268 formatted before display? [default: False]
269 metadata : dict (optional)
269 metadata : dict (optional)
270 Metadata to be associated with the specific mimetype output.
270 Metadata to be associated with the specific mimetype output.
271 """
271 """
272 _display_mimetype('application/javascript', objs, **kwargs)
272 _display_mimetype('application/javascript', objs, **kwargs)
273
273
274
274
275 def display_pdf(*objs, **kwargs):
275 def display_pdf(*objs, **kwargs):
276 """Display the PDF representation of an object.
276 """Display the PDF representation of an object.
277
277
278 Parameters
278 Parameters
279 ----------
279 ----------
280 objs : tuple of objects
280 objs : tuple of objects
281 The Python objects to display, or if raw=True raw javascript data to
281 The Python objects to display, or if raw=True raw javascript data to
282 display.
282 display.
283 raw : bool
283 raw : bool
284 Are the data objects raw data or Python objects that need to be
284 Are the data objects raw data or Python objects that need to be
285 formatted before display? [default: False]
285 formatted before display? [default: False]
286 metadata : dict (optional)
286 metadata : dict (optional)
287 Metadata to be associated with the specific mimetype output.
287 Metadata to be associated with the specific mimetype output.
288 """
288 """
289 _display_mimetype('application/pdf', objs, **kwargs)
289 _display_mimetype('application/pdf', objs, **kwargs)
290
290
291
291
292 #-----------------------------------------------------------------------------
292 #-----------------------------------------------------------------------------
293 # Smart classes
293 # Smart classes
294 #-----------------------------------------------------------------------------
294 #-----------------------------------------------------------------------------
295
295
296
296
297 class DisplayObject(object):
297 class DisplayObject(object):
298 """An object that wraps data to be displayed."""
298 """An object that wraps data to be displayed."""
299
299
300 _read_flags = 'r'
300 _read_flags = 'r'
301
301
302 def __init__(self, data=None, url=None, filename=None):
302 def __init__(self, data=None, url=None, filename=None):
303 """Create a display object given raw data.
303 """Create a display object given raw data.
304
304
305 When this object is returned by an expression or passed to the
305 When this object is returned by an expression or passed to the
306 display function, it will result in the data being displayed
306 display function, it will result in the data being displayed
307 in the frontend. The MIME type of the data should match the
307 in the frontend. The MIME type of the data should match the
308 subclasses used, so the Png subclass should be used for 'image/png'
308 subclasses used, so the Png subclass should be used for 'image/png'
309 data. If the data is a URL, the data will first be downloaded
309 data. If the data is a URL, the data will first be downloaded
310 and then displayed. If
310 and then displayed. If
311
311
312 Parameters
312 Parameters
313 ----------
313 ----------
314 data : unicode, str or bytes
314 data : unicode, str or bytes
315 The raw data or a URL or file to load the data from
315 The raw data or a URL or file to load the data from
316 url : unicode
316 url : unicode
317 A URL to download the data from.
317 A URL to download the data from.
318 filename : unicode
318 filename : unicode
319 Path to a local file to load the data from.
319 Path to a local file to load the data from.
320 """
320 """
321 if data is not None and isinstance(data, string_types):
321 if data is not None and isinstance(data, string_types):
322 if data.startswith('http') and url is None:
322 if data.startswith('http') and url is None:
323 url = data
323 url = data
324 filename = None
324 filename = None
325 data = None
325 data = None
326 elif _safe_exists(data) and filename is None:
326 elif _safe_exists(data) and filename is None:
327 url = None
327 url = None
328 filename = data
328 filename = data
329 data = None
329 data = None
330
330
331 self.data = data
331 self.data = data
332 self.url = url
332 self.url = url
333 self.filename = None if filename is None else unicode_type(filename)
333 self.filename = None if filename is None else unicode_type(filename)
334
334
335 self.reload()
335 self.reload()
336 self._check_data()
336 self._check_data()
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 reload(self):
342 def reload(self):
343 """Reload the raw data from file or URL."""
343 """Reload the raw data from file or URL."""
344 if self.filename is not None:
344 if self.filename is not None:
345 with open(self.filename, self._read_flags) as f:
345 with open(self.filename, self._read_flags) as f:
346 self.data = f.read()
346 self.data = f.read()
347 elif self.url is not None:
347 elif self.url is not None:
348 try:
348 try:
349 try:
349 try:
350 from urllib.request import urlopen # Py3
350 from urllib.request import urlopen # Py3
351 except ImportError:
351 except ImportError:
352 from urllib2 import urlopen
352 from urllib2 import urlopen
353 response = urlopen(self.url)
353 response = urlopen(self.url)
354 self.data = response.read()
354 self.data = response.read()
355 # extract encoding from header, if there is one:
355 # extract encoding from header, if there is one:
356 encoding = None
356 encoding = None
357 for sub in response.headers['content-type'].split(';'):
357 for sub in response.headers['content-type'].split(';'):
358 sub = sub.strip()
358 sub = sub.strip()
359 if sub.startswith('charset'):
359 if sub.startswith('charset'):
360 encoding = sub.split('=')[-1].strip()
360 encoding = sub.split('=')[-1].strip()
361 break
361 break
362 # decode data, if an encoding was specified
362 # decode data, if an encoding was specified
363 if encoding:
363 if encoding:
364 self.data = self.data.decode(encoding, 'replace')
364 self.data = self.data.decode(encoding, 'replace')
365 except:
365 except:
366 self.data = None
366 self.data = None
367
367
368 class TextDisplayObject(DisplayObject):
368 class TextDisplayObject(DisplayObject):
369 """Validate that display data is text"""
369 """Validate that display data is text"""
370 def _check_data(self):
370 def _check_data(self):
371 if self.data is not None and not isinstance(self.data, string_types):
371 if self.data is not None and not isinstance(self.data, string_types):
372 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
372 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
373
373
374 class Pretty(TextDisplayObject):
374 class Pretty(TextDisplayObject):
375
375
376 def _repr_pretty_(self):
376 def _repr_pretty_(self):
377 return self.data
377 return self.data
378
378
379
379
380 class HTML(TextDisplayObject):
380 class HTML(TextDisplayObject):
381
381
382 def _repr_html_(self):
382 def _repr_html_(self):
383 return self.data
383 return self.data
384
384
385 def __html__(self):
385 def __html__(self):
386 """
386 """
387 This method exists to inform other HTML-using modules (e.g. Markupsafe,
387 This method exists to inform other HTML-using modules (e.g. Markupsafe,
388 htmltag, etc) that this object is HTML and does not need things like
388 htmltag, etc) that this object is HTML and does not need things like
389 special characters (<>&) escaped.
389 special characters (<>&) escaped.
390 """
390 """
391 return self._repr_html_()
391 return self._repr_html_()
392
392
393
393
394 class Math(TextDisplayObject):
394 class Math(TextDisplayObject):
395
395
396 def _repr_latex_(self):
396 def _repr_latex_(self):
397 s = self.data.strip('$')
397 s = self.data.strip('$')
398 return "$$%s$$" % s
398 return "$$%s$$" % s
399
399
400
400
401 class Latex(TextDisplayObject):
401 class Latex(TextDisplayObject):
402
402
403 def _repr_latex_(self):
403 def _repr_latex_(self):
404 return self.data
404 return self.data
405
405
406
406
407 class SVG(DisplayObject):
407 class SVG(DisplayObject):
408
408
409 # wrap data in a property, which extracts the <svg> tag, discarding
409 # wrap data in a property, which extracts the <svg> tag, discarding
410 # document headers
410 # document headers
411 _data = None
411 _data = None
412
412
413 @property
413 @property
414 def data(self):
414 def data(self):
415 return self._data
415 return self._data
416
416
417 @data.setter
417 @data.setter
418 def data(self, svg):
418 def data(self, svg):
419 if svg is None:
419 if svg is None:
420 self._data = None
420 self._data = None
421 return
421 return
422 # parse into dom object
422 # parse into dom object
423 from xml.dom import minidom
423 from xml.dom import minidom
424 svg = cast_bytes_py2(svg)
424 svg = cast_bytes_py2(svg)
425 x = minidom.parseString(svg)
425 x = minidom.parseString(svg)
426 # get svg tag (should be 1)
426 # get svg tag (should be 1)
427 found_svg = x.getElementsByTagName('svg')
427 found_svg = x.getElementsByTagName('svg')
428 if found_svg:
428 if found_svg:
429 svg = found_svg[0].toxml()
429 svg = found_svg[0].toxml()
430 else:
430 else:
431 # fallback on the input, trust the user
431 # fallback on the input, trust the user
432 # but this is probably an error.
432 # but this is probably an error.
433 pass
433 pass
434 svg = cast_unicode(svg)
434 svg = cast_unicode(svg)
435 self._data = svg
435 self._data = svg
436
436
437 def _repr_svg_(self):
437 def _repr_svg_(self):
438 return self.data
438 return self.data
439
439
440
440
441 class JSON(TextDisplayObject):
441 class JSON(TextDisplayObject):
442
442
443 def _repr_json_(self):
443 def _repr_json_(self):
444 return self.data
444 return self.data
445
445
446 css_t = """$("head").append($("<link/>").attr({
446 css_t = """$("head").append($("<link/>").attr({
447 rel: "stylesheet",
447 rel: "stylesheet",
448 type: "text/css",
448 type: "text/css",
449 href: "%s"
449 href: "%s"
450 }));
450 }));
451 """
451 """
452
452
453 lib_t1 = """$.getScript("%s", function () {
453 lib_t1 = """$.getScript("%s", function () {
454 """
454 """
455 lib_t2 = """});
455 lib_t2 = """});
456 """
456 """
457
457
458 class Javascript(TextDisplayObject):
458 class Javascript(TextDisplayObject):
459
459
460 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
460 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
461 """Create a Javascript display object given raw data.
461 """Create a Javascript display object given raw data.
462
462
463 When this object is returned by an expression or passed to the
463 When this object is returned by an expression or passed to the
464 display function, it will result in the data being displayed
464 display function, it will result in the data being displayed
465 in the frontend. If the data is a URL, the data will first be
465 in the frontend. If the data is a URL, the data will first be
466 downloaded and then displayed.
466 downloaded and then displayed.
467
467
468 In the Notebook, the containing element will be available as `element`,
468 In the Notebook, the containing element will be available as `element`,
469 and jQuery will be available. The output area starts hidden, so if
469 and jQuery will be available. The output area starts hidden, so if
470 the js appends content to `element` that should be visible, then
470 the js appends content to `element` that should be visible, then
471 it must call `container.show()` to unhide the area.
471 it must call `container.show()` to unhide the area.
472
472
473 Parameters
473 Parameters
474 ----------
474 ----------
475 data : unicode, str or bytes
475 data : unicode, str or bytes
476 The Javascript source code or a URL to download it from.
476 The Javascript source code or a URL to download it from.
477 url : unicode
477 url : unicode
478 A URL to download the data from.
478 A URL to download the data from.
479 filename : unicode
479 filename : unicode
480 Path to a local file to load the data from.
480 Path to a local file to load the data from.
481 lib : list or str
481 lib : list or str
482 A sequence of Javascript library URLs to load asynchronously before
482 A sequence of Javascript library URLs to load asynchronously before
483 running the source code. The full URLs of the libraries should
483 running the source code. The full URLs of the libraries should
484 be given. A single Javascript library URL can also be given as a
484 be given. A single Javascript library URL can also be given as a
485 string.
485 string.
486 css: : list or str
486 css: : list or str
487 A sequence of css files to load before running the source code.
487 A sequence of css files to load before running the source code.
488 The full URLs of the css files should be given. A single css URL
488 The full URLs of the css files should be given. A single css URL
489 can also be given as a string.
489 can also be given as a string.
490 """
490 """
491 if isinstance(lib, string_types):
491 if isinstance(lib, string_types):
492 lib = [lib]
492 lib = [lib]
493 elif lib is None:
493 elif lib is None:
494 lib = []
494 lib = []
495 if isinstance(css, string_types):
495 if isinstance(css, string_types):
496 css = [css]
496 css = [css]
497 elif css is None:
497 elif css is None:
498 css = []
498 css = []
499 if not isinstance(lib, (list,tuple)):
499 if not isinstance(lib, (list,tuple)):
500 raise TypeError('expected sequence, got: %r' % lib)
500 raise TypeError('expected sequence, got: %r' % lib)
501 if not isinstance(css, (list,tuple)):
501 if not isinstance(css, (list,tuple)):
502 raise TypeError('expected sequence, got: %r' % css)
502 raise TypeError('expected sequence, got: %r' % css)
503 self.lib = lib
503 self.lib = lib
504 self.css = css
504 self.css = css
505 super(Javascript, self).__init__(data=data, url=url, filename=filename)
505 super(Javascript, self).__init__(data=data, url=url, filename=filename)
506
506
507 def _repr_javascript_(self):
507 def _repr_javascript_(self):
508 r = ''
508 r = ''
509 for c in self.css:
509 for c in self.css:
510 r += css_t % c
510 r += css_t % c
511 for l in self.lib:
511 for l in self.lib:
512 r += lib_t1 % l
512 r += lib_t1 % l
513 r += self.data
513 r += self.data
514 r += lib_t2*len(self.lib)
514 r += lib_t2*len(self.lib)
515 return r
515 return r
516
516
517 # constants for identifying png/jpeg data
517 # constants for identifying png/jpeg data
518 _PNG = b'\x89PNG\r\n\x1a\n'
518 _PNG = b'\x89PNG\r\n\x1a\n'
519 _JPEG = b'\xff\xd8'
519 _JPEG = b'\xff\xd8'
520
520
521 def _pngxy(data):
521 def _pngxy(data):
522 """read the (width, height) from a PNG header"""
522 """read the (width, height) from a PNG header"""
523 ihdr = data.index(b'IHDR')
523 ihdr = data.index(b'IHDR')
524 # next 8 bytes are width/height
524 # next 8 bytes are width/height
525 w4h4 = data[ihdr+4:ihdr+12]
525 w4h4 = data[ihdr+4:ihdr+12]
526 return struct.unpack('>ii', w4h4)
526 return struct.unpack('>ii', w4h4)
527
527
528 def _jpegxy(data):
528 def _jpegxy(data):
529 """read the (width, height) from a JPEG header"""
529 """read the (width, height) from a JPEG header"""
530 # adapted from http://www.64lines.com/jpeg-width-height
530 # adapted from http://www.64lines.com/jpeg-width-height
531
531
532 idx = 4
532 idx = 4
533 while True:
533 while True:
534 block_size = struct.unpack('>H', data[idx:idx+2])[0]
534 block_size = struct.unpack('>H', data[idx:idx+2])[0]
535 idx = idx + block_size
535 idx = idx + block_size
536 if data[idx:idx+2] == b'\xFF\xC0':
536 if data[idx:idx+2] == b'\xFF\xC0':
537 # found Start of Frame
537 # found Start of Frame
538 iSOF = idx
538 iSOF = idx
539 break
539 break
540 else:
540 else:
541 # read another block
541 # read another block
542 idx += 2
542 idx += 2
543
543
544 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
544 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
545 return w, h
545 return w, h
546
546
547 class Image(DisplayObject):
547 class Image(DisplayObject):
548
548
549 _read_flags = 'rb'
549 _read_flags = 'rb'
550 _FMT_JPEG = u'jpeg'
550 _FMT_JPEG = u'jpeg'
551 _FMT_PNG = u'png'
551 _FMT_PNG = u'png'
552 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
552 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
553
553
554 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
554 def __init__(self, data=None, url=None, filename=None, format=u'png', embed=None, width=None, height=None, retina=False):
555 """Create a PNG/JPEG image object given raw data.
555 """Create a PNG/JPEG image object given raw data.
556
556
557 When this object is returned by an input cell or passed to the
557 When this object is returned by an input cell or passed to the
558 display function, it will result in the image being displayed
558 display function, it will result in the image being displayed
559 in the frontend.
559 in the frontend.
560
560
561 Parameters
561 Parameters
562 ----------
562 ----------
563 data : unicode, str or bytes
563 data : unicode, str or bytes
564 The raw image data or a URL or filename to load the data from.
564 The raw image data or a URL or filename to load the data from.
565 This always results in embedded image data.
565 This always results in embedded image data.
566 url : unicode
566 url : unicode
567 A URL to download the data from. If you specify `url=`,
567 A URL to download the data from. If you specify `url=`,
568 the image data will not be embedded unless you also specify `embed=True`.
568 the image data will not be embedded unless you also specify `embed=True`.
569 filename : unicode
569 filename : unicode
570 Path to a local file to load the data from.
570 Path to a local file to load the data from.
571 Images from a file are always embedded.
571 Images from a file are always embedded.
572 format : unicode
572 format : unicode
573 The format of the image data (png/jpeg/jpg). If a filename or URL is given
573 The format of the image data (png/jpeg/jpg). If a filename or URL is given
574 for format will be inferred from the filename extension.
574 for format will be inferred from the filename extension.
575 embed : bool
575 embed : bool
576 Should the image data be embedded using a data URI (True) or be
576 Should the image data be embedded using a data URI (True) or be
577 loaded using an <img> tag. Set this to True if you want the image
577 loaded using an <img> tag. Set this to True if you want the image
578 to be viewable later with no internet connection in the notebook.
578 to be viewable later with no internet connection in the notebook.
579
579
580 Default is `True`, unless the keyword argument `url` is set, then
580 Default is `True`, unless the keyword argument `url` is set, then
581 default value is `False`.
581 default value is `False`.
582
582
583 Note that QtConsole is not able to display images if `embed` is set to `False`
583 Note that QtConsole is not able to display images if `embed` is set to `False`
584 width : int
584 width : int
585 Width to which to constrain the image in html
585 Width to which to constrain the image in html
586 height : int
586 height : int
587 Height to which to constrain the image in html
587 Height to which to constrain the image in html
588 retina : bool
588 retina : bool
589 Automatically set the width and height to half of the measured
589 Automatically set the width and height to half of the measured
590 width and height.
590 width and height.
591 This only works for embedded images because it reads the width/height
591 This only works for embedded images because it reads the width/height
592 from image data.
592 from image data.
593 For non-embedded images, you can just set the desired display width
593 For non-embedded images, you can just set the desired display width
594 and height directly.
594 and height directly.
595
595
596 Examples
596 Examples
597 --------
597 --------
598 # embedded image data, works in qtconsole and notebook
598 # embedded image data, works in qtconsole and notebook
599 # when passed positionally, the first arg can be any of raw image data,
599 # when passed positionally, the first arg can be any of raw image data,
600 # a URL, or a filename from which to load image data.
600 # a URL, or a filename from which to load image data.
601 # The result is always embedding image data for inline images.
601 # The result is always embedding image data for inline images.
602 Image('http://www.google.fr/images/srpr/logo3w.png')
602 Image('http://www.google.fr/images/srpr/logo3w.png')
603 Image('/path/to/image.jpg')
603 Image('/path/to/image.jpg')
604 Image(b'RAW_PNG_DATA...')
604 Image(b'RAW_PNG_DATA...')
605
605
606 # Specifying Image(url=...) does not embed the image data,
606 # Specifying Image(url=...) does not embed the image data,
607 # it only generates `<img>` tag with a link to the source.
607 # it only generates `<img>` tag with a link to the source.
608 # This will not work in the qtconsole or offline.
608 # This will not work in the qtconsole or offline.
609 Image(url='http://www.google.fr/images/srpr/logo3w.png')
609 Image(url='http://www.google.fr/images/srpr/logo3w.png')
610
610
611 """
611 """
612 if filename is not None:
612 if filename is not None:
613 ext = self._find_ext(filename)
613 ext = self._find_ext(filename)
614 elif url is not None:
614 elif url is not None:
615 ext = self._find_ext(url)
615 ext = self._find_ext(url)
616 elif data is None:
616 elif data is None:
617 raise ValueError("No image data found. Expecting filename, url, or data.")
617 raise ValueError("No image data found. Expecting filename, url, or data.")
618 elif isinstance(data, string_types) and (
618 elif isinstance(data, string_types) and (
619 data.startswith('http') or _safe_exists(data)
619 data.startswith('http') or _safe_exists(data)
620 ):
620 ):
621 ext = self._find_ext(data)
621 ext = self._find_ext(data)
622 else:
622 else:
623 ext = None
623 ext = None
624
624
625 if ext is not None:
625 if ext is not None:
626 format = ext.lower()
626 format = ext.lower()
627 if ext == u'jpg' or ext == u'jpeg':
627 if ext == u'jpg' or ext == u'jpeg':
628 format = self._FMT_JPEG
628 format = self._FMT_JPEG
629 if ext == u'png':
629 if ext == u'png':
630 format = self._FMT_PNG
630 format = self._FMT_PNG
631 elif isinstance(data, bytes) and format == 'png':
631 elif isinstance(data, bytes) and format == 'png':
632 # infer image type from image data header,
632 # infer image type from image data header,
633 # only if format might not have been specified.
633 # only if format might not have been specified.
634 if data[:2] == _JPEG:
634 if data[:2] == _JPEG:
635 format = 'jpeg'
635 format = 'jpeg'
636
636
637 self.format = unicode_type(format).lower()
637 self.format = unicode_type(format).lower()
638 self.embed = embed if embed is not None else (url is None)
638 self.embed = embed if embed is not None else (url is None)
639
639
640 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
640 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
641 raise ValueError("Cannot embed the '%s' image format" % (self.format))
641 raise ValueError("Cannot embed the '%s' image format" % (self.format))
642 self.width = width
642 self.width = width
643 self.height = height
643 self.height = height
644 self.retina = retina
644 self.retina = retina
645 super(Image, self).__init__(data=data, url=url, filename=filename)
645 super(Image, self).__init__(data=data, url=url, filename=filename)
646
646
647 if retina:
647 if retina:
648 self._retina_shape()
648 self._retina_shape()
649
649
650 def _retina_shape(self):
650 def _retina_shape(self):
651 """load pixel-doubled width and height from image data"""
651 """load pixel-doubled width and height from image data"""
652 if not self.embed:
652 if not self.embed:
653 return
653 return
654 if self.format == 'png':
654 if self.format == 'png':
655 w, h = _pngxy(self.data)
655 w, h = _pngxy(self.data)
656 elif self.format == 'jpeg':
656 elif self.format == 'jpeg':
657 w, h = _jpegxy(self.data)
657 w, h = _jpegxy(self.data)
658 else:
658 else:
659 # retina only supports png
659 # retina only supports png
660 return
660 return
661 self.width = w // 2
661 self.width = w // 2
662 self.height = h // 2
662 self.height = h // 2
663
663
664 def reload(self):
664 def reload(self):
665 """Reload the raw data from file or URL."""
665 """Reload the raw data from file or URL."""
666 if self.embed:
666 if self.embed:
667 super(Image,self).reload()
667 super(Image,self).reload()
668 if self.retina:
668 if self.retina:
669 self._retina_shape()
669 self._retina_shape()
670
670
671 def _repr_html_(self):
671 def _repr_html_(self):
672 if not self.embed:
672 if not self.embed:
673 width = height = ''
673 width = height = ''
674 if self.width:
674 if self.width:
675 width = ' width="%d"' % self.width
675 width = ' width="%d"' % self.width
676 if self.height:
676 if self.height:
677 height = ' height="%d"' % self.height
677 height = ' height="%d"' % self.height
678 return u'<img src="%s"%s%s/>' % (self.url, width, height)
678 return u'<img src="%s"%s%s/>' % (self.url, width, height)
679
679
680 def _data_and_metadata(self):
680 def _data_and_metadata(self):
681 """shortcut for returning metadata with shape information, if defined"""
681 """shortcut for returning metadata with shape information, if defined"""
682 md = {}
682 md = {}
683 if self.width:
683 if self.width:
684 md['width'] = self.width
684 md['width'] = self.width
685 if self.height:
685 if self.height:
686 md['height'] = self.height
686 md['height'] = self.height
687 if md:
687 if md:
688 return self.data, md
688 return self.data, md
689 else:
689 else:
690 return self.data
690 return self.data
691
691
692 def _repr_png_(self):
692 def _repr_png_(self):
693 if self.embed and self.format == u'png':
693 if self.embed and self.format == u'png':
694 return self._data_and_metadata()
694 return self._data_and_metadata()
695
695
696 def _repr_jpeg_(self):
696 def _repr_jpeg_(self):
697 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
697 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
698 return self._data_and_metadata()
698 return self._data_and_metadata()
699
699
700 def _find_ext(self, s):
700 def _find_ext(self, s):
701 return unicode_type(s.split('.')[-1].lower())
701 return unicode_type(s.split('.')[-1].lower())
702
702
703
703
704 def clear_output(wait=False):
704 def clear_output(wait=False):
705 """Clear the output of the current cell receiving output.
705 """Clear the output of the current cell receiving output.
706
706
707 Parameters
707 Parameters
708 ----------
708 ----------
709 wait : bool [default: false]
709 wait : bool [default: false]
710 Wait to clear the output until new output is available to replace it."""
710 Wait to clear the output until new output is available to replace it."""
711 from IPython.core.interactiveshell import InteractiveShell
711 from IPython.core.interactiveshell import InteractiveShell
712 if InteractiveShell.initialized():
712 if InteractiveShell.initialized():
713 InteractiveShell.instance().display_pub.clear_output(wait)
713 InteractiveShell.instance().display_pub.clear_output(wait)
714 else:
714 else:
715 from IPython.utils import io
715 from IPython.utils import io
716 print('\033[2K\r', file=io.stdout, end='')
716 print('\033[2K\r', file=io.stdout, end='')
717 io.stdout.flush()
717 io.stdout.flush()
718 print('\033[2K\r', file=io.stderr, end='')
718 print('\033[2K\r', file=io.stderr, end='')
719 io.stderr.flush()
719 io.stderr.flush()
720
720
721
721
722 @skip_doctest
722 @skip_doctest
723 def set_matplotlib_formats(*formats, **kwargs):
723 def set_matplotlib_formats(*formats, **kwargs):
724 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
724 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
725
725
726 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
726 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
727
727
728 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
728 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
729
729
730 To set this in your config files use the following::
730 To set this in your config files use the following::
731
731
732 c.InlineBackend.figure_formats = {'pdf', 'png', 'svg'}
732 c.InlineBackend.figure_formats = {'png', 'jpeg'}
733 c.InlineBackend.quality = 90
733 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
734
734
735 Parameters
735 Parameters
736 ----------
736 ----------
737 *formats : list, tuple
737 *formats : strs
738 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
738 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
739 quality : int
739 **kwargs :
740 A percentage for the quality of JPEG figures. Defaults to 90.
740 Keyword args will be relayed to ``figure.canvas.print_figure``.
741 """
741 """
742 from IPython.core.interactiveshell import InteractiveShell
742 from IPython.core.interactiveshell import InteractiveShell
743 from IPython.core.pylabtools import select_figure_formats
743 from IPython.core.pylabtools import select_figure_formats
744 from IPython.kernel.zmq.pylab.config import InlineBackend
745 # build kwargs, starting with InlineBackend config
746 kw = {}
747 cfg = InlineBackend.instance()
748 kw.update(cfg.print_figure_kwargs)
749 kw.update(**kwargs)
744 shell = InteractiveShell.instance()
750 shell = InteractiveShell.instance()
745 select_figure_formats(shell, formats, quality=90)
751 select_figure_formats(shell, formats, **kw)
746
752
747 @skip_doctest
753 @skip_doctest
748 def set_matplotlib_close(close):
754 def set_matplotlib_close(close=True):
749 """Set whether the inline backend closes all figures automatically or not.
755 """Set whether the inline backend closes all figures automatically or not.
750
756
751 By default, the inline backend used in the IPython Notebook will close all
757 By default, the inline backend used in the IPython Notebook will close all
752 matplotlib figures automatically after each cell is run. This means that
758 matplotlib figures automatically after each cell is run. This means that
753 plots in different cells won't interfere. Sometimes, you may want to make
759 plots in different cells won't interfere. Sometimes, you may want to make
754 a plot in one cell and then refine it in later cells. This can be accomplished
760 a plot in one cell and then refine it in later cells. This can be accomplished
755 by::
761 by::
756
762
757 In [1]: set_matplotlib_close(False)
763 In [1]: set_matplotlib_close(False)
758
764
759 To set this in your config files use the following::
765 To set this in your config files use the following::
760
766
761 c.InlineBackend.close_figures = False
767 c.InlineBackend.close_figures = False
762
768
763 Parameters
769 Parameters
764 ----------
770 ----------
765 close : bool
771 close : bool
766 Should all matplotlib figures be automatically closed after each cell is
772 Should all matplotlib figures be automatically closed after each cell is
767 run?
773 run?
768 """
774 """
769 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
775 from IPython.kernel.zmq.pylab.config import InlineBackend
770 ilbe = InlineBackend.instance()
776 cfg = InlineBackend.instance()
771 ilbe.close_figures = close
777 cfg.close_figures = close
772
778
@@ -1,358 +1,374
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities.
2 """Pylab (matplotlib) support utilities.
3
3
4 Authors
4 Authors
5 -------
5 -------
6
6
7 * Fernando Perez.
7 * Fernando Perez.
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10 from __future__ import print_function
10 from __future__ import print_function
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2009 The IPython Development Team
13 # Copyright (C) 2009 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 import sys
23 import sys
24 from io import BytesIO
24 from io import BytesIO
25
25
26 from IPython.core.display import _pngxy
26 from IPython.core.display import _pngxy
27 from IPython.utils.decorators import flag_calls
27 from IPython.utils.decorators import flag_calls
28 from IPython.utils import py3compat
28 from IPython.utils import py3compat
29
29
30 # If user specifies a GUI, that dictates the backend, otherwise we read the
30 # If user specifies a GUI, that dictates the backend, otherwise we read the
31 # user's mpl default from the mpl rc structure
31 # user's mpl default from the mpl rc structure
32 backends = {'tk': 'TkAgg',
32 backends = {'tk': 'TkAgg',
33 'gtk': 'GTKAgg',
33 'gtk': 'GTKAgg',
34 'gtk3': 'GTK3Agg',
34 'gtk3': 'GTK3Agg',
35 'wx': 'WXAgg',
35 'wx': 'WXAgg',
36 'qt': 'Qt4Agg', # qt3 not supported
36 'qt': 'Qt4Agg', # qt3 not supported
37 'qt4': 'Qt4Agg',
37 'qt4': 'Qt4Agg',
38 'osx': 'MacOSX',
38 'osx': 'MacOSX',
39 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
39 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
40
40
41 # We also need a reverse backends2guis mapping that will properly choose which
41 # We also need a reverse backends2guis mapping that will properly choose which
42 # GUI support to activate based on the desired matplotlib backend. For the
42 # GUI support to activate based on the desired matplotlib backend. For the
43 # most part it's just a reverse of the above dict, but we also need to add a
43 # most part it's just a reverse of the above dict, but we also need to add a
44 # few others that map to the same GUI manually:
44 # few others that map to the same GUI manually:
45 backend2gui = dict(zip(backends.values(), backends.keys()))
45 backend2gui = dict(zip(backends.values(), backends.keys()))
46 # Our tests expect backend2gui to just return 'qt'
46 # Our tests expect backend2gui to just return 'qt'
47 backend2gui['Qt4Agg'] = 'qt'
47 backend2gui['Qt4Agg'] = 'qt'
48 # In the reverse mapping, there are a few extra valid matplotlib backends that
48 # In the reverse mapping, there are a few extra valid matplotlib backends that
49 # map to the same GUI support
49 # map to the same GUI support
50 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
50 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
51 backend2gui['GTK3Cairo'] = 'gtk3'
51 backend2gui['GTK3Cairo'] = 'gtk3'
52 backend2gui['WX'] = 'wx'
52 backend2gui['WX'] = 'wx'
53 backend2gui['CocoaAgg'] = 'osx'
53 backend2gui['CocoaAgg'] = 'osx'
54
54
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 # Matplotlib utilities
56 # Matplotlib utilities
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58
58
59
59
60 def getfigs(*fig_nums):
60 def getfigs(*fig_nums):
61 """Get a list of matplotlib figures by figure numbers.
61 """Get a list of matplotlib figures by figure numbers.
62
62
63 If no arguments are given, all available figures are returned. If the
63 If no arguments are given, all available figures are returned. If the
64 argument list contains references to invalid figures, a warning is printed
64 argument list contains references to invalid figures, a warning is printed
65 but the function continues pasting further figures.
65 but the function continues pasting further figures.
66
66
67 Parameters
67 Parameters
68 ----------
68 ----------
69 figs : tuple
69 figs : tuple
70 A tuple of ints giving the figure numbers of the figures to return.
70 A tuple of ints giving the figure numbers of the figures to return.
71 """
71 """
72 from matplotlib._pylab_helpers import Gcf
72 from matplotlib._pylab_helpers import Gcf
73 if not fig_nums:
73 if not fig_nums:
74 fig_managers = Gcf.get_all_fig_managers()
74 fig_managers = Gcf.get_all_fig_managers()
75 return [fm.canvas.figure for fm in fig_managers]
75 return [fm.canvas.figure for fm in fig_managers]
76 else:
76 else:
77 figs = []
77 figs = []
78 for num in fig_nums:
78 for num in fig_nums:
79 f = Gcf.figs.get(num)
79 f = Gcf.figs.get(num)
80 if f is None:
80 if f is None:
81 print('Warning: figure %s not available.' % num)
81 print('Warning: figure %s not available.' % num)
82 else:
82 else:
83 figs.append(f.canvas.figure)
83 figs.append(f.canvas.figure)
84 return figs
84 return figs
85
85
86
86
87 def figsize(sizex, sizey):
87 def figsize(sizex, sizey):
88 """Set the default figure size to be [sizex, sizey].
88 """Set the default figure size to be [sizex, sizey].
89
89
90 This is just an easy to remember, convenience wrapper that sets::
90 This is just an easy to remember, convenience wrapper that sets::
91
91
92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
93 """
93 """
94 import matplotlib
94 import matplotlib
95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
96
96
97
97
98 def print_figure(fig, fmt='png', quality=90):
98 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
99 """Convert a figure to svg, png or jpg for inline display.
99 """Print a figure to an image, and return the resulting bytes
100 Quality is only relevant for jpg.
100
101 Any keyword args are passed to fig.canvas.print_figure,
102 such as ``quality`` or ``bbox_inches``.
101 """
103 """
102 from matplotlib import rcParams
104 from matplotlib import rcParams
103 # When there's an empty figure, we shouldn't return anything, otherwise we
105 # When there's an empty figure, we shouldn't return anything, otherwise we
104 # get big blank areas in the qt console.
106 # get big blank areas in the qt console.
105 if not fig.axes and not fig.lines:
107 if not fig.axes and not fig.lines:
106 return
108 return
107
109
108 fc = fig.get_facecolor()
109 ec = fig.get_edgecolor()
110 bytes_io = BytesIO()
111 dpi = rcParams['savefig.dpi']
110 dpi = rcParams['savefig.dpi']
112 if fmt == 'retina':
111 if fmt == 'retina':
113 dpi = dpi * 2
112 dpi = dpi * 2
114 fmt = 'png'
113 fmt = 'png'
115 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
116 facecolor=fc, edgecolor=ec, dpi=dpi, quality=quality)
117 data = bytes_io.getvalue()
118 return data
119
114
120 def retina_figure(fig):
115 # build keyword args
116 kw = dict(
117 format=fmt,
118 fc=fig.get_facecolor(),
119 ec=fig.get_edgecolor(),
120 dpi=dpi,
121 bbox_inches=bbox_inches,
122 )
123 # **kwargs get higher priority
124 kw.update(kwargs)
125
126 bytes_io = BytesIO()
127 fig.canvas.print_figure(bytes_io, **kw)
128 return bytes_io.getvalue()
129
130 def retina_figure(fig, **kwargs):
121 """format a figure as a pixel-doubled (retina) PNG"""
131 """format a figure as a pixel-doubled (retina) PNG"""
122 pngdata = print_figure(fig, fmt='retina')
132 pngdata = print_figure(fig, fmt='retina', **kwargs)
123 w, h = _pngxy(pngdata)
133 w, h = _pngxy(pngdata)
124 metadata = dict(width=w//2, height=h//2)
134 metadata = dict(width=w//2, height=h//2)
125 return pngdata, metadata
135 return pngdata, metadata
126
136
127 # We need a little factory function here to create the closure where
137 # We need a little factory function here to create the closure where
128 # safe_execfile can live.
138 # safe_execfile can live.
129 def mpl_runner(safe_execfile):
139 def mpl_runner(safe_execfile):
130 """Factory to return a matplotlib-enabled runner for %run.
140 """Factory to return a matplotlib-enabled runner for %run.
131
141
132 Parameters
142 Parameters
133 ----------
143 ----------
134 safe_execfile : function
144 safe_execfile : function
135 This must be a function with the same interface as the
145 This must be a function with the same interface as the
136 :meth:`safe_execfile` method of IPython.
146 :meth:`safe_execfile` method of IPython.
137
147
138 Returns
148 Returns
139 -------
149 -------
140 A function suitable for use as the ``runner`` argument of the %run magic
150 A function suitable for use as the ``runner`` argument of the %run magic
141 function.
151 function.
142 """
152 """
143
153
144 def mpl_execfile(fname,*where,**kw):
154 def mpl_execfile(fname,*where,**kw):
145 """matplotlib-aware wrapper around safe_execfile.
155 """matplotlib-aware wrapper around safe_execfile.
146
156
147 Its interface is identical to that of the :func:`execfile` builtin.
157 Its interface is identical to that of the :func:`execfile` builtin.
148
158
149 This is ultimately a call to execfile(), but wrapped in safeties to
159 This is ultimately a call to execfile(), but wrapped in safeties to
150 properly handle interactive rendering."""
160 properly handle interactive rendering."""
151
161
152 import matplotlib
162 import matplotlib
153 import matplotlib.pylab as pylab
163 import matplotlib.pylab as pylab
154
164
155 #print '*** Matplotlib runner ***' # dbg
165 #print '*** Matplotlib runner ***' # dbg
156 # turn off rendering until end of script
166 # turn off rendering until end of script
157 is_interactive = matplotlib.rcParams['interactive']
167 is_interactive = matplotlib.rcParams['interactive']
158 matplotlib.interactive(False)
168 matplotlib.interactive(False)
159 safe_execfile(fname,*where,**kw)
169 safe_execfile(fname,*where,**kw)
160 matplotlib.interactive(is_interactive)
170 matplotlib.interactive(is_interactive)
161 # make rendering call now, if the user tried to do it
171 # make rendering call now, if the user tried to do it
162 if pylab.draw_if_interactive.called:
172 if pylab.draw_if_interactive.called:
163 pylab.draw()
173 pylab.draw()
164 pylab.draw_if_interactive.called = False
174 pylab.draw_if_interactive.called = False
165
175
166 return mpl_execfile
176 return mpl_execfile
167
177
168
178
169 def select_figure_formats(shell, formats, quality=90):
179 def select_figure_formats(shell, formats, **kwargs):
170 """Select figure formats for the inline backend.
180 """Select figure formats for the inline backend.
171
181
172 Parameters
182 Parameters
173 ==========
183 ==========
174 shell : InteractiveShell
184 shell : InteractiveShell
175 The main IPython instance.
185 The main IPython instance.
176 formats : list
186 formats : str or set
177 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
187 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
178 quality : int
188 **kwargs : any
179 A percentage for the quality of JPEG figures.
189 Extra keyword arguments to be passed to fig.canvas.print_figure.
180 """
190 """
181 from matplotlib.figure import Figure
191 from matplotlib.figure import Figure
182 from IPython.kernel.zmq.pylab import backend_inline
192 from IPython.kernel.zmq.pylab import backend_inline
183
193
184 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
194 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
185 png_formatter = shell.display_formatter.formatters['image/png']
195 png_formatter = shell.display_formatter.formatters['image/png']
186 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
196 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
187 pdf_formatter = shell.display_formatter.formatters['application/pdf']
197 pdf_formatter = shell.display_formatter.formatters['application/pdf']
188
198
189 if isinstance(formats, py3compat.string_types):
199 if isinstance(formats, py3compat.string_types):
190 formats = {formats}
200 formats = {formats}
191
201 # cast in case of list / tuple
192 [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ]
202 formats = set(formats)
193
203
194 for fmt in formats:
204 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
195 if fmt == 'png':
205
196 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
206 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
197 elif fmt in ('png2x', 'retina'):
207 bad = formats.difference(supported)
198 png_formatter.for_type(Figure, retina_figure)
208 if bad:
199 elif fmt in ('jpg', 'jpeg'):
209 bs = "%s" % ','.join([repr(f) for f in bad])
200 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality))
210 gs = "%s" % ','.join([repr(f) for f in supported])
201 elif fmt == 'svg':
211 raise ValueError("supported formats are: %s not %s" % (gs, bs))
202 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
212
203 elif fmt == 'pdf':
213 if 'png' in formats:
204 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf'))
214 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
205 else:
215 if 'retina' in formats or 'png2x' in formats:
206 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %r" % fmt)
216 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
217 if 'jpg' in formats or 'jpeg' in formats:
218 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
219 if 'svg' in formats:
220 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
221 if 'pdf' in formats:
222 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
207
223
208 #-----------------------------------------------------------------------------
224 #-----------------------------------------------------------------------------
209 # Code for initializing matplotlib and importing pylab
225 # Code for initializing matplotlib and importing pylab
210 #-----------------------------------------------------------------------------
226 #-----------------------------------------------------------------------------
211
227
212
228
213 def find_gui_and_backend(gui=None, gui_select=None):
229 def find_gui_and_backend(gui=None, gui_select=None):
214 """Given a gui string return the gui and mpl backend.
230 """Given a gui string return the gui and mpl backend.
215
231
216 Parameters
232 Parameters
217 ----------
233 ----------
218 gui : str
234 gui : str
219 Can be one of ('tk','gtk','wx','qt','qt4','inline').
235 Can be one of ('tk','gtk','wx','qt','qt4','inline').
220 gui_select : str
236 gui_select : str
221 Can be one of ('tk','gtk','wx','qt','qt4','inline').
237 Can be one of ('tk','gtk','wx','qt','qt4','inline').
222 This is any gui already selected by the shell.
238 This is any gui already selected by the shell.
223
239
224 Returns
240 Returns
225 -------
241 -------
226 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
242 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
227 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
243 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
228 """
244 """
229
245
230 import matplotlib
246 import matplotlib
231
247
232 if gui and gui != 'auto':
248 if gui and gui != 'auto':
233 # select backend based on requested gui
249 # select backend based on requested gui
234 backend = backends[gui]
250 backend = backends[gui]
235 else:
251 else:
236 # We need to read the backend from the original data structure, *not*
252 # We need to read the backend from the original data structure, *not*
237 # from mpl.rcParams, since a prior invocation of %matplotlib may have
253 # from mpl.rcParams, since a prior invocation of %matplotlib may have
238 # overwritten that.
254 # overwritten that.
239 # WARNING: this assumes matplotlib 1.1 or newer!!
255 # WARNING: this assumes matplotlib 1.1 or newer!!
240 backend = matplotlib.rcParamsOrig['backend']
256 backend = matplotlib.rcParamsOrig['backend']
241 # In this case, we need to find what the appropriate gui selection call
257 # In this case, we need to find what the appropriate gui selection call
242 # should be for IPython, so we can activate inputhook accordingly
258 # should be for IPython, so we can activate inputhook accordingly
243 gui = backend2gui.get(backend, None)
259 gui = backend2gui.get(backend, None)
244
260
245 # If we have already had a gui active, we need it and inline are the
261 # If we have already had a gui active, we need it and inline are the
246 # ones allowed.
262 # ones allowed.
247 if gui_select and gui != gui_select:
263 if gui_select and gui != gui_select:
248 gui = gui_select
264 gui = gui_select
249 backend = backends[gui]
265 backend = backends[gui]
250
266
251 return gui, backend
267 return gui, backend
252
268
253
269
254 def activate_matplotlib(backend):
270 def activate_matplotlib(backend):
255 """Activate the given backend and set interactive to True."""
271 """Activate the given backend and set interactive to True."""
256
272
257 import matplotlib
273 import matplotlib
258 matplotlib.interactive(True)
274 matplotlib.interactive(True)
259
275
260 # Matplotlib had a bug where even switch_backend could not force
276 # Matplotlib had a bug where even switch_backend could not force
261 # the rcParam to update. This needs to be set *before* the module
277 # the rcParam to update. This needs to be set *before* the module
262 # magic of switch_backend().
278 # magic of switch_backend().
263 matplotlib.rcParams['backend'] = backend
279 matplotlib.rcParams['backend'] = backend
264
280
265 import matplotlib.pyplot
281 import matplotlib.pyplot
266 matplotlib.pyplot.switch_backend(backend)
282 matplotlib.pyplot.switch_backend(backend)
267
283
268 # This must be imported last in the matplotlib series, after
284 # This must be imported last in the matplotlib series, after
269 # backend/interactivity choices have been made
285 # backend/interactivity choices have been made
270 import matplotlib.pylab as pylab
286 import matplotlib.pylab as pylab
271
287
272 pylab.show._needmain = False
288 pylab.show._needmain = False
273 # We need to detect at runtime whether show() is called by the user.
289 # We need to detect at runtime whether show() is called by the user.
274 # For this, we wrap it into a decorator which adds a 'called' flag.
290 # For this, we wrap it into a decorator which adds a 'called' flag.
275 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
291 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
276
292
277
293
278 def import_pylab(user_ns, import_all=True):
294 def import_pylab(user_ns, import_all=True):
279 """Populate the namespace with pylab-related values.
295 """Populate the namespace with pylab-related values.
280
296
281 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
297 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
282
298
283 Also imports a few names from IPython (figsize, display, getfigs)
299 Also imports a few names from IPython (figsize, display, getfigs)
284
300
285 """
301 """
286
302
287 # Import numpy as np/pyplot as plt are conventions we're trying to
303 # Import numpy as np/pyplot as plt are conventions we're trying to
288 # somewhat standardize on. Making them available to users by default
304 # somewhat standardize on. Making them available to users by default
289 # will greatly help this.
305 # will greatly help this.
290 s = ("import numpy\n"
306 s = ("import numpy\n"
291 "import matplotlib\n"
307 "import matplotlib\n"
292 "from matplotlib import pylab, mlab, pyplot\n"
308 "from matplotlib import pylab, mlab, pyplot\n"
293 "np = numpy\n"
309 "np = numpy\n"
294 "plt = pyplot\n"
310 "plt = pyplot\n"
295 )
311 )
296 exec(s, user_ns)
312 exec(s, user_ns)
297
313
298 if import_all:
314 if import_all:
299 s = ("from matplotlib.pylab import *\n"
315 s = ("from matplotlib.pylab import *\n"
300 "from numpy import *\n")
316 "from numpy import *\n")
301 exec(s, user_ns)
317 exec(s, user_ns)
302
318
303 # IPython symbols to add
319 # IPython symbols to add
304 user_ns['figsize'] = figsize
320 user_ns['figsize'] = figsize
305 from IPython.core.display import display
321 from IPython.core.display import display
306 # Add display and getfigs to the user's namespace
322 # Add display and getfigs to the user's namespace
307 user_ns['display'] = display
323 user_ns['display'] = display
308 user_ns['getfigs'] = getfigs
324 user_ns['getfigs'] = getfigs
309
325
310
326
311 def configure_inline_support(shell, backend):
327 def configure_inline_support(shell, backend):
312 """Configure an IPython shell object for matplotlib use.
328 """Configure an IPython shell object for matplotlib use.
313
329
314 Parameters
330 Parameters
315 ----------
331 ----------
316 shell : InteractiveShell instance
332 shell : InteractiveShell instance
317
333
318 backend : matplotlib backend
334 backend : matplotlib backend
319 """
335 """
320 # If using our svg payload backend, register the post-execution
336 # If using our svg payload backend, register the post-execution
321 # function that will pick up the results for display. This can only be
337 # function that will pick up the results for display. This can only be
322 # done with access to the real shell object.
338 # done with access to the real shell object.
323
339
324 # Note: if we can't load the inline backend, then there's no point
340 # Note: if we can't load the inline backend, then there's no point
325 # continuing (such as in terminal-only shells in environments without
341 # continuing (such as in terminal-only shells in environments without
326 # zeromq available).
342 # zeromq available).
327 try:
343 try:
328 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
344 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
329 except ImportError:
345 except ImportError:
330 return
346 return
331 from matplotlib import pyplot
347 from matplotlib import pyplot
332
348
333 cfg = InlineBackend.instance(parent=shell)
349 cfg = InlineBackend.instance(parent=shell)
334 cfg.shell = shell
350 cfg.shell = shell
335 if cfg not in shell.configurables:
351 if cfg not in shell.configurables:
336 shell.configurables.append(cfg)
352 shell.configurables.append(cfg)
337
353
338 if backend == backends['inline']:
354 if backend == backends['inline']:
339 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
355 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
340 shell.register_post_execute(flush_figures)
356 shell.register_post_execute(flush_figures)
341
357
342 # Save rcParams that will be overwrittern
358 # Save rcParams that will be overwrittern
343 shell._saved_rcParams = dict()
359 shell._saved_rcParams = dict()
344 for k in cfg.rc:
360 for k in cfg.rc:
345 shell._saved_rcParams[k] = pyplot.rcParams[k]
361 shell._saved_rcParams[k] = pyplot.rcParams[k]
346 # load inline_rc
362 # load inline_rc
347 pyplot.rcParams.update(cfg.rc)
363 pyplot.rcParams.update(cfg.rc)
348 else:
364 else:
349 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
365 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
350 if flush_figures in shell._post_execute:
366 if flush_figures in shell._post_execute:
351 shell._post_execute.pop(flush_figures)
367 shell._post_execute.pop(flush_figures)
352 if hasattr(shell, '_saved_rcParams'):
368 if hasattr(shell, '_saved_rcParams'):
353 pyplot.rcParams.update(shell._saved_rcParams)
369 pyplot.rcParams.update(shell._saved_rcParams)
354 del shell._saved_rcParams
370 del shell._saved_rcParams
355
371
356 # Setup the default figure format
372 # Setup the default figure format
357 select_figure_formats(shell, cfg.figure_formats, cfg.quality)
373 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
358
374
@@ -1,60 +1,118
1 #-----------------------------------------------------------------------------
1 #-----------------------------------------------------------------------------
2 # Copyright (C) 2010-2011 The IPython Development Team.
2 # Copyright (C) 2010-2011 The IPython Development Team.
3 #
3 #
4 # Distributed under the terms of the BSD License.
4 # Distributed under the terms of the BSD License.
5 #
5 #
6 # The full license is in the file COPYING.txt, distributed with this software.
6 # The full license is in the file COPYING.txt, distributed with this software.
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 import os
8 import os
9
9
10 import nose.tools as nt
10 import nose.tools as nt
11
11
12 from IPython.core import display
12 from IPython.core import display
13 from IPython.core.getipython import get_ipython
13 from IPython.utils import path as ipath
14 from IPython.utils import path as ipath
14
15
16 import IPython.testing.decorators as dec
17
15 def test_image_size():
18 def test_image_size():
16 """Simple test for display.Image(args, width=x,height=y)"""
19 """Simple test for display.Image(args, width=x,height=y)"""
17 thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
20 thisurl = 'http://www.google.fr/images/srpr/logo3w.png'
18 img = display.Image(url=thisurl, width=200, height=200)
21 img = display.Image(url=thisurl, width=200, height=200)
19 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
22 nt.assert_equal(u'<img src="%s" width="200" height="200"/>' % (thisurl), img._repr_html_())
20 img = display.Image(url=thisurl, width=200)
23 img = display.Image(url=thisurl, width=200)
21 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
24 nt.assert_equal(u'<img src="%s" width="200"/>' % (thisurl), img._repr_html_())
22 img = display.Image(url=thisurl)
25 img = display.Image(url=thisurl)
23 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
26 nt.assert_equal(u'<img src="%s"/>' % (thisurl), img._repr_html_())
24
27
25 def test_retina_png():
28 def test_retina_png():
26 here = os.path.dirname(__file__)
29 here = os.path.dirname(__file__)
27 img = display.Image(os.path.join(here, "2x2.png"), retina=True)
30 img = display.Image(os.path.join(here, "2x2.png"), retina=True)
28 nt.assert_equal(img.height, 1)
31 nt.assert_equal(img.height, 1)
29 nt.assert_equal(img.width, 1)
32 nt.assert_equal(img.width, 1)
30 data, md = img._repr_png_()
33 data, md = img._repr_png_()
31 nt.assert_equal(md['width'], 1)
34 nt.assert_equal(md['width'], 1)
32 nt.assert_equal(md['height'], 1)
35 nt.assert_equal(md['height'], 1)
33
36
34 def test_retina_jpeg():
37 def test_retina_jpeg():
35 here = os.path.dirname(__file__)
38 here = os.path.dirname(__file__)
36 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
39 img = display.Image(os.path.join(here, "2x2.jpg"), retina=True)
37 nt.assert_equal(img.height, 1)
40 nt.assert_equal(img.height, 1)
38 nt.assert_equal(img.width, 1)
41 nt.assert_equal(img.width, 1)
39 data, md = img._repr_jpeg_()
42 data, md = img._repr_jpeg_()
40 nt.assert_equal(md['width'], 1)
43 nt.assert_equal(md['width'], 1)
41 nt.assert_equal(md['height'], 1)
44 nt.assert_equal(md['height'], 1)
42
45
43 def test_image_filename_defaults():
46 def test_image_filename_defaults():
44 '''test format constraint, and validity of jpeg and png'''
47 '''test format constraint, and validity of jpeg and png'''
45 tpath = ipath.get_ipython_package_dir()
48 tpath = ipath.get_ipython_package_dir()
46 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.gif'),
49 nt.assert_raises(ValueError, display.Image, filename=os.path.join(tpath, 'testing/tests/badformat.gif'),
47 embed=True)
50 embed=True)
48 nt.assert_raises(ValueError, display.Image)
51 nt.assert_raises(ValueError, display.Image)
49 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
52 nt.assert_raises(ValueError, display.Image, data='this is not an image', format='badformat', embed=True)
50 from IPython.html import DEFAULT_STATIC_FILES_PATH
53 from IPython.html import DEFAULT_STATIC_FILES_PATH
51 # check boths paths to allow packages to test at build and install time
54 # check boths paths to allow packages to test at build and install time
52 imgfile = os.path.join(tpath, 'html/static/base/images/ipynblogo.png')
55 imgfile = os.path.join(tpath, 'html/static/base/images/ipynblogo.png')
53 if not os.path.exists(imgfile):
56 if not os.path.exists(imgfile):
54 imgfile = os.path.join(DEFAULT_STATIC_FILES_PATH, 'base/images/ipynblogo.png')
57 imgfile = os.path.join(DEFAULT_STATIC_FILES_PATH, 'base/images/ipynblogo.png')
55 img = display.Image(filename=imgfile)
58 img = display.Image(filename=imgfile)
56 nt.assert_equal('png', img.format)
59 nt.assert_equal('png', img.format)
57 nt.assert_is_not_none(img._repr_png_())
60 nt.assert_is_not_none(img._repr_png_())
58 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
61 img = display.Image(filename=os.path.join(tpath, 'testing/tests/logo.jpg'), embed=False)
59 nt.assert_equal('jpeg', img.format)
62 nt.assert_equal('jpeg', img.format)
60 nt.assert_is_none(img._repr_jpeg_())
63 nt.assert_is_none(img._repr_jpeg_())
64
65 def _get_inline_config():
66 from IPython.kernel.zmq.pylab.config import InlineBackend
67 return InlineBackend.instance()
68
69 @dec.skip_without('matplotlib')
70 def test_set_matplotlib_close():
71 cfg = _get_inline_config()
72 cfg.close_figures = False
73 display.set_matplotlib_close()
74 assert cfg.close_figures
75 display.set_matplotlib_close(False)
76 assert not cfg.close_figures
77
78 _fmt_mime_map = {
79 'png': 'image/png',
80 'jpeg': 'image/jpeg',
81 'pdf': 'application/pdf',
82 'retina': 'image/png',
83 'svg': 'image/svg+xml',
84 }
85
86 @dec.skip_without('matplotlib')
87 def test_set_matplotlib_formats():
88 from matplotlib.figure import Figure
89 formatters = get_ipython().display_formatter.formatters
90 for formats in [
91 ('png',),
92 ('pdf', 'svg'),
93 ('jpeg', 'retina', 'png'),
94 (),
95 ]:
96 active_mimes = {_fmt_mime_map[fmt] for fmt in formats}
97 display.set_matplotlib_formats(*formats)
98 for mime, f in formatters.items():
99 if mime in active_mimes:
100 nt.assert_in(Figure, f)
101 else:
102 nt.assert_not_in(Figure, f)
103
104 @dec.skip_without('matplotlib')
105 def test_set_matplotlib_formats_kwargs():
106 from matplotlib.figure import Figure
107 ip = get_ipython()
108 cfg = _get_inline_config()
109 cfg.print_figure_kwargs.update(dict(foo='bar'))
110 kwargs = dict(quality=10)
111 display.set_matplotlib_formats('png', **kwargs)
112 formatter = ip.display_formatter.formatters['image/png']
113 f = formatter.lookup_by_type(Figure)
114 cell = f.__closure__[0].cell_contents
115 expected = kwargs
116 expected.update(cfg.print_figure_kwargs)
117 nt.assert_equal(cell, expected)
118
@@ -1,153 +1,224
1 """Tests for pylab tools module.
1 """Tests for pylab tools module.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2011, the IPython Development Team.
4 # Copyright (c) 2011, the IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 import matplotlib
17 matplotlib.use('Agg')
18 from matplotlib.figure import Figure
17
19
18 # Third-party imports
19 import matplotlib; matplotlib.use('Agg')
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 from matplotlib import pyplot as plt
22 from matplotlib import pyplot as plt
23 import numpy as np
23 import numpy as np
24
24
25 # Our own imports
25 # Our own imports
26 from IPython.core.getipython import get_ipython
26 from IPython.core.interactiveshell import InteractiveShell
27 from IPython.core.interactiveshell import InteractiveShell
28 from IPython.core.display import _PNG, _JPEG
27 from .. import pylabtools as pt
29 from .. import pylabtools as pt
28
30
29 from IPython.testing import decorators as dec
31 from IPython.testing import decorators as dec
30
32
31 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
32 # Globals and constants
34 # Globals and constants
33 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
34
36
35 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
36 # Local utilities
38 # Local utilities
37 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
38
40
39 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
40 # Classes and functions
42 # Classes and functions
41 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
42
44
43 def test_figure_to_svg():
45 def test_figure_to_svg():
44 # simple empty-figure test
46 # simple empty-figure test
45 fig = plt.figure()
47 fig = plt.figure()
46 nt.assert_equal(pt.print_figure(fig, 'svg'), None)
48 nt.assert_equal(pt.print_figure(fig, 'svg'), None)
47
49
48 plt.close('all')
50 plt.close('all')
49
51
50 # simple check for at least svg-looking output
52 # simple check for at least svg-looking output
51 fig = plt.figure()
53 fig = plt.figure()
52 ax = fig.add_subplot(1,1,1)
54 ax = fig.add_subplot(1,1,1)
53 ax.plot([1,2,3])
55 ax.plot([1,2,3])
54 plt.draw()
56 plt.draw()
55 svg = pt.print_figure(fig, 'svg')[:100].lower()
57 svg = pt.print_figure(fig, 'svg')[:100].lower()
56 nt.assert_in(b'doctype svg', svg)
58 nt.assert_in(b'doctype svg', svg)
57
59
58 @dec.skip_without("PIL.Image")
60 @dec.skip_without("PIL.Image")
59 def test_figure_to_jpg():
61 def test_figure_to_jpg():
60 # simple check for at least jpg-looking output
62 # simple check for at least jpg-looking output
61 fig = plt.figure()
63 fig = plt.figure()
62 ax = fig.add_subplot(1,1,1)
64 ax = fig.add_subplot(1,1,1)
63 ax.plot([1,2,3])
65 ax.plot([1,2,3])
64 plt.draw()
66 plt.draw()
65 jpg = pt.print_figure(fig, 'jpg')[:100].lower()
67 jpg = pt.print_figure(fig, 'jpg', quality=50)[:100].lower()
66 assert jpg.startswith(b'\xff\xd8')
68 assert jpg.startswith(_JPEG)
67
69
70 def test_retina_figure():
71 fig = plt.figure()
72 ax = fig.add_subplot(1,1,1)
73 ax.plot([1,2,3])
74 plt.draw()
75 png, md = pt.retina_figure(fig)
76 assert png.startswith(_PNG)
77 nt.assert_in('width', md)
78 nt.assert_in('height', md)
79
80 _fmt_mime_map = {
81 'png': 'image/png',
82 'jpeg': 'image/jpeg',
83 'pdf': 'application/pdf',
84 'retina': 'image/png',
85 'svg': 'image/svg+xml',
86 }
87
88 def test_select_figure_formats_str():
89 ip = get_ipython()
90 for fmt, active_mime in _fmt_mime_map.items():
91 pt.select_figure_formats(ip, fmt)
92 for mime, f in ip.display_formatter.formatters.items():
93 if mime == active_mime:
94 nt.assert_in(Figure, f)
95 else:
96 nt.assert_not_in(Figure, f)
97
98 def test_select_figure_formats_kwargs():
99 ip = get_ipython()
100 kwargs = dict(quality=10, bbox_inches='tight')
101 pt.select_figure_formats(ip, 'png', **kwargs)
102 formatter = ip.display_formatter.formatters['image/png']
103 f = formatter.lookup_by_type(Figure)
104 cell = f.__closure__[0].cell_contents
105 nt.assert_equal(cell, kwargs)
106
107 # check that the formatter doesn't raise
108 fig = plt.figure()
109 ax = fig.add_subplot(1,1,1)
110 ax.plot([1,2,3])
111 plt.draw()
112 formatter.enabled = True
113 png = formatter(fig)
114 assert png.startswith(_PNG)
68
115
69 def test_import_pylab():
116 def test_select_figure_formats_set():
70 ip = get_ipython()
117 ip = get_ipython()
118 for fmts in [
119 {'png', 'svg'},
120 ['png'],
121 ('jpeg', 'pdf', 'retina'),
122 {'svg'},
123 ]:
124 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
125 pt.select_figure_formats(ip, fmts)
126 for mime, f in ip.display_formatter.formatters.items():
127 if mime in active_mimes:
128 nt.assert_in(Figure, f)
129 else:
130 nt.assert_not_in(Figure, f)
131
132 def test_select_figure_formats_bad():
133 ip = get_ipython()
134 with nt.assert_raises(ValueError):
135 pt.select_figure_formats(ip, 'foo')
136 with nt.assert_raises(ValueError):
137 pt.select_figure_formats(ip, {'png', 'foo'})
138 with nt.assert_raises(ValueError):
139 pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad'])
140
141 def test_import_pylab():
71 ns = {}
142 ns = {}
72 pt.import_pylab(ns, import_all=False)
143 pt.import_pylab(ns, import_all=False)
73 nt.assert_true('plt' in ns)
144 nt.assert_true('plt' in ns)
74 nt.assert_equal(ns['np'], np)
145 nt.assert_equal(ns['np'], np)
75
146
76 class TestPylabSwitch(object):
147 class TestPylabSwitch(object):
77 class Shell(InteractiveShell):
148 class Shell(InteractiveShell):
78 def enable_gui(self, gui):
149 def enable_gui(self, gui):
79 pass
150 pass
80
151
81 def setup(self):
152 def setup(self):
82 import matplotlib
153 import matplotlib
83 def act_mpl(backend):
154 def act_mpl(backend):
84 matplotlib.rcParams['backend'] = backend
155 matplotlib.rcParams['backend'] = backend
85
156
86 # Save rcParams since they get modified
157 # Save rcParams since they get modified
87 self._saved_rcParams = matplotlib.rcParams
158 self._saved_rcParams = matplotlib.rcParams
88 self._saved_rcParamsOrig = matplotlib.rcParamsOrig
159 self._saved_rcParamsOrig = matplotlib.rcParamsOrig
89 matplotlib.rcParams = dict(backend='Qt4Agg')
160 matplotlib.rcParams = dict(backend='Qt4Agg')
90 matplotlib.rcParamsOrig = dict(backend='Qt4Agg')
161 matplotlib.rcParamsOrig = dict(backend='Qt4Agg')
91
162
92 # Mock out functions
163 # Mock out functions
93 self._save_am = pt.activate_matplotlib
164 self._save_am = pt.activate_matplotlib
94 pt.activate_matplotlib = act_mpl
165 pt.activate_matplotlib = act_mpl
95 self._save_ip = pt.import_pylab
166 self._save_ip = pt.import_pylab
96 pt.import_pylab = lambda *a,**kw:None
167 pt.import_pylab = lambda *a,**kw:None
97 self._save_cis = pt.configure_inline_support
168 self._save_cis = pt.configure_inline_support
98 pt.configure_inline_support = lambda *a,**kw:None
169 pt.configure_inline_support = lambda *a,**kw:None
99
170
100 def teardown(self):
171 def teardown(self):
101 pt.activate_matplotlib = self._save_am
172 pt.activate_matplotlib = self._save_am
102 pt.import_pylab = self._save_ip
173 pt.import_pylab = self._save_ip
103 pt.configure_inline_support = self._save_cis
174 pt.configure_inline_support = self._save_cis
104 import matplotlib
175 import matplotlib
105 matplotlib.rcParams = self._saved_rcParams
176 matplotlib.rcParams = self._saved_rcParams
106 matplotlib.rcParamsOrig = self._saved_rcParamsOrig
177 matplotlib.rcParamsOrig = self._saved_rcParamsOrig
107
178
108 def test_qt(self):
179 def test_qt(self):
109 s = self.Shell()
180 s = self.Shell()
110 gui, backend = s.enable_matplotlib(None)
181 gui, backend = s.enable_matplotlib(None)
111 nt.assert_equal(gui, 'qt')
182 nt.assert_equal(gui, 'qt')
112 nt.assert_equal(s.pylab_gui_select, 'qt')
183 nt.assert_equal(s.pylab_gui_select, 'qt')
113
184
114 gui, backend = s.enable_matplotlib('inline')
185 gui, backend = s.enable_matplotlib('inline')
115 nt.assert_equal(gui, 'inline')
186 nt.assert_equal(gui, 'inline')
116 nt.assert_equal(s.pylab_gui_select, 'qt')
187 nt.assert_equal(s.pylab_gui_select, 'qt')
117
188
118 gui, backend = s.enable_matplotlib('qt')
189 gui, backend = s.enable_matplotlib('qt')
119 nt.assert_equal(gui, 'qt')
190 nt.assert_equal(gui, 'qt')
120 nt.assert_equal(s.pylab_gui_select, 'qt')
191 nt.assert_equal(s.pylab_gui_select, 'qt')
121
192
122 gui, backend = s.enable_matplotlib('inline')
193 gui, backend = s.enable_matplotlib('inline')
123 nt.assert_equal(gui, 'inline')
194 nt.assert_equal(gui, 'inline')
124 nt.assert_equal(s.pylab_gui_select, 'qt')
195 nt.assert_equal(s.pylab_gui_select, 'qt')
125
196
126 gui, backend = s.enable_matplotlib()
197 gui, backend = s.enable_matplotlib()
127 nt.assert_equal(gui, 'qt')
198 nt.assert_equal(gui, 'qt')
128 nt.assert_equal(s.pylab_gui_select, 'qt')
199 nt.assert_equal(s.pylab_gui_select, 'qt')
129
200
130 def test_inline(self):
201 def test_inline(self):
131 s = self.Shell()
202 s = self.Shell()
132 gui, backend = s.enable_matplotlib('inline')
203 gui, backend = s.enable_matplotlib('inline')
133 nt.assert_equal(gui, 'inline')
204 nt.assert_equal(gui, 'inline')
134 nt.assert_equal(s.pylab_gui_select, None)
205 nt.assert_equal(s.pylab_gui_select, None)
135
206
136 gui, backend = s.enable_matplotlib('inline')
207 gui, backend = s.enable_matplotlib('inline')
137 nt.assert_equal(gui, 'inline')
208 nt.assert_equal(gui, 'inline')
138 nt.assert_equal(s.pylab_gui_select, None)
209 nt.assert_equal(s.pylab_gui_select, None)
139
210
140 gui, backend = s.enable_matplotlib('qt')
211 gui, backend = s.enable_matplotlib('qt')
141 nt.assert_equal(gui, 'qt')
212 nt.assert_equal(gui, 'qt')
142 nt.assert_equal(s.pylab_gui_select, 'qt')
213 nt.assert_equal(s.pylab_gui_select, 'qt')
143
214
144 def test_qt_gtk(self):
215 def test_qt_gtk(self):
145 s = self.Shell()
216 s = self.Shell()
146 gui, backend = s.enable_matplotlib('qt')
217 gui, backend = s.enable_matplotlib('qt')
147 nt.assert_equal(gui, 'qt')
218 nt.assert_equal(gui, 'qt')
148 nt.assert_equal(s.pylab_gui_select, 'qt')
219 nt.assert_equal(s.pylab_gui_select, 'qt')
149
220
150 gui, backend = s.enable_matplotlib('gtk')
221 gui, backend = s.enable_matplotlib('gtk')
151 nt.assert_equal(gui, 'qt')
222 nt.assert_equal(gui, 'qt')
152 nt.assert_equal(s.pylab_gui_select, 'qt')
223 nt.assert_equal(s.pylab_gui_select, 'qt')
153
224
@@ -1,115 +1,117
1 """Configurable for configuring the IPython inline backend
1 """Configurable for configuring the IPython inline backend
2
2
3 This module does not import anything from matplotlib.
3 This module does not import anything from matplotlib.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2011 The IPython Development Team
6 # Copyright (C) 2011 The IPython Development Team
7 #
7 #
8 # Distributed under the terms of the BSD License. The full license is in
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING, distributed as part of this software.
9 # the file COPYING, distributed as part of this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 from IPython.config.configurable import SingletonConfigurable
16 from IPython.config.configurable import SingletonConfigurable
17 from IPython.utils.traitlets import (
17 from IPython.utils.traitlets import (
18 Dict, Instance, CaselessStrEnum, Set, Bool, Int, TraitError, Unicode
18 Dict, Instance, CaselessStrEnum, Set, Bool, Int, TraitError, Unicode
19 )
19 )
20 from IPython.utils.warn import warn
20 from IPython.utils.warn import warn
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Configurable for inline backend options
23 # Configurable for inline backend options
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 def pil_available():
26 def pil_available():
27 """Test if PIL/Pillow is available"""
27 """Test if PIL/Pillow is available"""
28 out = False
28 out = False
29 try:
29 try:
30 from PIL import Image
30 from PIL import Image
31 out = True
31 out = True
32 except:
32 except:
33 pass
33 pass
34 return out
34 return out
35
35
36 # inherit from InlineBackendConfig for deprecation purposes
36 # inherit from InlineBackendConfig for deprecation purposes
37 class InlineBackendConfig(SingletonConfigurable):
37 class InlineBackendConfig(SingletonConfigurable):
38 pass
38 pass
39
39
40 class InlineBackend(InlineBackendConfig):
40 class InlineBackend(InlineBackendConfig):
41 """An object to store configuration of the inline backend."""
41 """An object to store configuration of the inline backend."""
42
42
43 def _config_changed(self, name, old, new):
43 def _config_changed(self, name, old, new):
44 # warn on change of renamed config section
44 # warn on change of renamed config section
45 if new.InlineBackendConfig != old.InlineBackendConfig:
45 if new.InlineBackendConfig != old.InlineBackendConfig:
46 warn("InlineBackendConfig has been renamed to InlineBackend")
46 warn("InlineBackendConfig has been renamed to InlineBackend")
47 super(InlineBackend, self)._config_changed(name, old, new)
47 super(InlineBackend, self)._config_changed(name, old, new)
48
48
49 # The typical default figure size is too large for inline use,
49 # The typical default figure size is too large for inline use,
50 # so we shrink the figure size to 6x4, and tweak fonts to
50 # so we shrink the figure size to 6x4, and tweak fonts to
51 # make that fit.
51 # make that fit.
52 rc = Dict({'figure.figsize': (6.0,4.0),
52 rc = Dict({'figure.figsize': (6.0,4.0),
53 # play nicely with white background in the Qt and notebook frontend
53 # play nicely with white background in the Qt and notebook frontend
54 'figure.facecolor': (1,1,1,0),
54 'figure.facecolor': (1,1,1,0),
55 'figure.edgecolor': (1,1,1,0),
55 'figure.edgecolor': (1,1,1,0),
56 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
56 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
57 'font.size': 10,
57 'font.size': 10,
58 # 72 dpi matches SVG/qtconsole
58 # 72 dpi matches SVG/qtconsole
59 # this only affects PNG export, as SVG has no dpi setting
59 # this only affects PNG export, as SVG has no dpi setting
60 'savefig.dpi': 72,
60 'savefig.dpi': 72,
61 # 10pt still needs a little more room on the xlabel:
61 # 10pt still needs a little more room on the xlabel:
62 'figure.subplot.bottom' : .125
62 'figure.subplot.bottom' : .125
63 }, config=True,
63 }, config=True,
64 help="""Subset of matplotlib rcParams that should be different for the
64 help="""Subset of matplotlib rcParams that should be different for the
65 inline backend."""
65 inline backend."""
66 )
66 )
67
67
68 figure_formats = Set({'png'}, config=True,
68 figure_formats = Set({'png'}, config=True,
69 help="""A set of figure formats to enable: 'png',
69 help="""A set of figure formats to enable: 'png',
70 'retina', 'jpeg', 'svg', 'pdf'.""")
70 'retina', 'jpeg', 'svg', 'pdf'.""")
71
71
72 def _update_figure_formatters(self):
73 if self.shell is not None:
74 select_figure_formats(self.shell, self.figure_formats, **self.print_figure_kwargs)
75
72 def _figure_formats_changed(self, name, old, new):
76 def _figure_formats_changed(self, name, old, new):
73 from IPython.core.pylabtools import select_figure_formats
77 from IPython.core.pylabtools import select_figure_formats
74 if 'jpg' in new or 'jpeg' in new:
78 if 'jpg' in new or 'jpeg' in new:
75 if not pil_available():
79 if not pil_available():
76 raise TraitError("Requires PIL/Pillow for JPG figures")
80 raise TraitError("Requires PIL/Pillow for JPG figures")
77 if self.shell is None:
81 self._update_figure_formatters()
78 return
79 else:
80 select_figure_formats(self.shell, new)
81
82
82 figure_format = Unicode(config=True, help="""The figure format to enable (deprecated
83 figure_format = Unicode(config=True, help="""The figure format to enable (deprecated
83 use `figure_formats` instead)""")
84 use `figure_formats` instead)""")
84
85
85 def _figure_format_changed(self, name, old, new):
86 def _figure_format_changed(self, name, old, new):
86 if new:
87 if new:
87 self.figure_formats = {new}
88 self.figure_formats = {new}
88
89
89 quality = Int(default_value=90, config=True,
90 print_figure_kwargs = Dict({'bbox_inches' : 'tight'}, config=True,
90 help="Quality of compression [10-100], currently for lossy JPEG only.")
91 help="""Extra kwargs to be passed to fig.canvas.print_figure.
91
92
92 def _quality_changed(self, name, old, new):
93 Logical examples include: bbox_inches, quality (for jpeg figures), etc.
93 if new < 10 or new > 100:
94 """
94 raise TraitError("figure JPEG quality must be in [10-100] range.")
95 )
96 _print_figure_kwargs_changed = _update_figure_formatters
95
97
96 close_figures = Bool(True, config=True,
98 close_figures = Bool(True, config=True,
97 help="""Close all figures at the end of each cell.
99 help="""Close all figures at the end of each cell.
98
100
99 When True, ensures that each cell starts with no active figures, but it
101 When True, ensures that each cell starts with no active figures, but it
100 also means that one must keep track of references in order to edit or
102 also means that one must keep track of references in order to edit or
101 redraw figures in subsequent cells. This mode is ideal for the notebook,
103 redraw figures in subsequent cells. This mode is ideal for the notebook,
102 where residual plots from other cells might be surprising.
104 where residual plots from other cells might be surprising.
103
105
104 When False, one must call figure() to create new figures. This means
106 When False, one must call figure() to create new figures. This means
105 that gcf() and getfigs() can reference figures created in other cells,
107 that gcf() and getfigs() can reference figures created in other cells,
106 and the active figure can continue to be edited with pylab/pyplot
108 and the active figure can continue to be edited with pylab/pyplot
107 methods that reference the current active figure. This mode facilitates
109 methods that reference the current active figure. This mode facilitates
108 iterative editing of figures, and behaves most consistently with
110 iterative editing of figures, and behaves most consistently with
109 other matplotlib backends, but figure barriers between cells must
111 other matplotlib backends, but figure barriers between cells must
110 be explicit.
112 be explicit.
111 """)
113 """)
112
114
113 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
115 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
114
116
115
117
@@ -1,285 +1,283
1 =====================
1 =====================
2 Development version
2 Development version
3 =====================
3 =====================
4
4
5 This document describes in-flight development work.
5 This document describes in-flight development work.
6
6
7 .. warning::
7 .. warning::
8
8
9 Please do not edit this file by hand (doing so will likely cause merge
9 Please do not edit this file by hand (doing so will likely cause merge
10 conflicts for other Pull Requests). Instead, create a new file in the
10 conflicts for other Pull Requests). Instead, create a new file in the
11 `docs/source/whatsnew/pr` folder
11 `docs/source/whatsnew/pr` folder
12
12
13 Select Notebook Name When Renaming a Notebook
13 Select Notebook Name When Renaming a Notebook
14 ---------------------------------------------
14 ---------------------------------------------
15
15
16 The default notebook name is Untitled. It's unlikely you want to keep this name
16 The default notebook name is Untitled. It's unlikely you want to keep this name
17 or part of it when naming your notebook. Instead, IPython will select the text
17 or part of it when naming your notebook. Instead, IPython will select the text
18 in the input field so the user can easily type over the name and change it.
18 in the input field so the user can easily type over the name and change it.
19
19
20 clear_output changes
20 clear_output changes
21 --------------------
21 --------------------
22
22
23 * There is no longer a 500ms delay when calling ``clear_output``.
23 * There is no longer a 500ms delay when calling ``clear_output``.
24 * The ability to clear stderr and stdout individually was removed.
24 * The ability to clear stderr and stdout individually was removed.
25 * A new ``wait`` flag that prevents ``clear_output`` from being executed until new
25 * A new ``wait`` flag that prevents ``clear_output`` from being executed until new
26 output is available. This eliminates animation flickering by allowing the
26 output is available. This eliminates animation flickering by allowing the
27 user to double buffer the output.
27 user to double buffer the output.
28 * The output div height is remembered when the ``wait=True`` flag is used.
28 * The output div height is remembered when the ``wait=True`` flag is used.
29
29
30 Extending Configurable Containers
30 Extending Configurable Containers
31 ---------------------------------
31 ---------------------------------
32
32
33 Some configurable traits are containers (list, dict, set)
33 Some configurable traits are containers (list, dict, set)
34 Config objects now support calling ``extend``, ``update``, ``insert``, etc.
34 Config objects now support calling ``extend``, ``update``, ``insert``, etc.
35 on traits in config files, which will ultimately result in calling
35 on traits in config files, which will ultimately result in calling
36 those methods on the original object.
36 those methods on the original object.
37
37
38 The effect being that you can now add to containers without having to copy/paste
38 The effect being that you can now add to containers without having to copy/paste
39 the initial value::
39 the initial value::
40
40
41 c = get_config()
41 c = get_config()
42 c.InlineBackend.rc.update({ 'figure.figsize' : (6, 4) })
42 c.InlineBackend.rc.update({ 'figure.figsize' : (6, 4) })
43
43
44 Single codebase Python 3 support
44 Single codebase Python 3 support
45 --------------------------------
45 --------------------------------
46
46
47 IPython previously supported Python 3 by running 2to3 during setup. We
47 IPython previously supported Python 3 by running 2to3 during setup. We
48 have now switched to a single codebase which runs natively on Python 2.7
48 have now switched to a single codebase which runs natively on Python 2.7
49 and 3.3.
49 and 3.3.
50
50
51 For notes on how to maintain this, see :doc:`/development/pycompat`.
51 For notes on how to maintain this, see :doc:`/development/pycompat`.
52
52
53 changes to hidden namespace on startup
53 changes to hidden namespace on startup
54 --------------------------------------
54 --------------------------------------
55
55
56 Previously, all names declared in code run at startup
56 Previously, all names declared in code run at startup
57 (startup files, ``ipython -i script.py``, etc.)
57 (startup files, ``ipython -i script.py``, etc.)
58 were added to the hidden namespace, which hides the names from tools like ``%whos``.
58 were added to the hidden namespace, which hides the names from tools like ``%whos``.
59 There are two changes to this behavior:
59 There are two changes to this behavior:
60
60
61 1. Scripts run on the command-line ``ipython -i script.py``now behave the same as if they were
61 1. Scripts run on the command-line ``ipython -i script.py``now behave the same as if they were
62 passed to ``%run``, so their variables are never hidden.
62 passed to ``%run``, so their variables are never hidden.
63 2. A boolean config flag ``InteractiveShellApp.hide_initial_ns`` has been added to optionally
63 2. A boolean config flag ``InteractiveShellApp.hide_initial_ns`` has been added to optionally
64 disable the hidden behavior altogether. The default behavior is unchanged.
64 disable the hidden behavior altogether. The default behavior is unchanged.
65
65
66 Using dill to expand serialization support
66 Using dill to expand serialization support
67 ------------------------------------------
67 ------------------------------------------
68
68
69 adds :func:`~IPython.utils.pickleutil.use_dill` for allowing
69 adds :func:`~IPython.utils.pickleutil.use_dill` for allowing
70 dill to extend serialization support in :mod:`IPython.parallel` (closures, etc.).
70 dill to extend serialization support in :mod:`IPython.parallel` (closures, etc.).
71 Also adds :meth:`DirectView.use_dill` convenience method for enabling dill
71 Also adds :meth:`DirectView.use_dill` convenience method for enabling dill
72 locally and on all engines with one call.
72 locally and on all engines with one call.
73
73
74 New IPython Console Lexer
74 New IPython Console Lexer
75 -------------------------
75 -------------------------
76
76
77 The IPython console lexer has been rewritten and now supports tracebacks
77 The IPython console lexer has been rewritten and now supports tracebacks
78 and customized input/output prompts. An entire suite of lexers is now
78 and customized input/output prompts. An entire suite of lexers is now
79 available at :mod:`IPython.nbconvert.utils.lexers`. These include:
79 available at :mod:`IPython.nbconvert.utils.lexers`. These include:
80
80
81 IPythonLexer & IPython3Lexer
81 IPythonLexer & IPython3Lexer
82 Lexers for pure IPython (python + magic/shell commands)
82 Lexers for pure IPython (python + magic/shell commands)
83
83
84 IPythonPartialTracebackLexer & IPythonTracebackLexer
84 IPythonPartialTracebackLexer & IPythonTracebackLexer
85 Supports 2.x and 3.x via the keyword `python3`. The partial traceback
85 Supports 2.x and 3.x via the keyword `python3`. The partial traceback
86 lexer reads everything but the Python code appearing in a traceback.
86 lexer reads everything but the Python code appearing in a traceback.
87 The full lexer combines the partial lexer with an IPython lexer.
87 The full lexer combines the partial lexer with an IPython lexer.
88
88
89 IPythonConsoleLexer
89 IPythonConsoleLexer
90 A lexer for IPython console sessions, with support for tracebacks.
90 A lexer for IPython console sessions, with support for tracebacks.
91 Supports 2.x and 3.x via the keyword `python3`.
91 Supports 2.x and 3.x via the keyword `python3`.
92
92
93 IPyLexer
93 IPyLexer
94 A friendly lexer which examines the first line of text and from it,
94 A friendly lexer which examines the first line of text and from it,
95 decides whether to use an IPython lexer or an IPython console lexer.
95 decides whether to use an IPython lexer or an IPython console lexer.
96 Supports 2.x and 3.x via the keyword `python3`.
96 Supports 2.x and 3.x via the keyword `python3`.
97
97
98 Previously, the :class:`IPythonConsoleLexer` class was available at
98 Previously, the :class:`IPythonConsoleLexer` class was available at
99 :mod:`IPython.sphinxext.ipython_console_hightlight`. It was inserted
99 :mod:`IPython.sphinxext.ipython_console_hightlight`. It was inserted
100 into Pygments' list of available lexers under the name `ipython`. It should
100 into Pygments' list of available lexers under the name `ipython`. It should
101 be mentioned that this name is inaccurate, since an IPython console session
101 be mentioned that this name is inaccurate, since an IPython console session
102 is not the same as IPython code (which itself is a superset of the Python
102 is not the same as IPython code (which itself is a superset of the Python
103 language).
103 language).
104
104
105 Now, the Sphinx extension inserts two console lexers into Pygments' list of
105 Now, the Sphinx extension inserts two console lexers into Pygments' list of
106 available lexers. Both are IPyLexer instances under the names: `ipython` and
106 available lexers. Both are IPyLexer instances under the names: `ipython` and
107 `ipython3`. Although the names can be confusing (as mentioned above), their
107 `ipython3`. Although the names can be confusing (as mentioned above), their
108 continued use is, in part, to maintain backwards compatibility and to
108 continued use is, in part, to maintain backwards compatibility and to
109 aid typical usage. If a project needs to make Pygments aware of more than just
109 aid typical usage. If a project needs to make Pygments aware of more than just
110 the IPyLexer class, then one should not make the IPyLexer class available under
110 the IPyLexer class, then one should not make the IPyLexer class available under
111 the name `ipython` and use `ipy` or some other non-conflicting value.
111 the name `ipython` and use `ipy` or some other non-conflicting value.
112
112
113 Code blocks such as:
113 Code blocks such as:
114
114
115 .. code-block:: rst
115 .. code-block:: rst
116
116
117 .. code-block:: ipython
117 .. code-block:: ipython
118
118
119 In [1]: 2**2
119 In [1]: 2**2
120 Out[1]: 4
120 Out[1]: 4
121
121
122 will continue to work as before, but now, they will also properly highlight
122 will continue to work as before, but now, they will also properly highlight
123 tracebacks. For pure IPython code, the same lexer will also work:
123 tracebacks. For pure IPython code, the same lexer will also work:
124
124
125 .. code-block:: rst
125 .. code-block:: rst
126
126
127 .. code-block:: ipython
127 .. code-block:: ipython
128
128
129 x = ''.join(map(str, range(10)))
129 x = ''.join(map(str, range(10)))
130 !echo $x
130 !echo $x
131
131
132 Since the first line of the block did not begin with a standard IPython console
132 Since the first line of the block did not begin with a standard IPython console
133 prompt, the entire block is assumed to consist of IPython code instead.
133 prompt, the entire block is assumed to consist of IPython code instead.
134
134
135 DisplayFormatter changes
135 DisplayFormatter changes
136 ------------------------
136 ------------------------
137
137
138 There was no official way to query or remove callbacks in the Formatter API.
138 There was no official way to query or remove callbacks in the Formatter API.
139 To remedy this, the following methods are added to :class:`BaseFormatter`:
139 To remedy this, the following methods are added to :class:`BaseFormatter`:
140
140
141 - ``lookup(instance)`` - return appropriate callback or a given object
141 - ``lookup(instance)`` - return appropriate callback or a given object
142 - ``lookup_by_type(type_or_str)`` - return appropriate callback for a given type or ``'mod.name'`` type string
142 - ``lookup_by_type(type_or_str)`` - return appropriate callback for a given type or ``'mod.name'`` type string
143 - ``pop(type_or_str)`` - remove a type (by type or string).
143 - ``pop(type_or_str)`` - remove a type (by type or string).
144 Pass a second argument to avoid KeyError (like dict).
144 Pass a second argument to avoid KeyError (like dict).
145
145
146 All of the above methods raise a KeyError if no match is found.
146 All of the above methods raise a KeyError if no match is found.
147
147
148 And the following methods are changed:
148 And the following methods are changed:
149
149
150 - ``for_type(type_or_str)`` - behaves the same as before, only adding support for ``'mod.name'``
150 - ``for_type(type_or_str)`` - behaves the same as before, only adding support for ``'mod.name'``
151 type strings in addition to plain types. This removes the need for ``for_type_by_name()``,
151 type strings in addition to plain types. This removes the need for ``for_type_by_name()``,
152 but it remains for backward compatibility.
152 but it remains for backward compatibility.
153
153
154 Notebook Widgets
154 Notebook Widgets
155 ----------------
155 ----------------
156
156
157 Available in the new `IPython.html.widgets` namespace, widgets provide an easy
157 Available in the new `IPython.html.widgets` namespace, widgets provide an easy
158 way for IPython notebook users to display GUI controls in the IPython notebook.
158 way for IPython notebook users to display GUI controls in the IPython notebook.
159 IPython comes with bundle of built-in widgets and also the ability for users
159 IPython comes with bundle of built-in widgets and also the ability for users
160 to define their own widgets. A widget is displayed in the front-end using
160 to define their own widgets. A widget is displayed in the front-end using
161 using a view. For example, a FloatRangeWidget can be displayed using a
161 using a view. For example, a FloatRangeWidget can be displayed using a
162 FloatSliderView (which is the default if no view is specified when displaying
162 FloatSliderView (which is the default if no view is specified when displaying
163 the widget). IPython also comes with a bundle of views and the ability for the
163 the widget). IPython also comes with a bundle of views and the ability for the
164 user to define custom views. One widget can be displayed multiple times, in on
164 user to define custom views. One widget can be displayed multiple times, in on
165 or more cells, using one or more views. All views will automatically remain in
165 or more cells, using one or more views. All views will automatically remain in
166 sync with the widget which is accessible in the back-end.
166 sync with the widget which is accessible in the back-end.
167
167
168 The widget layer provides an MVC-like architecture on top of the comm layer.
168 The widget layer provides an MVC-like architecture on top of the comm layer.
169 It's useful for widgets that can be expressed via a list of properties.
169 It's useful for widgets that can be expressed via a list of properties.
170 Widgets work by synchronizing IPython traitlet models in the back-end with
170 Widgets work by synchronizing IPython traitlet models in the back-end with
171 backbone models in the front-end. The widget layer automatically handles
171 backbone models in the front-end. The widget layer automatically handles
172
172
173 * delta compression (only sending the state information that has changed)
173 * delta compression (only sending the state information that has changed)
174 * wiring the message callbacks to the correct cells automatically
174 * wiring the message callbacks to the correct cells automatically
175 * inter-view synchronization (handled by backbone)
175 * inter-view synchronization (handled by backbone)
176 * message throttling (to avoid flooding the kernel)
176 * message throttling (to avoid flooding the kernel)
177 * parent/child relationships between views (which one can override to specify custom parent/child relationships)
177 * parent/child relationships between views (which one can override to specify custom parent/child relationships)
178 * ability to manipulate the widget view's DOM from python using CSS, $().addClass, and $().removeClass methods
178 * ability to manipulate the widget view's DOM from python using CSS, $().addClass, and $().removeClass methods
179
179
180 Signing Notebooks
180 Signing Notebooks
181 -----------------
181 -----------------
182
182
183 To prevent untrusted code from executing on users' behalf when notebooks open,
183 To prevent untrusted code from executing on users' behalf when notebooks open,
184 we have added a signature to the notebook, stored in metadata.
184 we have added a signature to the notebook, stored in metadata.
185
185
186 For more information, see :ref:`signing_notebooks`.
186 For more information, see :ref:`signing_notebooks`.
187
187
188 Other changes
188 Other changes
189 -------------
189 -------------
190
190
191 * `%%capture` cell magic now captures the rich display output, not just
191 * `%%capture` cell magic now captures the rich display output, not just
192 stdout/stderr
192 stdout/stderr
193
193
194 * In notebook, Showing tooltip on tab has been disables to avoid conflict with
194 * In notebook, Showing tooltip on tab has been disables to avoid conflict with
195 completion, Shift-Tab could still be used to invoke tooltip when inside
195 completion, Shift-Tab could still be used to invoke tooltip when inside
196 function signature and/or on selection.
196 function signature and/or on selection.
197
197
198 * ``object_info_request`` as been replaced by ``object_info`` for consistency in the javascript API.
198 * ``object_info_request`` as been replaced by ``object_info`` for consistency in the javascript API.
199 ``object_info`` as a simpler interface to register callback that is incompatible with ``object_info_request``.
199 ``object_info`` as a simpler interface to register callback that is incompatible with ``object_info_request``.
200
200
201 * Previous versions of IPython on Linux would use the XDG config directory,
201 * Previous versions of IPython on Linux would use the XDG config directory,
202 creating :file:`~/.config/ipython` by default. We have decided to go
202 creating :file:`~/.config/ipython` by default. We have decided to go
203 back to :file:`~/.ipython` for consistency among systems. IPython will
203 back to :file:`~/.ipython` for consistency among systems. IPython will
204 issue a warning if it finds the XDG location, and will move it to the new
204 issue a warning if it finds the XDG location, and will move it to the new
205 location if there isn't already a directory there.
205 location if there isn't already a directory there.
206
206
207 * Equations, images and tables are now centered in Markdown cells.
207 * Equations, images and tables are now centered in Markdown cells.
208 * Multiline equations are now centered in output areas; single line equations
208 * Multiline equations are now centered in output areas; single line equations
209 remain left justified.
209 remain left justified.
210
210
211 * IPython config objects can be loaded from and serialized to JSON.
211 * IPython config objects can be loaded from and serialized to JSON.
212 JSON config file have the same base name as their ``.py`` counterpart,
212 JSON config file have the same base name as their ``.py`` counterpart,
213 and will be loaded with higher priority if found.
213 and will be loaded with higher priority if found.
214
214
215 * bash completion updated with support for all ipython subcommands and flags, including nbconvert
215 * bash completion updated with support for all ipython subcommands and flags, including nbconvert
216
216
217 * ``ipython history trim``: added ``--keep=<N>`` as an alias for the more verbose
217 * ``ipython history trim``: added ``--keep=<N>`` as an alias for the more verbose
218 ``--HistoryTrim.keep=<N>``
218 ``--HistoryTrim.keep=<N>``
219 * new ``ipython history clear`` subcommand, which is the same as the newly supported
219 * new ``ipython history clear`` subcommand, which is the same as the newly supported
220 ``ipython history trim --keep=0``
220 ``ipython history trim --keep=0``
221
221
222 * You can now run notebooks in an interactive session via ``%run notebook.ipynb``.
222 * You can now run notebooks in an interactive session via ``%run notebook.ipynb``.
223
223
224 * Print preview is back in the notebook menus, along with options to
224 * Print preview is back in the notebook menus, along with options to
225 download the open notebook in various formats. This is powered by
225 download the open notebook in various formats. This is powered by
226 nbconvert.
226 nbconvert.
227
227
228 * :exc:`~IPython.nbconvert.utils.pandoc.PandocMissing` exceptions will be
228 * :exc:`~IPython.nbconvert.utils.pandoc.PandocMissing` exceptions will be
229 raised if Pandoc is unavailable, and warnings will be printed if the version
229 raised if Pandoc is unavailable, and warnings will be printed if the version
230 found is too old. The recommended Pandoc version for use with nbconvert is
230 found is too old. The recommended Pandoc version for use with nbconvert is
231 1.12.1.
231 1.12.1.
232
232
233 * The InlineBackend.figure_format flag now supports JPEG output if PIL/Pillow is available.
233 * The InlineBackend.figure_format flag now supports JPEG output if PIL/Pillow is available.
234 * The new ``InlineBackend.quality`` flag is a Integer in the range [10, 100] which controls
235 the quality of figures where higher values give nicer images (currently JPEG only).
236
234
237 * Input transformers (see :doc:`/config/inputtransforms`) may now raise
235 * Input transformers (see :doc:`/config/inputtransforms`) may now raise
238 :exc:`SyntaxError` if they determine that input is invalid. The input
236 :exc:`SyntaxError` if they determine that input is invalid. The input
239 transformation machinery in IPython will handle displaying the exception to
237 transformation machinery in IPython will handle displaying the exception to
240 the user and resetting state.
238 the user and resetting state.
241
239
242 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
240 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
243
241
244 Backwards incompatible changes
242 Backwards incompatible changes
245 ------------------------------
243 ------------------------------
246
244
247 * Python 2.6 and 3.2 are no longer supported: the minimum required
245 * Python 2.6 and 3.2 are no longer supported: the minimum required
248 Python versions are now 2.7 and 3.3.
246 Python versions are now 2.7 and 3.3.
249 * The Transformer classes have been renamed to Preprocessor in nbconvert and
247 * The Transformer classes have been renamed to Preprocessor in nbconvert and
250 their `call` methods for them have been renamed to `preprocess`.
248 their `call` methods for them have been renamed to `preprocess`.
251 * The `call` methods of nbconvert post-processsors have been renamed to
249 * The `call` methods of nbconvert post-processsors have been renamed to
252 `postprocess`.
250 `postprocess`.
253
251
254 * The module ``IPython.core.fakemodule`` has been removed.
252 * The module ``IPython.core.fakemodule`` has been removed.
255
253
256 * The alias system has been reimplemented to use magic functions. There should be little
254 * The alias system has been reimplemented to use magic functions. There should be little
257 visible difference while automagics are enabled, as they are by default, but parts of the
255 visible difference while automagics are enabled, as they are by default, but parts of the
258 :class:`~IPython.core.alias.AliasManager` API have been removed.
256 :class:`~IPython.core.alias.AliasManager` API have been removed.
259
257
260 * We fixed an issue with switching between matplotlib inline and GUI backends,
258 * We fixed an issue with switching between matplotlib inline and GUI backends,
261 but the fix requires matplotlib 1.1 or newer. So from now on, we consider
259 but the fix requires matplotlib 1.1 or newer. So from now on, we consider
262 matplotlib 1.1 to be the minimally supported version for IPython. Older
260 matplotlib 1.1 to be the minimally supported version for IPython. Older
263 versions for the most part will work, but we make no guarantees about it.
261 versions for the most part will work, but we make no guarantees about it.
264
262
265 * The :command:`pycolor` command has been removed. We recommend the much more capable
263 * The :command:`pycolor` command has been removed. We recommend the much more capable
266 :command:`pygmentize` command from the `Pygments <http://pygments.org/>`_ project.
264 :command:`pygmentize` command from the `Pygments <http://pygments.org/>`_ project.
267 If you need to keep the exact output of :command:`pycolor`, you can still use
265 If you need to keep the exact output of :command:`pycolor`, you can still use
268 ``python -m IPython.utils.PyColorize foo.py``.
266 ``python -m IPython.utils.PyColorize foo.py``.
269
267
270 * :mod:`IPython.lib.irunner` and its command-line entry point have been removed.
268 * :mod:`IPython.lib.irunner` and its command-line entry point have been removed.
271 It had fallen out of use long ago.
269 It had fallen out of use long ago.
272
270
273 * The ``input_prefilter`` hook has been removed, as it was never
271 * The ``input_prefilter`` hook has been removed, as it was never
274 actually used by the code. The input transformer system offers much
272 actually used by the code. The input transformer system offers much
275 more powerful APIs to work with input code. See
273 more powerful APIs to work with input code. See
276 :doc:`/config/inputtransforms` for details.
274 :doc:`/config/inputtransforms` for details.
277
275
278 * :class:`IPython.core.inputsplitter.IPythonInputSplitter` no longer has a method
276 * :class:`IPython.core.inputsplitter.IPythonInputSplitter` no longer has a method
279 ``source_raw_reset()``, but gains :meth:`~IPython.core.inputsplitter.IPythonInputSplitter.raw_reset`
277 ``source_raw_reset()``, but gains :meth:`~IPython.core.inputsplitter.IPythonInputSplitter.raw_reset`
280 instead. Use of ``source_raw_reset`` can be replaced with::
278 instead. Use of ``source_raw_reset`` can be replaced with::
281
279
282 raw = isp.source_raw
280 raw = isp.source_raw
283 transformed = isp.source_reset()
281 transformed = isp.source_reset()
284
282
285 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
283 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
General Comments 0
You need to be logged in to leave comments. Login now