##// END OF EJS Templates
make pylab_activate call import_pylab with import_all
Jens Hedegaard Nielsen -
Show More
@@ -1,321 +1,321 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Pylab (matplotlib) support utilities.
2 """Pylab (matplotlib) support utilities.
3
3
4 Authors
4 Authors
5 -------
5 -------
6
6
7 * Fernando Perez.
7 * Fernando Perez.
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2009 The IPython Development Team
12 # Copyright (C) 2009 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 from cStringIO import StringIO
22 from cStringIO import StringIO
23
23
24 from IPython.utils.decorators import flag_calls
24 from IPython.utils.decorators import flag_calls
25
25
26 # If user specifies a GUI, that dictates the backend, otherwise we read the
26 # If user specifies a GUI, that dictates the backend, otherwise we read the
27 # user's mpl default from the mpl rc structure
27 # user's mpl default from the mpl rc structure
28 backends = {'tk': 'TkAgg',
28 backends = {'tk': 'TkAgg',
29 'gtk': 'GTKAgg',
29 'gtk': 'GTKAgg',
30 'wx': 'WXAgg',
30 'wx': 'WXAgg',
31 'qt': 'Qt4Agg', # qt3 not supported
31 'qt': 'Qt4Agg', # qt3 not supported
32 'qt4': 'Qt4Agg',
32 'qt4': 'Qt4Agg',
33 'osx': 'MacOSX',
33 'osx': 'MacOSX',
34 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
34 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
35
35
36 # We also need a reverse backends2guis mapping that will properly choose which
36 # We also need a reverse backends2guis mapping that will properly choose which
37 # GUI support to activate based on the desired matplotlib backend. For the
37 # GUI support to activate based on the desired matplotlib backend. For the
38 # most part it's just a reverse of the above dict, but we also need to add a
38 # most part it's just a reverse of the above dict, but we also need to add a
39 # few others that map to the same GUI manually:
39 # few others that map to the same GUI manually:
40 backend2gui = dict(zip(backends.values(), backends.keys()))
40 backend2gui = dict(zip(backends.values(), backends.keys()))
41 # In the reverse mapping, there are a few extra valid matplotlib backends that
41 # In the reverse mapping, there are a few extra valid matplotlib backends that
42 # map to the same GUI support
42 # map to the same GUI support
43 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
43 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
44 backend2gui['WX'] = 'wx'
44 backend2gui['WX'] = 'wx'
45 backend2gui['CocoaAgg'] = 'osx'
45 backend2gui['CocoaAgg'] = 'osx'
46
46
47 #-----------------------------------------------------------------------------
47 #-----------------------------------------------------------------------------
48 # Matplotlib utilities
48 # Matplotlib utilities
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50
50
51
51
52 def getfigs(*fig_nums):
52 def getfigs(*fig_nums):
53 """Get a list of matplotlib figures by figure numbers.
53 """Get a list of matplotlib figures by figure numbers.
54
54
55 If no arguments are given, all available figures are returned. If the
55 If no arguments are given, all available figures are returned. If the
56 argument list contains references to invalid figures, a warning is printed
56 argument list contains references to invalid figures, a warning is printed
57 but the function continues pasting further figures.
57 but the function continues pasting further figures.
58
58
59 Parameters
59 Parameters
60 ----------
60 ----------
61 figs : tuple
61 figs : tuple
62 A tuple of ints giving the figure numbers of the figures to return.
62 A tuple of ints giving the figure numbers of the figures to return.
63 """
63 """
64 from matplotlib._pylab_helpers import Gcf
64 from matplotlib._pylab_helpers import Gcf
65 if not fig_nums:
65 if not fig_nums:
66 fig_managers = Gcf.get_all_fig_managers()
66 fig_managers = Gcf.get_all_fig_managers()
67 return [fm.canvas.figure for fm in fig_managers]
67 return [fm.canvas.figure for fm in fig_managers]
68 else:
68 else:
69 figs = []
69 figs = []
70 for num in fig_nums:
70 for num in fig_nums:
71 f = Gcf.figs.get(num)
71 f = Gcf.figs.get(num)
72 if f is None:
72 if f is None:
73 print('Warning: figure %s not available.' % num)
73 print('Warning: figure %s not available.' % num)
74 else:
74 else:
75 figs.append(f.canvas.figure)
75 figs.append(f.canvas.figure)
76 return figs
76 return figs
77
77
78
78
79 def figsize(sizex, sizey):
79 def figsize(sizex, sizey):
80 """Set the default figure size to be [sizex, sizey].
80 """Set the default figure size to be [sizex, sizey].
81
81
82 This is just an easy to remember, convenience wrapper that sets::
82 This is just an easy to remember, convenience wrapper that sets::
83
83
84 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
84 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
85 """
85 """
86 import matplotlib
86 import matplotlib
87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
88
88
89
89
90 def print_figure(fig, fmt='png'):
90 def print_figure(fig, fmt='png'):
91 """Convert a figure to svg or png for inline display."""
91 """Convert a figure to svg or png for inline display."""
92 # When there's an empty figure, we shouldn't return anything, otherwise we
92 # When there's an empty figure, we shouldn't return anything, otherwise we
93 # get big blank areas in the qt console.
93 # get big blank areas in the qt console.
94 if not fig.axes:
94 if not fig.axes:
95 return
95 return
96
96
97 fc = fig.get_facecolor()
97 fc = fig.get_facecolor()
98 ec = fig.get_edgecolor()
98 ec = fig.get_edgecolor()
99 fig.set_facecolor('white')
99 fig.set_facecolor('white')
100 fig.set_edgecolor('white')
100 fig.set_edgecolor('white')
101 try:
101 try:
102 string_io = StringIO()
102 string_io = StringIO()
103 # use 72 dpi to match QTConsole's dpi
103 # use 72 dpi to match QTConsole's dpi
104 fig.canvas.print_figure(string_io, format=fmt, dpi=72)
104 fig.canvas.print_figure(string_io, format=fmt, dpi=72)
105 data = string_io.getvalue()
105 data = string_io.getvalue()
106 finally:
106 finally:
107 fig.set_facecolor(fc)
107 fig.set_facecolor(fc)
108 fig.set_edgecolor(ec)
108 fig.set_edgecolor(ec)
109 return data
109 return data
110
110
111
111
112 # We need a little factory function here to create the closure where
112 # We need a little factory function here to create the closure where
113 # safe_execfile can live.
113 # safe_execfile can live.
114 def mpl_runner(safe_execfile):
114 def mpl_runner(safe_execfile):
115 """Factory to return a matplotlib-enabled runner for %run.
115 """Factory to return a matplotlib-enabled runner for %run.
116
116
117 Parameters
117 Parameters
118 ----------
118 ----------
119 safe_execfile : function
119 safe_execfile : function
120 This must be a function with the same interface as the
120 This must be a function with the same interface as the
121 :meth:`safe_execfile` method of IPython.
121 :meth:`safe_execfile` method of IPython.
122
122
123 Returns
123 Returns
124 -------
124 -------
125 A function suitable for use as the ``runner`` argument of the %run magic
125 A function suitable for use as the ``runner`` argument of the %run magic
126 function.
126 function.
127 """
127 """
128
128
129 def mpl_execfile(fname,*where,**kw):
129 def mpl_execfile(fname,*where,**kw):
130 """matplotlib-aware wrapper around safe_execfile.
130 """matplotlib-aware wrapper around safe_execfile.
131
131
132 Its interface is identical to that of the :func:`execfile` builtin.
132 Its interface is identical to that of the :func:`execfile` builtin.
133
133
134 This is ultimately a call to execfile(), but wrapped in safeties to
134 This is ultimately a call to execfile(), but wrapped in safeties to
135 properly handle interactive rendering."""
135 properly handle interactive rendering."""
136
136
137 import matplotlib
137 import matplotlib
138 import matplotlib.pylab as pylab
138 import matplotlib.pylab as pylab
139
139
140 #print '*** Matplotlib runner ***' # dbg
140 #print '*** Matplotlib runner ***' # dbg
141 # turn off rendering until end of script
141 # turn off rendering until end of script
142 is_interactive = matplotlib.rcParams['interactive']
142 is_interactive = matplotlib.rcParams['interactive']
143 matplotlib.interactive(False)
143 matplotlib.interactive(False)
144 safe_execfile(fname,*where,**kw)
144 safe_execfile(fname,*where,**kw)
145 matplotlib.interactive(is_interactive)
145 matplotlib.interactive(is_interactive)
146 # make rendering call now, if the user tried to do it
146 # make rendering call now, if the user tried to do it
147 if pylab.draw_if_interactive.called:
147 if pylab.draw_if_interactive.called:
148 pylab.draw()
148 pylab.draw()
149 pylab.draw_if_interactive.called = False
149 pylab.draw_if_interactive.called = False
150
150
151 return mpl_execfile
151 return mpl_execfile
152
152
153
153
154 def select_figure_format(shell, fmt):
154 def select_figure_format(shell, fmt):
155 """Select figure format for inline backend, either 'png' or 'svg'.
155 """Select figure format for inline backend, either 'png' or 'svg'.
156
156
157 Using this method ensures only one figure format is active at a time.
157 Using this method ensures only one figure format is active at a time.
158 """
158 """
159 from matplotlib.figure import Figure
159 from matplotlib.figure import Figure
160 from IPython.zmq.pylab import backend_inline
160 from IPython.zmq.pylab import backend_inline
161
161
162 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
162 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
163 png_formatter = shell.display_formatter.formatters['image/png']
163 png_formatter = shell.display_formatter.formatters['image/png']
164
164
165 if fmt=='png':
165 if fmt=='png':
166 svg_formatter.type_printers.pop(Figure, None)
166 svg_formatter.type_printers.pop(Figure, None)
167 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
167 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
168 elif fmt=='svg':
168 elif fmt=='svg':
169 png_formatter.type_printers.pop(Figure, None)
169 png_formatter.type_printers.pop(Figure, None)
170 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
170 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
171 else:
171 else:
172 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
172 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
173
173
174 # set the format to be used in the backend()
174 # set the format to be used in the backend()
175 backend_inline._figure_format = fmt
175 backend_inline._figure_format = fmt
176
176
177 #-----------------------------------------------------------------------------
177 #-----------------------------------------------------------------------------
178 # Code for initializing matplotlib and importing pylab
178 # Code for initializing matplotlib and importing pylab
179 #-----------------------------------------------------------------------------
179 #-----------------------------------------------------------------------------
180
180
181
181
182 def find_gui_and_backend(gui=None):
182 def find_gui_and_backend(gui=None):
183 """Given a gui string return the gui and mpl backend.
183 """Given a gui string return the gui and mpl backend.
184
184
185 Parameters
185 Parameters
186 ----------
186 ----------
187 gui : str
187 gui : str
188 Can be one of ('tk','gtk','wx','qt','qt4','inline').
188 Can be one of ('tk','gtk','wx','qt','qt4','inline').
189
189
190 Returns
190 Returns
191 -------
191 -------
192 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
192 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
193 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
193 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
194 """
194 """
195
195
196 import matplotlib
196 import matplotlib
197
197
198 if gui:
198 if gui:
199 # select backend based on requested gui
199 # select backend based on requested gui
200 backend = backends[gui]
200 backend = backends[gui]
201 else:
201 else:
202 backend = matplotlib.rcParams['backend']
202 backend = matplotlib.rcParams['backend']
203 # In this case, we need to find what the appropriate gui selection call
203 # In this case, we need to find what the appropriate gui selection call
204 # should be for IPython, so we can activate inputhook accordingly
204 # should be for IPython, so we can activate inputhook accordingly
205 gui = backend2gui.get(backend, None)
205 gui = backend2gui.get(backend, None)
206 return gui, backend
206 return gui, backend
207
207
208
208
209 def activate_matplotlib(backend):
209 def activate_matplotlib(backend):
210 """Activate the given backend and set interactive to True."""
210 """Activate the given backend and set interactive to True."""
211
211
212 import matplotlib
212 import matplotlib
213 if backend.startswith('module://'):
213 if backend.startswith('module://'):
214 # Work around bug in matplotlib: matplotlib.use converts the
214 # Work around bug in matplotlib: matplotlib.use converts the
215 # backend_id to lowercase even if a module name is specified!
215 # backend_id to lowercase even if a module name is specified!
216 matplotlib.rcParams['backend'] = backend
216 matplotlib.rcParams['backend'] = backend
217 else:
217 else:
218 matplotlib.use(backend)
218 matplotlib.use(backend)
219 matplotlib.interactive(True)
219 matplotlib.interactive(True)
220
220
221 # This must be imported last in the matplotlib series, after
221 # This must be imported last in the matplotlib series, after
222 # backend/interactivity choices have been made
222 # backend/interactivity choices have been made
223 import matplotlib.pylab as pylab
223 import matplotlib.pylab as pylab
224
224
225 # XXX For now leave this commented out, but depending on discussions with
225 # XXX For now leave this commented out, but depending on discussions with
226 # mpl-dev, we may be able to allow interactive switching...
226 # mpl-dev, we may be able to allow interactive switching...
227 #import matplotlib.pyplot
227 #import matplotlib.pyplot
228 #matplotlib.pyplot.switch_backend(backend)
228 #matplotlib.pyplot.switch_backend(backend)
229
229
230 pylab.show._needmain = False
230 pylab.show._needmain = False
231 # We need to detect at runtime whether show() is called by the user.
231 # We need to detect at runtime whether show() is called by the user.
232 # For this, we wrap it into a decorator which adds a 'called' flag.
232 # For this, we wrap it into a decorator which adds a 'called' flag.
233 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
233 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
234
234
235 def import_pylab(user_ns, backend, import_all=True, shell=None):
235 def import_pylab(user_ns, backend, import_all=True, shell=None):
236 """Import the standard pylab symbols into user_ns."""
236 """Import the standard pylab symbols into user_ns."""
237
237
238 # Import numpy as np/pyplot as plt are conventions we're trying to
238 # Import numpy as np/pyplot as plt are conventions we're trying to
239 # somewhat standardize on. Making them available to users by default
239 # somewhat standardize on. Making them available to users by default
240 # will greatly help this.
240 # will greatly help this.
241 s = ("import numpy\n"
241 s = ("import numpy\n"
242 "import matplotlib\n"
242 "import matplotlib\n"
243 "from matplotlib import pylab, mlab, pyplot\n"
243 "from matplotlib import pylab, mlab, pyplot\n"
244 "np = numpy\n"
244 "np = numpy\n"
245 "plt = pyplot\n"
245 "plt = pyplot\n"
246 )
246 )
247 exec s in user_ns
247 exec s in user_ns
248
248
249 if shell is not None:
249 if shell is not None:
250 exec s in shell.user_ns_hidden
250 exec s in shell.user_ns_hidden
251 # If using our svg payload backend, register the post-execution
251 # If using our svg payload backend, register the post-execution
252 # function that will pick up the results for display. This can only be
252 # function that will pick up the results for display. This can only be
253 # done with access to the real shell object.
253 # done with access to the real shell object.
254 #
254 #
255 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
255 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
256
256
257 cfg = InlineBackendConfig.instance(config=shell.config)
257 cfg = InlineBackendConfig.instance(config=shell.config)
258 cfg.shell = shell
258 cfg.shell = shell
259
259
260 if backend == backends['inline']:
260 if backend == backends['inline']:
261 from IPython.zmq.pylab.backend_inline import flush_figures
261 from IPython.zmq.pylab.backend_inline import flush_figures
262 from matplotlib import pyplot
262 from matplotlib import pyplot
263 shell.register_post_execute(flush_figures)
263 shell.register_post_execute(flush_figures)
264 # load inline_rc
264 # load inline_rc
265 pyplot.rcParams.update(cfg.rc)
265 pyplot.rcParams.update(cfg.rc)
266
266
267 # Add 'figsize' to pyplot and to the user's namespace
267 # Add 'figsize' to pyplot and to the user's namespace
268 user_ns['figsize'] = pyplot.figsize = figsize
268 user_ns['figsize'] = pyplot.figsize = figsize
269 shell.user_ns_hidden['figsize'] = figsize
269 shell.user_ns_hidden['figsize'] = figsize
270
270
271 # Setup the default figure format
271 # Setup the default figure format
272 fmt = cfg.figure_format
272 fmt = cfg.figure_format
273 select_figure_format(shell, fmt)
273 select_figure_format(shell, fmt)
274
274
275 # The old pastefig function has been replaced by display
275 # The old pastefig function has been replaced by display
276 from IPython.core.display import display
276 from IPython.core.display import display
277 # Add display and display_png to the user's namespace
277 # Add display and display_png to the user's namespace
278 user_ns['display'] = display
278 user_ns['display'] = display
279 shell.user_ns_hidden['display'] = display
279 shell.user_ns_hidden['display'] = display
280 user_ns['getfigs'] = getfigs
280 user_ns['getfigs'] = getfigs
281 shell.user_ns_hidden['getfigs'] = getfigs
281 shell.user_ns_hidden['getfigs'] = getfigs
282
282
283 if import_all:
283 if import_all:
284 s = ("from matplotlib.pylab import *\n"
284 s = ("from matplotlib.pylab import *\n"
285 "from numpy import *\n")
285 "from numpy import *\n")
286 exec s in user_ns
286 exec s in user_ns
287 if shell is not None:
287 if shell is not None:
288 exec s in shell.user_ns_hidden
288 exec s in shell.user_ns_hidden
289
289
290
290
291 def pylab_activate(user_ns, gui=None, import_all=True):
291 def pylab_activate(user_ns, gui=None, import_all=True):
292 """Activate pylab mode in the user's namespace.
292 """Activate pylab mode in the user's namespace.
293
293
294 Loads and initializes numpy, matplotlib and friends for interactive use.
294 Loads and initializes numpy, matplotlib and friends for interactive use.
295
295
296 Parameters
296 Parameters
297 ----------
297 ----------
298 user_ns : dict
298 user_ns : dict
299 Namespace where the imports will occur.
299 Namespace where the imports will occur.
300
300
301 gui : optional, string
301 gui : optional, string
302 A valid gui name following the conventions of the %gui magic.
302 A valid gui name following the conventions of the %gui magic.
303
303
304 import_all : optional, boolean
304 import_all : optional, boolean
305 If true, an 'import *' is done from numpy and pylab.
305 If true, an 'import *' is done from numpy and pylab.
306
306
307 Returns
307 Returns
308 -------
308 -------
309 The actual gui used (if not given as input, it was obtained from matplotlib
309 The actual gui used (if not given as input, it was obtained from matplotlib
310 itself, and will be needed next to configure IPython's gui integration.
310 itself, and will be needed next to configure IPython's gui integration.
311 """
311 """
312 gui, backend = find_gui_and_backend(gui)
312 gui, backend = find_gui_and_backend(gui)
313 activate_matplotlib(backend)
313 activate_matplotlib(backend)
314 import_pylab(user_ns, backend)
314 import_pylab(user_ns, backend, import_all)
315
315
316 print """
316 print """
317 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
317 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
318 For more information, type 'help(pylab)'.""" % backend
318 For more information, type 'help(pylab)'.""" % backend
319
319
320 return gui
320 return gui
321
321
General Comments 0
You need to be logged in to leave comments. Login now