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