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