##// END OF EJS Templates
Set default figure size in inline mode to (6,4)....
Fernando Perez -
Show More
@@ -1,196 +1,202 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 IPython.utils.decorators import flag_calls
22 from IPython.utils.decorators import flag_calls
23
23
24 # If user specifies a GUI, that dictates the backend, otherwise we read the
24 # If user specifies a GUI, that dictates the backend, otherwise we read the
25 # user's mpl default from the mpl rc structure
25 # user's mpl default from the mpl rc structure
26 backends = {'tk': 'TkAgg',
26 backends = {'tk': 'TkAgg',
27 'gtk': 'GTKAgg',
27 'gtk': 'GTKAgg',
28 'wx': 'WXAgg',
28 'wx': 'WXAgg',
29 'qt': 'Qt4Agg', # qt3 not supported
29 'qt': 'Qt4Agg', # qt3 not supported
30 'qt4': 'Qt4Agg',
30 'qt4': 'Qt4Agg',
31 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
31 'inline' : 'module://IPython.zmq.pylab.backend_inline'}
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Main classes and functions
34 # Main classes and functions
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37
37
38 def find_gui_and_backend(gui=None):
38 def find_gui_and_backend(gui=None):
39 """Given a gui string return the gui and mpl backend.
39 """Given a gui string return the gui and mpl backend.
40
40
41 Parameters
41 Parameters
42 ----------
42 ----------
43 gui : str
43 gui : str
44 Can be one of ('tk','gtk','wx','qt','qt4','inline').
44 Can be one of ('tk','gtk','wx','qt','qt4','inline').
45
45
46 Returns
46 Returns
47 -------
47 -------
48 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
48 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
49 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
49 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
50 """
50 """
51
51
52 import matplotlib
52 import matplotlib
53
53
54 if gui:
54 if gui:
55 # select backend based on requested gui
55 # select backend based on requested gui
56 backend = backends[gui]
56 backend = backends[gui]
57 else:
57 else:
58 backend = matplotlib.rcParams['backend']
58 backend = matplotlib.rcParams['backend']
59 # In this case, we need to find what the appropriate gui selection call
59 # In this case, we need to find what the appropriate gui selection call
60 # should be for IPython, so we can activate inputhook accordingly
60 # should be for IPython, so we can activate inputhook accordingly
61 g2b = backends # maps gui names to mpl backend names
61 g2b = backends # maps gui names to mpl backend names
62 b2g = dict(zip(g2b.values(), g2b.keys())) # reverse dict
62 b2g = dict(zip(g2b.values(), g2b.keys())) # reverse dict
63 gui = b2g.get(backend, None)
63 gui = b2g.get(backend, None)
64 return gui, backend
64 return gui, backend
65
65
66
66
67 def activate_matplotlib(backend):
67 def activate_matplotlib(backend):
68 """Activate the given backend and set interactive to True."""
68 """Activate the given backend and set interactive to True."""
69
69
70 import matplotlib
70 import matplotlib
71 if backend.startswith('module://'):
71 if backend.startswith('module://'):
72 # Work around bug in matplotlib: matplotlib.use converts the
72 # Work around bug in matplotlib: matplotlib.use converts the
73 # backend_id to lowercase even if a module name is specified!
73 # backend_id to lowercase even if a module name is specified!
74 matplotlib.rcParams['backend'] = backend
74 matplotlib.rcParams['backend'] = backend
75 else:
75 else:
76 matplotlib.use(backend)
76 matplotlib.use(backend)
77 matplotlib.interactive(True)
77 matplotlib.interactive(True)
78
78
79 # This must be imported last in the matplotlib series, after
79 # This must be imported last in the matplotlib series, after
80 # backend/interactivity choices have been made
80 # backend/interactivity choices have been made
81 import matplotlib.pylab as pylab
81 import matplotlib.pylab as pylab
82
82
83 # XXX For now leave this commented out, but depending on discussions with
83 # XXX For now leave this commented out, but depending on discussions with
84 # mpl-dev, we may be able to allow interactive switching...
84 # mpl-dev, we may be able to allow interactive switching...
85 #import matplotlib.pyplot
85 #import matplotlib.pyplot
86 #matplotlib.pyplot.switch_backend(backend)
86 #matplotlib.pyplot.switch_backend(backend)
87
87
88 pylab.show._needmain = False
88 pylab.show._needmain = False
89 # We need to detect at runtime whether show() is called by the user.
89 # We need to detect at runtime whether show() is called by the user.
90 # For this, we wrap it into a decorator which adds a 'called' flag.
90 # For this, we wrap it into a decorator which adds a 'called' flag.
91 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
91 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
92
92
93
93
94 def import_pylab(user_ns, backend, import_all=True, shell=None):
94 def import_pylab(user_ns, backend, import_all=True, shell=None):
95 """Import the standard pylab symbols into user_ns."""
95 """Import the standard pylab symbols into user_ns."""
96
96
97 # Import numpy as np/pyplot as plt are conventions we're trying to
97 # Import numpy as np/pyplot as plt are conventions we're trying to
98 # somewhat standardize on. Making them available to users by default
98 # somewhat standardize on. Making them available to users by default
99 # will greatly help this.
99 # will greatly help this.
100 exec ("import numpy\n"
100 exec ("import numpy\n"
101 "import matplotlib\n"
101 "import matplotlib\n"
102 "from matplotlib import pylab, mlab, pyplot\n"
102 "from matplotlib import pylab, mlab, pyplot\n"
103 "np = numpy\n"
103 "np = numpy\n"
104 "plt = pyplot\n"
104 "plt = pyplot\n"
105 ) in user_ns
105 ) in user_ns
106
106
107 if shell is not None:
107 if shell is not None:
108 # If using our svg payload backend, register the post-execution
108 # If using our svg payload backend, register the post-execution
109 # function that will pick up the results for display. This can only be
109 # function that will pick up the results for display. This can only be
110 # done with access to the real shell object.
110 # done with access to the real shell object.
111 if backend == backends['inline']:
111 if backend == backends['inline']:
112 from IPython.zmq.pylab.backend_inline import flush_svg
112 from IPython.zmq.pylab.backend_inline import flush_svg, figsize
113 from matplotlib import pyplot
113 shell.register_post_execute(flush_svg)
114 shell.register_post_execute(flush_svg)
115 # The typical default figure size is too large for inline use. We
116 # might make this a user-configurable parameter later.
117 figsize(6.0, 4.0)
118 # Add 'figsize' to pyplot and to the user's namespace
119 user_ns['figsize'] = pyplot.figsize = figsize
114 else:
120 else:
115 from IPython.zmq.pylab.backend_inline import pastefig
121 from IPython.zmq.pylab.backend_inline import pastefig
116 from matplotlib import pyplot
122 from matplotlib import pyplot
117 # Add 'paste' to pyplot and to the user's namespace
123 # Add 'paste' to pyplot and to the user's namespace
118 user_ns['pastefig'] = pyplot.pastefig = pastefig
124 user_ns['pastefig'] = pyplot.pastefig = pastefig
119
125
120 if import_all:
126 if import_all:
121 exec("from matplotlib.pylab import *\n"
127 exec("from matplotlib.pylab import *\n"
122 "from numpy import *\n") in user_ns
128 "from numpy import *\n") in user_ns
123
129
124
130
125 def pylab_activate(user_ns, gui=None, import_all=True):
131 def pylab_activate(user_ns, gui=None, import_all=True):
126 """Activate pylab mode in the user's namespace.
132 """Activate pylab mode in the user's namespace.
127
133
128 Loads and initializes numpy, matplotlib and friends for interactive use.
134 Loads and initializes numpy, matplotlib and friends for interactive use.
129
135
130 Parameters
136 Parameters
131 ----------
137 ----------
132 user_ns : dict
138 user_ns : dict
133 Namespace where the imports will occur.
139 Namespace where the imports will occur.
134
140
135 gui : optional, string
141 gui : optional, string
136 A valid gui name following the conventions of the %gui magic.
142 A valid gui name following the conventions of the %gui magic.
137
143
138 import_all : optional, boolean
144 import_all : optional, boolean
139 If true, an 'import *' is done from numpy and pylab.
145 If true, an 'import *' is done from numpy and pylab.
140
146
141 Returns
147 Returns
142 -------
148 -------
143 The actual gui used (if not given as input, it was obtained from matplotlib
149 The actual gui used (if not given as input, it was obtained from matplotlib
144 itself, and will be needed next to configure IPython's gui integration.
150 itself, and will be needed next to configure IPython's gui integration.
145 """
151 """
146 gui, backend = find_gui_and_backend(gui)
152 gui, backend = find_gui_and_backend(gui)
147 activate_matplotlib(backend)
153 activate_matplotlib(backend)
148 import_pylab(user_ns, backend)
154 import_pylab(user_ns, backend)
149
155
150 print """
156 print """
151 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
157 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
152 For more information, type 'help(pylab)'.""" % backend
158 For more information, type 'help(pylab)'.""" % backend
153
159
154 return gui
160 return gui
155
161
156 # We need a little factory function here to create the closure where
162 # We need a little factory function here to create the closure where
157 # safe_execfile can live.
163 # safe_execfile can live.
158 def mpl_runner(safe_execfile):
164 def mpl_runner(safe_execfile):
159 """Factory to return a matplotlib-enabled runner for %run.
165 """Factory to return a matplotlib-enabled runner for %run.
160
166
161 Parameters
167 Parameters
162 ----------
168 ----------
163 safe_execfile : function
169 safe_execfile : function
164 This must be a function with the same interface as the
170 This must be a function with the same interface as the
165 :meth:`safe_execfile` method of IPython.
171 :meth:`safe_execfile` method of IPython.
166
172
167 Returns
173 Returns
168 -------
174 -------
169 A function suitable for use as the ``runner`` argument of the %run magic
175 A function suitable for use as the ``runner`` argument of the %run magic
170 function.
176 function.
171 """
177 """
172
178
173 def mpl_execfile(fname,*where,**kw):
179 def mpl_execfile(fname,*where,**kw):
174 """matplotlib-aware wrapper around safe_execfile.
180 """matplotlib-aware wrapper around safe_execfile.
175
181
176 Its interface is identical to that of the :func:`execfile` builtin.
182 Its interface is identical to that of the :func:`execfile` builtin.
177
183
178 This is ultimately a call to execfile(), but wrapped in safeties to
184 This is ultimately a call to execfile(), but wrapped in safeties to
179 properly handle interactive rendering."""
185 properly handle interactive rendering."""
180
186
181 import matplotlib
187 import matplotlib
182 import matplotlib.pylab as pylab
188 import matplotlib.pylab as pylab
183
189
184 #print '*** Matplotlib runner ***' # dbg
190 #print '*** Matplotlib runner ***' # dbg
185 # turn off rendering until end of script
191 # turn off rendering until end of script
186 is_interactive = matplotlib.rcParams['interactive']
192 is_interactive = matplotlib.rcParams['interactive']
187 matplotlib.interactive(False)
193 matplotlib.interactive(False)
188 safe_execfile(fname,*where,**kw)
194 safe_execfile(fname,*where,**kw)
189 matplotlib.interactive(is_interactive)
195 matplotlib.interactive(is_interactive)
190 # make rendering call now, if the user tried to do it
196 # make rendering call now, if the user tried to do it
191 if pylab.draw_if_interactive.called:
197 if pylab.draw_if_interactive.called:
192 pylab.draw()
198 pylab.draw()
193 pylab.draw_if_interactive.called = False
199 pylab.draw_if_interactive.called = False
194
200
195 return mpl_execfile
201 return mpl_execfile
196
202
@@ -1,112 +1,119 b''
1 """Produce SVG versions of active plots for display by the rich Qt frontend.
1 """Produce SVG versions of active plots for display by the rich Qt frontend.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Imports
4 # Imports
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 from __future__ import print_function
6 from __future__ import print_function
7
7
8 # Standard library imports
8 # Standard library imports
9 from cStringIO import StringIO
9 from cStringIO import StringIO
10
10
11 # System library imports.
11 # System library imports.
12 import matplotlib
12 import matplotlib
13 from matplotlib.backends.backend_svg import new_figure_manager
13 from matplotlib.backends.backend_svg import new_figure_manager
14 from matplotlib._pylab_helpers import Gcf
14 from matplotlib._pylab_helpers import Gcf
15
15
16 # Local imports.
16 # Local imports.
17 from backend_payload import add_plot_payload
17 from backend_payload import add_plot_payload
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Functions
20 # Functions
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 def show(close=True):
23 def show(close=True):
24 """Show all figures as SVG payloads sent to the IPython clients.
24 """Show all figures as SVG payloads sent to the IPython clients.
25
25
26 Parameters
26 Parameters
27 ----------
27 ----------
28 close : bool, optional
28 close : bool, optional
29 If true, a ``plt.close('all')`` call is automatically issued after
29 If true, a ``plt.close('all')`` call is automatically issued after
30 sending all the SVG figures.
30 sending all the SVG figures.
31 """
31 """
32 for figure_manager in Gcf.get_all_fig_managers():
32 for figure_manager in Gcf.get_all_fig_managers():
33 send_svg_canvas(figure_manager.canvas)
33 send_svg_canvas(figure_manager.canvas)
34 if close:
34 if close:
35 matplotlib.pyplot.close('all')
35 matplotlib.pyplot.close('all')
36
36
37 # This flag will be reset by draw_if_interactive when called
37 # This flag will be reset by draw_if_interactive when called
38 show._draw_called = False
38 show._draw_called = False
39
39
40
40
41 def figsize(sizex, sizey):
42 """Set the default figure size to be [sizex, sizey].
43
44 This is just an easy to remember, convenience wrapper that sets::
45
46 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
47 """
48 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
49
50
41 def pastefig(*figs):
51 def pastefig(*figs):
42 """Paste one or more figures into the console workspace.
52 """Paste one or more figures into the console workspace.
43
53
44 If no arguments are given, all available figures are pasted. If the
54 If no arguments are given, all available figures are pasted. If the
45 argument list contains references to invalid figures, a warning is printed
55 argument list contains references to invalid figures, a warning is printed
46 but the function continues pasting further figures.
56 but the function continues pasting further figures.
47
57
48 Parameters
58 Parameters
49 ----------
59 ----------
50 figs : tuple
60 figs : tuple
51 A tuple that can contain any mixture of integers and figure objects.
61 A tuple that can contain any mixture of integers and figure objects.
52 """
62 """
53 if not figs:
63 if not figs:
54 show(close=False)
64 show(close=False)
55 else:
65 else:
56 fig_managers = Gcf.get_all_fig_managers()
66 fig_managers = Gcf.get_all_fig_managers()
57 fig_index = dict( [(fm.canvas.figure, fm.canvas) for fm in fig_managers]
67 fig_index = dict( [(fm.canvas.figure, fm.canvas) for fm in fig_managers]
58 + [ (fm.canvas.figure.number, fm.canvas) for fm in fig_managers] )
68 + [ (fm.canvas.figure.number, fm.canvas) for fm in fig_managers] )
59
69
60 for fig in figs:
70 for fig in figs:
61 canvas = fig_index.get(fig)
71 canvas = fig_index.get(fig)
62 if canvas is None:
72 if canvas is None:
63 print('Warning: figure %s not available.' % fig)
73 print('Warning: figure %s not available.' % fig)
64 else:
74 else:
65 send_svg_canvas(canvas)
75 send_svg_canvas(canvas)
66
76
67
77
68 def send_svg_canvas(canvas):
78 def send_svg_canvas(canvas):
69 """Draw the current canvas and send it as an SVG payload.
79 """Draw the current canvas and send it as an SVG payload.
70 """
80 """
71 # Make the background transparent.
72 # figure_manager.canvas.figure.patch.set_alpha(0.0)
73
74 # Set the background to white instead so it looks good on black. We store
81 # Set the background to white instead so it looks good on black. We store
75 # the current values to restore them at the end.
82 # the current values to restore them at the end.
76 fc = canvas.figure.get_facecolor()
83 fc = canvas.figure.get_facecolor()
77 ec = canvas.figure.get_edgecolor()
84 ec = canvas.figure.get_edgecolor()
78 canvas.figure.set_facecolor('white')
85 canvas.figure.set_facecolor('white')
79 canvas.figure.set_edgecolor('white')
86 canvas.figure.set_edgecolor('white')
80 try:
87 try:
81 add_plot_payload('svg', svg_from_canvas(canvas))
88 add_plot_payload('svg', svg_from_canvas(canvas))
82 finally:
89 finally:
83 canvas.figure.set_facecolor(fc)
90 canvas.figure.set_facecolor(fc)
84 canvas.figure.set_edgecolor(ec)
91 canvas.figure.set_edgecolor(ec)
85
92
86
93
87 def svg_from_canvas(canvas):
94 def svg_from_canvas(canvas):
88 """ Return a string containing the SVG representation of a FigureCanvasSvg.
95 """ Return a string containing the SVG representation of a FigureCanvasSvg.
89 """
96 """
90 string_io = StringIO()
97 string_io = StringIO()
91 canvas.print_svg(string_io)
98 canvas.print_svg(string_io)
92 return string_io.getvalue()
99 return string_io.getvalue()
93
100
94
101
95 def draw_if_interactive():
102 def draw_if_interactive():
96 """
103 """
97 Is called after every pylab drawing command
104 Is called after every pylab drawing command
98 """
105 """
99 # We simply flag we were called and otherwise do nothing. At the end of
106 # We simply flag we were called and otherwise do nothing. At the end of
100 # the code execution, a separate call to show_close() will act upon this.
107 # the code execution, a separate call to show_close() will act upon this.
101 show._draw_called = True
108 show._draw_called = True
102
109
103
110
104 def flush_svg():
111 def flush_svg():
105 """Call show, close all open figures, sending all SVG images.
112 """Call show, close all open figures, sending all SVG images.
106
113
107 This is meant to be called automatically and will call show() if, during
114 This is meant to be called automatically and will call show() if, during
108 prior code execution, there had been any calls to draw_if_interactive.
115 prior code execution, there had been any calls to draw_if_interactive.
109 """
116 """
110 if show._draw_called:
117 if show._draw_called:
111 show(close=True)
118 show(close=True)
112 show._draw_called = False
119 show._draw_called = False
General Comments 0
You need to be logged in to leave comments. Login now