##// END OF EJS Templates
Added '%matplotlib agg' option....
Matteo -
Show More
@@ -1,396 +1,399 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities."""
2 """Pylab (matplotlib) support utilities."""
3 from __future__ import print_function
3 from __future__ import print_function
4
4
5 # Copyright (c) IPython Development Team.
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7
7
8 from io import BytesIO
8 from io import BytesIO
9
9
10 from IPython.core.display import _pngxy
10 from IPython.core.display import _pngxy
11 from IPython.utils.decorators import flag_calls
11 from IPython.utils.decorators import flag_calls
12 from IPython.utils import py3compat
12 from IPython.utils import py3compat
13
13
14 # If user specifies a GUI, that dictates the backend, otherwise we read the
14 # If user specifies a GUI, that dictates the backend, otherwise we read the
15 # user's mpl default from the mpl rc structure
15 # user's mpl default from the mpl rc structure
16 backends = {'tk': 'TkAgg',
16 backends = {'tk': 'TkAgg',
17 'gtk': 'GTKAgg',
17 'gtk': 'GTKAgg',
18 'gtk3': 'GTK3Agg',
18 'gtk3': 'GTK3Agg',
19 'wx': 'WXAgg',
19 'wx': 'WXAgg',
20 'qt': 'Qt4Agg', # qt3 not supported
20 'qt': 'Qt4Agg', # qt3 not supported
21 'qt4': 'Qt4Agg',
21 'qt4': 'Qt4Agg',
22 'qt5': 'Qt5Agg',
22 'qt5': 'Qt5Agg',
23 'osx': 'MacOSX',
23 'osx': 'MacOSX',
24 'nbagg': 'nbAgg',
24 'nbagg': 'nbAgg',
25 'notebook': 'nbAgg',
25 'notebook': 'nbAgg',
26 'agg': 'agg',
26 'inline' : 'module://ipykernel.pylab.backend_inline'}
27 'inline' : 'module://ipykernel.pylab.backend_inline'}
27
28
28 # We also need a reverse backends2guis mapping that will properly choose which
29 # We also need a reverse backends2guis mapping that will properly choose which
29 # GUI support to activate based on the desired matplotlib backend. For the
30 # GUI support to activate based on the desired matplotlib backend. For the
30 # most part it's just a reverse of the above dict, but we also need to add a
31 # most part it's just a reverse of the above dict, but we also need to add a
31 # few others that map to the same GUI manually:
32 # few others that map to the same GUI manually:
32 backend2gui = dict(zip(backends.values(), backends.keys()))
33 backend2gui = dict(zip(backends.values(), backends.keys()))
33 # Our tests expect backend2gui to just return 'qt'
34 # Our tests expect backend2gui to just return 'qt'
34 backend2gui['Qt4Agg'] = 'qt'
35 backend2gui['Qt4Agg'] = 'qt'
35 # In the reverse mapping, there are a few extra valid matplotlib backends that
36 # In the reverse mapping, there are a few extra valid matplotlib backends that
36 # map to the same GUI support
37 # map to the same GUI support
37 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
38 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
38 backend2gui['GTK3Cairo'] = 'gtk3'
39 backend2gui['GTK3Cairo'] = 'gtk3'
39 backend2gui['WX'] = 'wx'
40 backend2gui['WX'] = 'wx'
40 backend2gui['CocoaAgg'] = 'osx'
41 backend2gui['CocoaAgg'] = 'osx'
41
42
42 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
43 # Matplotlib utilities
44 # Matplotlib utilities
44 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
45
46
46
47
47 def getfigs(*fig_nums):
48 def getfigs(*fig_nums):
48 """Get a list of matplotlib figures by figure numbers.
49 """Get a list of matplotlib figures by figure numbers.
49
50
50 If no arguments are given, all available figures are returned. If the
51 If no arguments are given, all available figures are returned. If the
51 argument list contains references to invalid figures, a warning is printed
52 argument list contains references to invalid figures, a warning is printed
52 but the function continues pasting further figures.
53 but the function continues pasting further figures.
53
54
54 Parameters
55 Parameters
55 ----------
56 ----------
56 figs : tuple
57 figs : tuple
57 A tuple of ints giving the figure numbers of the figures to return.
58 A tuple of ints giving the figure numbers of the figures to return.
58 """
59 """
59 from matplotlib._pylab_helpers import Gcf
60 from matplotlib._pylab_helpers import Gcf
60 if not fig_nums:
61 if not fig_nums:
61 fig_managers = Gcf.get_all_fig_managers()
62 fig_managers = Gcf.get_all_fig_managers()
62 return [fm.canvas.figure for fm in fig_managers]
63 return [fm.canvas.figure for fm in fig_managers]
63 else:
64 else:
64 figs = []
65 figs = []
65 for num in fig_nums:
66 for num in fig_nums:
66 f = Gcf.figs.get(num)
67 f = Gcf.figs.get(num)
67 if f is None:
68 if f is None:
68 print('Warning: figure %s not available.' % num)
69 print('Warning: figure %s not available.' % num)
69 else:
70 else:
70 figs.append(f.canvas.figure)
71 figs.append(f.canvas.figure)
71 return figs
72 return figs
72
73
73
74
74 def figsize(sizex, sizey):
75 def figsize(sizex, sizey):
75 """Set the default figure size to be [sizex, sizey].
76 """Set the default figure size to be [sizex, sizey].
76
77
77 This is just an easy to remember, convenience wrapper that sets::
78 This is just an easy to remember, convenience wrapper that sets::
78
79
79 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
80 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
80 """
81 """
81 import matplotlib
82 import matplotlib
82 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
83 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
83
84
84
85
85 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
86 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
86 """Print a figure to an image, and return the resulting file data
87 """Print a figure to an image, and return the resulting file data
87
88
88 Returned data will be bytes unless ``fmt='svg'``,
89 Returned data will be bytes unless ``fmt='svg'``,
89 in which case it will be unicode.
90 in which case it will be unicode.
90
91
91 Any keyword args are passed to fig.canvas.print_figure,
92 Any keyword args are passed to fig.canvas.print_figure,
92 such as ``quality`` or ``bbox_inches``.
93 such as ``quality`` or ``bbox_inches``.
93 """
94 """
94 from matplotlib import rcParams
95 from matplotlib import rcParams
95 # When there's an empty figure, we shouldn't return anything, otherwise we
96 # When there's an empty figure, we shouldn't return anything, otherwise we
96 # get big blank areas in the qt console.
97 # get big blank areas in the qt console.
97 if not fig.axes and not fig.lines:
98 if not fig.axes and not fig.lines:
98 return
99 return
99
100
100 dpi = rcParams['savefig.dpi']
101 dpi = rcParams['savefig.dpi']
101 if dpi == 'figure':
102 if dpi == 'figure':
102 dpi = fig.dpi
103 dpi = fig.dpi
103 if fmt == 'retina':
104 if fmt == 'retina':
104 dpi = dpi * 2
105 dpi = dpi * 2
105 fmt = 'png'
106 fmt = 'png'
106
107
107 # build keyword args
108 # build keyword args
108 kw = dict(
109 kw = dict(
109 format=fmt,
110 format=fmt,
110 facecolor=fig.get_facecolor(),
111 facecolor=fig.get_facecolor(),
111 edgecolor=fig.get_edgecolor(),
112 edgecolor=fig.get_edgecolor(),
112 dpi=dpi,
113 dpi=dpi,
113 bbox_inches=bbox_inches,
114 bbox_inches=bbox_inches,
114 )
115 )
115 # **kwargs get higher priority
116 # **kwargs get higher priority
116 kw.update(kwargs)
117 kw.update(kwargs)
117
118
118 bytes_io = BytesIO()
119 bytes_io = BytesIO()
119 fig.canvas.print_figure(bytes_io, **kw)
120 fig.canvas.print_figure(bytes_io, **kw)
120 data = bytes_io.getvalue()
121 data = bytes_io.getvalue()
121 if fmt == 'svg':
122 if fmt == 'svg':
122 data = data.decode('utf-8')
123 data = data.decode('utf-8')
123 return data
124 return data
124
125
125 def retina_figure(fig, **kwargs):
126 def retina_figure(fig, **kwargs):
126 """format a figure as a pixel-doubled (retina) PNG"""
127 """format a figure as a pixel-doubled (retina) PNG"""
127 pngdata = print_figure(fig, fmt='retina', **kwargs)
128 pngdata = print_figure(fig, fmt='retina', **kwargs)
128 # Make sure that retina_figure acts just like print_figure and returns
129 # Make sure that retina_figure acts just like print_figure and returns
129 # None when the figure is empty.
130 # None when the figure is empty.
130 if pngdata is None:
131 if pngdata is None:
131 return
132 return
132 w, h = _pngxy(pngdata)
133 w, h = _pngxy(pngdata)
133 metadata = dict(width=w//2, height=h//2)
134 metadata = dict(width=w//2, height=h//2)
134 return pngdata, metadata
135 return pngdata, metadata
135
136
136 # 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
137 # safe_execfile can live.
138 # safe_execfile can live.
138 def mpl_runner(safe_execfile):
139 def mpl_runner(safe_execfile):
139 """Factory to return a matplotlib-enabled runner for %run.
140 """Factory to return a matplotlib-enabled runner for %run.
140
141
141 Parameters
142 Parameters
142 ----------
143 ----------
143 safe_execfile : function
144 safe_execfile : function
144 This must be a function with the same interface as the
145 This must be a function with the same interface as the
145 :meth:`safe_execfile` method of IPython.
146 :meth:`safe_execfile` method of IPython.
146
147
147 Returns
148 Returns
148 -------
149 -------
149 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
150 function.
151 function.
151 """
152 """
152
153
153 def mpl_execfile(fname,*where,**kw):
154 def mpl_execfile(fname,*where,**kw):
154 """matplotlib-aware wrapper around safe_execfile.
155 """matplotlib-aware wrapper around safe_execfile.
155
156
156 Its interface is identical to that of the :func:`execfile` builtin.
157 Its interface is identical to that of the :func:`execfile` builtin.
157
158
158 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
159 properly handle interactive rendering."""
160 properly handle interactive rendering."""
160
161
161 import matplotlib
162 import matplotlib
162 import matplotlib.pylab as pylab
163 import matplotlib.pylab as pylab
163
164
164 #print '*** Matplotlib runner ***' # dbg
165 #print '*** Matplotlib runner ***' # dbg
165 # turn off rendering until end of script
166 # turn off rendering until end of script
166 is_interactive = matplotlib.rcParams['interactive']
167 is_interactive = matplotlib.rcParams['interactive']
167 matplotlib.interactive(False)
168 matplotlib.interactive(False)
168 safe_execfile(fname,*where,**kw)
169 safe_execfile(fname,*where,**kw)
169 matplotlib.interactive(is_interactive)
170 matplotlib.interactive(is_interactive)
170 # make rendering call now, if the user tried to do it
171 # make rendering call now, if the user tried to do it
171 if pylab.draw_if_interactive.called:
172 if pylab.draw_if_interactive.called:
172 pylab.draw()
173 pylab.draw()
173 pylab.draw_if_interactive.called = False
174 pylab.draw_if_interactive.called = False
174
175
175 return mpl_execfile
176 return mpl_execfile
176
177
177
178
178 def _reshow_nbagg_figure(fig):
179 def _reshow_nbagg_figure(fig):
179 """reshow an nbagg figure"""
180 """reshow an nbagg figure"""
180 try:
181 try:
181 reshow = fig.canvas.manager.reshow
182 reshow = fig.canvas.manager.reshow
182 except AttributeError:
183 except AttributeError:
183 raise NotImplementedError()
184 raise NotImplementedError()
184 else:
185 else:
185 reshow()
186 reshow()
186
187
187
188
188 def select_figure_formats(shell, formats, **kwargs):
189 def select_figure_formats(shell, formats, **kwargs):
189 """Select figure formats for the inline backend.
190 """Select figure formats for the inline backend.
190
191
191 Parameters
192 Parameters
192 ==========
193 ==========
193 shell : InteractiveShell
194 shell : InteractiveShell
194 The main IPython instance.
195 The main IPython instance.
195 formats : str or set
196 formats : str or set
196 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
197 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
197 **kwargs : any
198 **kwargs : any
198 Extra keyword arguments to be passed to fig.canvas.print_figure.
199 Extra keyword arguments to be passed to fig.canvas.print_figure.
199 """
200 """
200 import matplotlib
201 import matplotlib
201 from matplotlib.figure import Figure
202 from matplotlib.figure import Figure
202
203
203 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
204 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
204 png_formatter = shell.display_formatter.formatters['image/png']
205 png_formatter = shell.display_formatter.formatters['image/png']
205 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
206 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
206 pdf_formatter = shell.display_formatter.formatters['application/pdf']
207 pdf_formatter = shell.display_formatter.formatters['application/pdf']
207
208
208 if isinstance(formats, py3compat.string_types):
209 if isinstance(formats, py3compat.string_types):
209 formats = {formats}
210 formats = {formats}
210 # cast in case of list / tuple
211 # cast in case of list / tuple
211 formats = set(formats)
212 formats = set(formats)
212
213
213 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
214 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
214
215
215 if matplotlib.get_backend().lower() == 'nbagg':
216 if matplotlib.get_backend().lower() == 'nbagg':
216 formatter = shell.display_formatter.ipython_display_formatter
217 formatter = shell.display_formatter.ipython_display_formatter
217 formatter.for_type(Figure, _reshow_nbagg_figure)
218 formatter.for_type(Figure, _reshow_nbagg_figure)
218
219
219 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
220 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
220 bad = formats.difference(supported)
221 bad = formats.difference(supported)
221 if bad:
222 if bad:
222 bs = "%s" % ','.join([repr(f) for f in bad])
223 bs = "%s" % ','.join([repr(f) for f in bad])
223 gs = "%s" % ','.join([repr(f) for f in supported])
224 gs = "%s" % ','.join([repr(f) for f in supported])
224 raise ValueError("supported formats are: %s not %s" % (gs, bs))
225 raise ValueError("supported formats are: %s not %s" % (gs, bs))
225
226
226 if 'png' in formats:
227 if 'png' in formats:
227 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
228 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
228 if 'retina' in formats or 'png2x' in formats:
229 if 'retina' in formats or 'png2x' in formats:
229 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
230 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
230 if 'jpg' in formats or 'jpeg' in formats:
231 if 'jpg' in formats or 'jpeg' in formats:
231 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
232 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
232 if 'svg' in formats:
233 if 'svg' in formats:
233 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
234 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
234 if 'pdf' in formats:
235 if 'pdf' in formats:
235 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
236 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
236
237
237 #-----------------------------------------------------------------------------
238 #-----------------------------------------------------------------------------
238 # Code for initializing matplotlib and importing pylab
239 # Code for initializing matplotlib and importing pylab
239 #-----------------------------------------------------------------------------
240 #-----------------------------------------------------------------------------
240
241
241
242
242 def find_gui_and_backend(gui=None, gui_select=None):
243 def find_gui_and_backend(gui=None, gui_select=None):
243 """Given a gui string return the gui and mpl backend.
244 """Given a gui string return the gui and mpl backend.
244
245
245 Parameters
246 Parameters
246 ----------
247 ----------
247 gui : str
248 gui : str
248 Can be one of ('tk','gtk','wx','qt','qt4','inline').
249 Can be one of ('tk','gtk','wx','qt','qt4','inline').
249 gui_select : str
250 gui_select : str
250 Can be one of ('tk','gtk','wx','qt','qt4','inline').
251 Can be one of ('tk','gtk','wx','qt','qt4','inline').
251 This is any gui already selected by the shell.
252 This is any gui already selected by the shell.
252
253
253 Returns
254 Returns
254 -------
255 -------
255 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
256 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
256 'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline').
257 'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline').
257 """
258 """
258
259
259 import matplotlib
260 import matplotlib
260
261
261 if gui and gui != 'auto':
262 if gui and gui != 'auto':
262 # select backend based on requested gui
263 # select backend based on requested gui
263 backend = backends[gui]
264 backend = backends[gui]
265 if gui == 'agg':
266 gui = None
264 else:
267 else:
265 # We need to read the backend from the original data structure, *not*
268 # We need to read the backend from the original data structure, *not*
266 # from mpl.rcParams, since a prior invocation of %matplotlib may have
269 # from mpl.rcParams, since a prior invocation of %matplotlib may have
267 # overwritten that.
270 # overwritten that.
268 # WARNING: this assumes matplotlib 1.1 or newer!!
271 # WARNING: this assumes matplotlib 1.1 or newer!!
269 backend = matplotlib.rcParamsOrig['backend']
272 backend = matplotlib.rcParamsOrig['backend']
270 # In this case, we need to find what the appropriate gui selection call
273 # In this case, we need to find what the appropriate gui selection call
271 # should be for IPython, so we can activate inputhook accordingly
274 # should be for IPython, so we can activate inputhook accordingly
272 gui = backend2gui.get(backend, None)
275 gui = backend2gui.get(backend, None)
273
276
274 # If we have already had a gui active, we need it and inline are the
277 # If we have already had a gui active, we need it and inline are the
275 # ones allowed.
278 # ones allowed.
276 if gui_select and gui != gui_select:
279 if gui_select and gui != gui_select:
277 gui = gui_select
280 gui = gui_select
278 backend = backends[gui]
281 backend = backends[gui]
279
282
280 return gui, backend
283 return gui, backend
281
284
282
285
283 def activate_matplotlib(backend):
286 def activate_matplotlib(backend):
284 """Activate the given backend and set interactive to True."""
287 """Activate the given backend and set interactive to True."""
285
288
286 import matplotlib
289 import matplotlib
287 matplotlib.interactive(True)
290 matplotlib.interactive(True)
288
291
289 # Matplotlib had a bug where even switch_backend could not force
292 # Matplotlib had a bug where even switch_backend could not force
290 # the rcParam to update. This needs to be set *before* the module
293 # the rcParam to update. This needs to be set *before* the module
291 # magic of switch_backend().
294 # magic of switch_backend().
292 matplotlib.rcParams['backend'] = backend
295 matplotlib.rcParams['backend'] = backend
293
296
294 import matplotlib.pyplot
297 import matplotlib.pyplot
295 matplotlib.pyplot.switch_backend(backend)
298 matplotlib.pyplot.switch_backend(backend)
296
299
297 # This must be imported last in the matplotlib series, after
300 # This must be imported last in the matplotlib series, after
298 # backend/interactivity choices have been made
301 # backend/interactivity choices have been made
299 import matplotlib.pylab as pylab
302 import matplotlib.pylab as pylab
300
303
301 pylab.show._needmain = False
304 pylab.show._needmain = False
302 # We need to detect at runtime whether show() is called by the user.
305 # We need to detect at runtime whether show() is called by the user.
303 # For this, we wrap it into a decorator which adds a 'called' flag.
306 # For this, we wrap it into a decorator which adds a 'called' flag.
304 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
307 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
305
308
306
309
307 def import_pylab(user_ns, import_all=True):
310 def import_pylab(user_ns, import_all=True):
308 """Populate the namespace with pylab-related values.
311 """Populate the namespace with pylab-related values.
309
312
310 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
313 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
311
314
312 Also imports a few names from IPython (figsize, display, getfigs)
315 Also imports a few names from IPython (figsize, display, getfigs)
313
316
314 """
317 """
315
318
316 # Import numpy as np/pyplot as plt are conventions we're trying to
319 # Import numpy as np/pyplot as plt are conventions we're trying to
317 # somewhat standardize on. Making them available to users by default
320 # somewhat standardize on. Making them available to users by default
318 # will greatly help this.
321 # will greatly help this.
319 s = ("import numpy\n"
322 s = ("import numpy\n"
320 "import matplotlib\n"
323 "import matplotlib\n"
321 "from matplotlib import pylab, mlab, pyplot\n"
324 "from matplotlib import pylab, mlab, pyplot\n"
322 "np = numpy\n"
325 "np = numpy\n"
323 "plt = pyplot\n"
326 "plt = pyplot\n"
324 )
327 )
325 exec(s, user_ns)
328 exec(s, user_ns)
326
329
327 if import_all:
330 if import_all:
328 s = ("from matplotlib.pylab import *\n"
331 s = ("from matplotlib.pylab import *\n"
329 "from numpy import *\n")
332 "from numpy import *\n")
330 exec(s, user_ns)
333 exec(s, user_ns)
331
334
332 # IPython symbols to add
335 # IPython symbols to add
333 user_ns['figsize'] = figsize
336 user_ns['figsize'] = figsize
334 from IPython.core.display import display
337 from IPython.core.display import display
335 # Add display and getfigs to the user's namespace
338 # Add display and getfigs to the user's namespace
336 user_ns['display'] = display
339 user_ns['display'] = display
337 user_ns['getfigs'] = getfigs
340 user_ns['getfigs'] = getfigs
338
341
339
342
340 def configure_inline_support(shell, backend):
343 def configure_inline_support(shell, backend):
341 """Configure an IPython shell object for matplotlib use.
344 """Configure an IPython shell object for matplotlib use.
342
345
343 Parameters
346 Parameters
344 ----------
347 ----------
345 shell : InteractiveShell instance
348 shell : InteractiveShell instance
346
349
347 backend : matplotlib backend
350 backend : matplotlib backend
348 """
351 """
349 # If using our svg payload backend, register the post-execution
352 # If using our svg payload backend, register the post-execution
350 # function that will pick up the results for display. This can only be
353 # function that will pick up the results for display. This can only be
351 # done with access to the real shell object.
354 # done with access to the real shell object.
352
355
353 # Note: if we can't load the inline backend, then there's no point
356 # Note: if we can't load the inline backend, then there's no point
354 # continuing (such as in terminal-only shells in environments without
357 # continuing (such as in terminal-only shells in environments without
355 # zeromq available).
358 # zeromq available).
356 try:
359 try:
357 from ipykernel.pylab.backend_inline import InlineBackend
360 from ipykernel.pylab.backend_inline import InlineBackend
358 except ImportError:
361 except ImportError:
359 return
362 return
360 import matplotlib
363 import matplotlib
361
364
362 cfg = InlineBackend.instance(parent=shell)
365 cfg = InlineBackend.instance(parent=shell)
363 cfg.shell = shell
366 cfg.shell = shell
364 if cfg not in shell.configurables:
367 if cfg not in shell.configurables:
365 shell.configurables.append(cfg)
368 shell.configurables.append(cfg)
366
369
367 if backend == backends['inline']:
370 if backend == backends['inline']:
368 from ipykernel.pylab.backend_inline import flush_figures
371 from ipykernel.pylab.backend_inline import flush_figures
369 shell.events.register('post_execute', flush_figures)
372 shell.events.register('post_execute', flush_figures)
370
373
371 # Save rcParams that will be overwrittern
374 # Save rcParams that will be overwrittern
372 shell._saved_rcParams = dict()
375 shell._saved_rcParams = dict()
373 for k in cfg.rc:
376 for k in cfg.rc:
374 shell._saved_rcParams[k] = matplotlib.rcParams[k]
377 shell._saved_rcParams[k] = matplotlib.rcParams[k]
375 # load inline_rc
378 # load inline_rc
376 matplotlib.rcParams.update(cfg.rc)
379 matplotlib.rcParams.update(cfg.rc)
377 new_backend_name = "inline"
380 new_backend_name = "inline"
378 else:
381 else:
379 from ipykernel.pylab.backend_inline import flush_figures
382 from ipykernel.pylab.backend_inline import flush_figures
380 try:
383 try:
381 shell.events.unregister('post_execute', flush_figures)
384 shell.events.unregister('post_execute', flush_figures)
382 except ValueError:
385 except ValueError:
383 pass
386 pass
384 if hasattr(shell, '_saved_rcParams'):
387 if hasattr(shell, '_saved_rcParams'):
385 matplotlib.rcParams.update(shell._saved_rcParams)
388 matplotlib.rcParams.update(shell._saved_rcParams)
386 del shell._saved_rcParams
389 del shell._saved_rcParams
387 new_backend_name = "other"
390 new_backend_name = "other"
388
391
389 # only enable the formats once -> don't change the enabled formats (which the user may
392 # only enable the formats once -> don't change the enabled formats (which the user may
390 # has changed) when getting another "%matplotlib inline" call.
393 # has changed) when getting another "%matplotlib inline" call.
391 # See https://github.com/ipython/ipykernel/issues/29
394 # See https://github.com/ipython/ipykernel/issues/29
392 cur_backend = getattr(configure_inline_support, "current_backend", "unset")
395 cur_backend = getattr(configure_inline_support, "current_backend", "unset")
393 if new_backend_name != cur_backend:
396 if new_backend_name != cur_backend:
394 # Setup the default figure format
397 # Setup the default figure format
395 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
398 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
396 configure_inline_support.current_backend = new_backend_name
399 configure_inline_support.current_backend = new_backend_name
General Comments 0
You need to be logged in to leave comments. Login now