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