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