##// END OF EJS Templates
use config.Global.inline_rc to initialize matplotlib with the inline backend....
MinRK -
Show More
@@ -1,284 +1,294 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 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
33 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Matplotlib utilities
36 # Matplotlib utilities
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39
39
40 def getfigs(*fig_nums):
40 def getfigs(*fig_nums):
41 """Get a list of matplotlib figures by figure numbers.
41 """Get a list of matplotlib figures by figure numbers.
42
42
43 If no arguments are given, all available figures are returned. If the
43 If no arguments are given, all available figures are returned. If the
44 argument list contains references to invalid figures, a warning is printed
44 argument list contains references to invalid figures, a warning is printed
45 but the function continues pasting further figures.
45 but the function continues pasting further figures.
46
46
47 Parameters
47 Parameters
48 ----------
48 ----------
49 figs : tuple
49 figs : tuple
50 A tuple of ints giving the figure numbers of the figures to return.
50 A tuple of ints giving the figure numbers of the figures to return.
51 """
51 """
52 from matplotlib._pylab_helpers import Gcf
52 from matplotlib._pylab_helpers import Gcf
53 if not fig_nums:
53 if not fig_nums:
54 fig_managers = Gcf.get_all_fig_managers()
54 fig_managers = Gcf.get_all_fig_managers()
55 return [fm.canvas.figure for fm in fig_managers]
55 return [fm.canvas.figure for fm in fig_managers]
56 else:
56 else:
57 figs = []
57 figs = []
58 for num in fig_nums:
58 for num in fig_nums:
59 f = Gcf.figs.get(num)
59 f = Gcf.figs.get(num)
60 if f is None:
60 if f is None:
61 print('Warning: figure %s not available.' % num)
61 print('Warning: figure %s not available.' % num)
62 figs.append(f.canvas.figure)
62 figs.append(f.canvas.figure)
63 return figs
63 return figs
64
64
65
65
66 def figsize(sizex, sizey):
66 def figsize(sizex, sizey):
67 """Set the default figure size to be [sizex, sizey].
67 """Set the default figure size to be [sizex, sizey].
68
68
69 This is just an easy to remember, convenience wrapper that sets::
69 This is just an easy to remember, convenience wrapper that sets::
70
70
71 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
71 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
72 """
72 """
73 import matplotlib
73 import matplotlib
74 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
74 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
75
75
76
76
77 def figure_to_svg(fig):
77 def figure_to_svg(fig):
78 """Convert a figure to svg for inline display."""
78 """Convert a figure to svg for inline display."""
79 fc = fig.get_facecolor()
79 fc = fig.get_facecolor()
80 ec = fig.get_edgecolor()
80 ec = fig.get_edgecolor()
81 fig.set_facecolor('white')
81 fig.set_facecolor('white')
82 fig.set_edgecolor('white')
82 fig.set_edgecolor('white')
83 try:
83 try:
84 string_io = StringIO()
84 string_io = StringIO()
85 fig.canvas.print_figure(string_io, format='svg')
85 fig.canvas.print_figure(string_io, format='svg')
86 svg = string_io.getvalue()
86 svg = string_io.getvalue()
87 finally:
87 finally:
88 fig.set_facecolor(fc)
88 fig.set_facecolor(fc)
89 fig.set_edgecolor(ec)
89 fig.set_edgecolor(ec)
90 return svg
90 return svg
91
91
92
92
93 # We need a little factory function here to create the closure where
93 # We need a little factory function here to create the closure where
94 # safe_execfile can live.
94 # safe_execfile can live.
95 def mpl_runner(safe_execfile):
95 def mpl_runner(safe_execfile):
96 """Factory to return a matplotlib-enabled runner for %run.
96 """Factory to return a matplotlib-enabled runner for %run.
97
97
98 Parameters
98 Parameters
99 ----------
99 ----------
100 safe_execfile : function
100 safe_execfile : function
101 This must be a function with the same interface as the
101 This must be a function with the same interface as the
102 :meth:`safe_execfile` method of IPython.
102 :meth:`safe_execfile` method of IPython.
103
103
104 Returns
104 Returns
105 -------
105 -------
106 A function suitable for use as the ``runner`` argument of the %run magic
106 A function suitable for use as the ``runner`` argument of the %run magic
107 function.
107 function.
108 """
108 """
109
109
110 def mpl_execfile(fname,*where,**kw):
110 def mpl_execfile(fname,*where,**kw):
111 """matplotlib-aware wrapper around safe_execfile.
111 """matplotlib-aware wrapper around safe_execfile.
112
112
113 Its interface is identical to that of the :func:`execfile` builtin.
113 Its interface is identical to that of the :func:`execfile` builtin.
114
114
115 This is ultimately a call to execfile(), but wrapped in safeties to
115 This is ultimately a call to execfile(), but wrapped in safeties to
116 properly handle interactive rendering."""
116 properly handle interactive rendering."""
117
117
118 import matplotlib
118 import matplotlib
119 import matplotlib.pylab as pylab
119 import matplotlib.pylab as pylab
120
120
121 #print '*** Matplotlib runner ***' # dbg
121 #print '*** Matplotlib runner ***' # dbg
122 # turn off rendering until end of script
122 # turn off rendering until end of script
123 is_interactive = matplotlib.rcParams['interactive']
123 is_interactive = matplotlib.rcParams['interactive']
124 matplotlib.interactive(False)
124 matplotlib.interactive(False)
125 safe_execfile(fname,*where,**kw)
125 safe_execfile(fname,*where,**kw)
126 matplotlib.interactive(is_interactive)
126 matplotlib.interactive(is_interactive)
127 # make rendering call now, if the user tried to do it
127 # make rendering call now, if the user tried to do it
128 if pylab.draw_if_interactive.called:
128 if pylab.draw_if_interactive.called:
129 pylab.draw()
129 pylab.draw()
130 pylab.draw_if_interactive.called = False
130 pylab.draw_if_interactive.called = False
131
131
132 return mpl_execfile
132 return mpl_execfile
133
133
134
134
135 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
136 # Code for initializing matplotlib and importing pylab
136 # Code for initializing matplotlib and importing pylab
137 #-----------------------------------------------------------------------------
137 #-----------------------------------------------------------------------------
138
138
139
139
140 def find_gui_and_backend(gui=None):
140 def find_gui_and_backend(gui=None):
141 """Given a gui string return the gui and mpl backend.
141 """Given a gui string return the gui and mpl backend.
142
142
143 Parameters
143 Parameters
144 ----------
144 ----------
145 gui : str
145 gui : str
146 Can be one of ('tk','gtk','wx','qt','qt4','inline').
146 Can be one of ('tk','gtk','wx','qt','qt4','inline').
147
147
148 Returns
148 Returns
149 -------
149 -------
150 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
150 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
151 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
151 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
152 """
152 """
153
153
154 import matplotlib
154 import matplotlib
155
155
156 if gui:
156 if gui:
157 # select backend based on requested gui
157 # select backend based on requested gui
158 backend = backends[gui]
158 backend = backends[gui]
159 else:
159 else:
160 backend = matplotlib.rcParams['backend']
160 backend = matplotlib.rcParams['backend']
161 # In this case, we need to find what the appropriate gui selection call
161 # In this case, we need to find what the appropriate gui selection call
162 # should be for IPython, so we can activate inputhook accordingly
162 # should be for IPython, so we can activate inputhook accordingly
163 g2b = backends # maps gui names to mpl backend names
163 g2b = backends # maps gui names to mpl backend names
164 b2g = dict(zip(g2b.values(), g2b.keys())) # reverse dict
164 b2g = dict(zip(g2b.values(), g2b.keys())) # reverse dict
165 gui = b2g.get(backend, None)
165 gui = b2g.get(backend, None)
166 return gui, backend
166 return gui, backend
167
167
168
168
169 def activate_matplotlib(backend):
169 def activate_matplotlib(backend):
170 """Activate the given backend and set interactive to True."""
170 """Activate the given backend and set interactive to True."""
171
171
172 import matplotlib
172 import matplotlib
173 if backend.startswith('module://'):
173 if backend.startswith('module://'):
174 # Work around bug in matplotlib: matplotlib.use converts the
174 # Work around bug in matplotlib: matplotlib.use converts the
175 # backend_id to lowercase even if a module name is specified!
175 # backend_id to lowercase even if a module name is specified!
176 matplotlib.rcParams['backend'] = backend
176 matplotlib.rcParams['backend'] = backend
177 else:
177 else:
178 matplotlib.use(backend)
178 matplotlib.use(backend)
179 matplotlib.interactive(True)
179 matplotlib.interactive(True)
180
180
181 # This must be imported last in the matplotlib series, after
181 # This must be imported last in the matplotlib series, after
182 # backend/interactivity choices have been made
182 # backend/interactivity choices have been made
183 import matplotlib.pylab as pylab
183 import matplotlib.pylab as pylab
184
184
185 # XXX For now leave this commented out, but depending on discussions with
185 # XXX For now leave this commented out, but depending on discussions with
186 # mpl-dev, we may be able to allow interactive switching...
186 # mpl-dev, we may be able to allow interactive switching...
187 #import matplotlib.pyplot
187 #import matplotlib.pyplot
188 #matplotlib.pyplot.switch_backend(backend)
188 #matplotlib.pyplot.switch_backend(backend)
189
189
190 pylab.show._needmain = False
190 pylab.show._needmain = False
191 # We need to detect at runtime whether show() is called by the user.
191 # We need to detect at runtime whether show() is called by the user.
192 # For this, we wrap it into a decorator which adds a 'called' flag.
192 # For this, we wrap it into a decorator which adds a 'called' flag.
193 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
193 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
194
194
195
195
196 def import_pylab(user_ns, backend, import_all=True, shell=None):
196 def import_pylab(user_ns, backend, import_all=True, shell=None):
197 """Import the standard pylab symbols into user_ns."""
197 """Import the standard pylab symbols into user_ns."""
198
198
199 # Import numpy as np/pyplot as plt are conventions we're trying to
199 # Import numpy as np/pyplot as plt are conventions we're trying to
200 # somewhat standardize on. Making them available to users by default
200 # somewhat standardize on. Making them available to users by default
201 # will greatly help this.
201 # will greatly help this.
202 s = ("import numpy\n"
202 s = ("import numpy\n"
203 "import matplotlib\n"
203 "import matplotlib\n"
204 "from matplotlib import pylab, mlab, pyplot\n"
204 "from matplotlib import pylab, mlab, pyplot\n"
205 "np = numpy\n"
205 "np = numpy\n"
206 "plt = pyplot\n"
206 "plt = pyplot\n"
207 )
207 )
208 exec s in user_ns
208 exec s in user_ns
209
209
210 if shell is not None:
210 if shell is not None:
211 exec s in shell.user_ns_hidden
211 exec s in shell.user_ns_hidden
212 # If using our svg payload backend, register the post-execution
212 # If using our svg payload backend, register the post-execution
213 # function that will pick up the results for display. This can only be
213 # function that will pick up the results for display. This can only be
214 # done with access to the real shell object.
214 # done with access to the real shell object.
215 if backend == backends['inline']:
215 if backend == backends['inline']:
216 from IPython.zmq.pylab.backend_inline import flush_svg
216 from IPython.zmq.pylab.backend_inline import flush_svg
217 from matplotlib import pyplot
217 from matplotlib import pyplot
218 shell.register_post_execute(flush_svg)
218 shell.register_post_execute(flush_svg)
219 # The typical default figure size is too large for inline use. We
219 # The typical default figure size is too large for inline use,
220 # might make this a user-configurable parameter later.
220 # so we shrink the figure size to 6x4, and tweak fonts to
221 figsize(6.0, 4.0)
221 # make that fit. This is configurable via Global.inline_rc,
222 # or rather it will be once the zmq kernel is hooked up to
223 # the config system.
224
225 default_rc = {
226 'figure.figsize': (6.0,4.0),
222 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
227 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
223 pyplot.rcParams['font.size'] = 10
228 'font.size': 10,
224 # 10pt still needs a little more room on the xlabel:
229 # 10pt still needs a little more room on the xlabel:
225 pyplot.rcParams['figure.subplot.bottom'] = .125
230 'figure.subplot.bottom' : .125
231 }
232 rc = getattr(shell.config.Global, 'inline_rc', default_rc)
233 pyplot.rcParams.update(rc)
234 shell.config.Global.inline_rc = rc
235
226 # Add 'figsize' to pyplot and to the user's namespace
236 # Add 'figsize' to pyplot and to the user's namespace
227 user_ns['figsize'] = pyplot.figsize = figsize
237 user_ns['figsize'] = pyplot.figsize = figsize
228 shell.user_ns_hidden['figsize'] = figsize
238 shell.user_ns_hidden['figsize'] = figsize
229
239
230 # The old pastefig function has been replaced by display
240 # The old pastefig function has been replaced by display
231 # Always add this svg formatter so display works.
241 # Always add this svg formatter so display works.
232 from IPython.zmq.pylab.backend_inline import figure_to_svg
242 from IPython.zmq.pylab.backend_inline import figure_to_svg
233 from IPython.core.display import display, display_svg
243 from IPython.core.display import display, display_svg
234 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
244 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
235 svg_formatter.for_type_by_name(
245 svg_formatter.for_type_by_name(
236 'matplotlib.figure','Figure',figure_to_svg
246 'matplotlib.figure','Figure',figure_to_svg
237 )
247 )
238 # Add display and display_png to the user's namespace
248 # Add display and display_png to the user's namespace
239 user_ns['display'] = display
249 user_ns['display'] = display
240 shell.user_ns_hidden['display'] = display
250 shell.user_ns_hidden['display'] = display
241 user_ns['display_svg'] = display_svg
251 user_ns['display_svg'] = display_svg
242 shell.user_ns_hidden['display_svg'] = display_svg
252 shell.user_ns_hidden['display_svg'] = display_svg
243 user_ns['getfigs'] = getfigs
253 user_ns['getfigs'] = getfigs
244 shell.user_ns_hidden['getfigs'] = getfigs
254 shell.user_ns_hidden['getfigs'] = getfigs
245
255
246 if import_all:
256 if import_all:
247 s = ("from matplotlib.pylab import *\n"
257 s = ("from matplotlib.pylab import *\n"
248 "from numpy import *\n")
258 "from numpy import *\n")
249 exec s in user_ns
259 exec s in user_ns
250 if shell is not None:
260 if shell is not None:
251 exec s in shell.user_ns_hidden
261 exec s in shell.user_ns_hidden
252
262
253
263
254 def pylab_activate(user_ns, gui=None, import_all=True):
264 def pylab_activate(user_ns, gui=None, import_all=True):
255 """Activate pylab mode in the user's namespace.
265 """Activate pylab mode in the user's namespace.
256
266
257 Loads and initializes numpy, matplotlib and friends for interactive use.
267 Loads and initializes numpy, matplotlib and friends for interactive use.
258
268
259 Parameters
269 Parameters
260 ----------
270 ----------
261 user_ns : dict
271 user_ns : dict
262 Namespace where the imports will occur.
272 Namespace where the imports will occur.
263
273
264 gui : optional, string
274 gui : optional, string
265 A valid gui name following the conventions of the %gui magic.
275 A valid gui name following the conventions of the %gui magic.
266
276
267 import_all : optional, boolean
277 import_all : optional, boolean
268 If true, an 'import *' is done from numpy and pylab.
278 If true, an 'import *' is done from numpy and pylab.
269
279
270 Returns
280 Returns
271 -------
281 -------
272 The actual gui used (if not given as input, it was obtained from matplotlib
282 The actual gui used (if not given as input, it was obtained from matplotlib
273 itself, and will be needed next to configure IPython's gui integration.
283 itself, and will be needed next to configure IPython's gui integration.
274 """
284 """
275 gui, backend = find_gui_and_backend(gui)
285 gui, backend = find_gui_and_backend(gui)
276 activate_matplotlib(backend)
286 activate_matplotlib(backend)
277 import_pylab(user_ns, backend)
287 import_pylab(user_ns, backend)
278
288
279 print """
289 print """
280 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
290 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
281 For more information, type 'help(pylab)'.""" % backend
291 For more information, type 'help(pylab)'.""" % backend
282
292
283 return gui
293 return gui
284
294
General Comments 0
You need to be logged in to leave comments. Login now