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