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