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