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