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