##// END OF EJS Templates
fix double-encoding of png data...
MinRK -
Show More
@@ -1,323 +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 if fmt == 'png':
110 data = data.encode('base64')
111 return data
109 return data
112
110
113
111
114 # 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
115 # safe_execfile can live.
113 # safe_execfile can live.
116 def mpl_runner(safe_execfile):
114 def mpl_runner(safe_execfile):
117 """Factory to return a matplotlib-enabled runner for %run.
115 """Factory to return a matplotlib-enabled runner for %run.
118
116
119 Parameters
117 Parameters
120 ----------
118 ----------
121 safe_execfile : function
119 safe_execfile : function
122 This must be a function with the same interface as the
120 This must be a function with the same interface as the
123 :meth:`safe_execfile` method of IPython.
121 :meth:`safe_execfile` method of IPython.
124
122
125 Returns
123 Returns
126 -------
124 -------
127 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
128 function.
126 function.
129 """
127 """
130
128
131 def mpl_execfile(fname,*where,**kw):
129 def mpl_execfile(fname,*where,**kw):
132 """matplotlib-aware wrapper around safe_execfile.
130 """matplotlib-aware wrapper around safe_execfile.
133
131
134 Its interface is identical to that of the :func:`execfile` builtin.
132 Its interface is identical to that of the :func:`execfile` builtin.
135
133
136 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
137 properly handle interactive rendering."""
135 properly handle interactive rendering."""
138
136
139 import matplotlib
137 import matplotlib
140 import matplotlib.pylab as pylab
138 import matplotlib.pylab as pylab
141
139
142 #print '*** Matplotlib runner ***' # dbg
140 #print '*** Matplotlib runner ***' # dbg
143 # turn off rendering until end of script
141 # turn off rendering until end of script
144 is_interactive = matplotlib.rcParams['interactive']
142 is_interactive = matplotlib.rcParams['interactive']
145 matplotlib.interactive(False)
143 matplotlib.interactive(False)
146 safe_execfile(fname,*where,**kw)
144 safe_execfile(fname,*where,**kw)
147 matplotlib.interactive(is_interactive)
145 matplotlib.interactive(is_interactive)
148 # make rendering call now, if the user tried to do it
146 # make rendering call now, if the user tried to do it
149 if pylab.draw_if_interactive.called:
147 if pylab.draw_if_interactive.called:
150 pylab.draw()
148 pylab.draw()
151 pylab.draw_if_interactive.called = False
149 pylab.draw_if_interactive.called = False
152
150
153 return mpl_execfile
151 return mpl_execfile
154
152
155
153
156 def select_figure_format(shell, fmt):
154 def select_figure_format(shell, fmt):
157 """Select figure format for inline backend, either 'png' or 'svg'.
155 """Select figure format for inline backend, either 'png' or 'svg'.
158
156
159 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.
160 """
158 """
161 from matplotlib.figure import Figure
159 from matplotlib.figure import Figure
162 from IPython.zmq.pylab import backend_inline
160 from IPython.zmq.pylab import backend_inline
163
161
164 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
162 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
165 png_formatter = shell.display_formatter.formatters['image/png']
163 png_formatter = shell.display_formatter.formatters['image/png']
166
164
167 if fmt=='png':
165 if fmt=='png':
168 svg_formatter.type_printers.pop(Figure, None)
166 svg_formatter.type_printers.pop(Figure, None)
169 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
167 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
170 elif fmt=='svg':
168 elif fmt=='svg':
171 png_formatter.type_printers.pop(Figure, None)
169 png_formatter.type_printers.pop(Figure, None)
172 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
170 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
173 else:
171 else:
174 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
172 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
175
173
176 # set the format to be used in the backend()
174 # set the format to be used in the backend()
177 backend_inline._figure_format = fmt
175 backend_inline._figure_format = fmt
178
176
179 #-----------------------------------------------------------------------------
177 #-----------------------------------------------------------------------------
180 # Code for initializing matplotlib and importing pylab
178 # Code for initializing matplotlib and importing pylab
181 #-----------------------------------------------------------------------------
179 #-----------------------------------------------------------------------------
182
180
183
181
184 def find_gui_and_backend(gui=None):
182 def find_gui_and_backend(gui=None):
185 """Given a gui string return the gui and mpl backend.
183 """Given a gui string return the gui and mpl backend.
186
184
187 Parameters
185 Parameters
188 ----------
186 ----------
189 gui : str
187 gui : str
190 Can be one of ('tk','gtk','wx','qt','qt4','inline').
188 Can be one of ('tk','gtk','wx','qt','qt4','inline').
191
189
192 Returns
190 Returns
193 -------
191 -------
194 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',
195 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
193 'WXAgg','Qt4Agg','module://IPython.zmq.pylab.backend_inline').
196 """
194 """
197
195
198 import matplotlib
196 import matplotlib
199
197
200 if gui:
198 if gui:
201 # select backend based on requested gui
199 # select backend based on requested gui
202 backend = backends[gui]
200 backend = backends[gui]
203 else:
201 else:
204 backend = matplotlib.rcParams['backend']
202 backend = matplotlib.rcParams['backend']
205 # 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
206 # should be for IPython, so we can activate inputhook accordingly
204 # should be for IPython, so we can activate inputhook accordingly
207 gui = backend2gui.get(backend, None)
205 gui = backend2gui.get(backend, None)
208 return gui, backend
206 return gui, backend
209
207
210
208
211 def activate_matplotlib(backend):
209 def activate_matplotlib(backend):
212 """Activate the given backend and set interactive to True."""
210 """Activate the given backend and set interactive to True."""
213
211
214 import matplotlib
212 import matplotlib
215 if backend.startswith('module://'):
213 if backend.startswith('module://'):
216 # Work around bug in matplotlib: matplotlib.use converts the
214 # Work around bug in matplotlib: matplotlib.use converts the
217 # backend_id to lowercase even if a module name is specified!
215 # backend_id to lowercase even if a module name is specified!
218 matplotlib.rcParams['backend'] = backend
216 matplotlib.rcParams['backend'] = backend
219 else:
217 else:
220 matplotlib.use(backend)
218 matplotlib.use(backend)
221 matplotlib.interactive(True)
219 matplotlib.interactive(True)
222
220
223 # This must be imported last in the matplotlib series, after
221 # This must be imported last in the matplotlib series, after
224 # backend/interactivity choices have been made
222 # backend/interactivity choices have been made
225 import matplotlib.pylab as pylab
223 import matplotlib.pylab as pylab
226
224
227 # 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
228 # mpl-dev, we may be able to allow interactive switching...
226 # mpl-dev, we may be able to allow interactive switching...
229 #import matplotlib.pyplot
227 #import matplotlib.pyplot
230 #matplotlib.pyplot.switch_backend(backend)
228 #matplotlib.pyplot.switch_backend(backend)
231
229
232 pylab.show._needmain = False
230 pylab.show._needmain = False
233 # 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.
234 # 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.
235 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
233 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
236
234
237 def import_pylab(user_ns, backend, import_all=True, shell=None):
235 def import_pylab(user_ns, backend, import_all=True, shell=None):
238 """Import the standard pylab symbols into user_ns."""
236 """Import the standard pylab symbols into user_ns."""
239
237
240 # 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
241 # somewhat standardize on. Making them available to users by default
239 # somewhat standardize on. Making them available to users by default
242 # will greatly help this.
240 # will greatly help this.
243 s = ("import numpy\n"
241 s = ("import numpy\n"
244 "import matplotlib\n"
242 "import matplotlib\n"
245 "from matplotlib import pylab, mlab, pyplot\n"
243 "from matplotlib import pylab, mlab, pyplot\n"
246 "np = numpy\n"
244 "np = numpy\n"
247 "plt = pyplot\n"
245 "plt = pyplot\n"
248 )
246 )
249 exec s in user_ns
247 exec s in user_ns
250
248
251 if shell is not None:
249 if shell is not None:
252 exec s in shell.user_ns_hidden
250 exec s in shell.user_ns_hidden
253 # If using our svg payload backend, register the post-execution
251 # If using our svg payload backend, register the post-execution
254 # 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
255 # done with access to the real shell object.
253 # done with access to the real shell object.
256 #
254 #
257 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
255 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
258
256
259 cfg = InlineBackendConfig.instance(config=shell.config)
257 cfg = InlineBackendConfig.instance(config=shell.config)
260 cfg.shell = shell
258 cfg.shell = shell
261
259
262 if backend == backends['inline']:
260 if backend == backends['inline']:
263 from IPython.zmq.pylab.backend_inline import flush_figures
261 from IPython.zmq.pylab.backend_inline import flush_figures
264 from matplotlib import pyplot
262 from matplotlib import pyplot
265 shell.register_post_execute(flush_figures)
263 shell.register_post_execute(flush_figures)
266 # load inline_rc
264 # load inline_rc
267 pyplot.rcParams.update(cfg.rc)
265 pyplot.rcParams.update(cfg.rc)
268
266
269 # Add 'figsize' to pyplot and to the user's namespace
267 # Add 'figsize' to pyplot and to the user's namespace
270 user_ns['figsize'] = pyplot.figsize = figsize
268 user_ns['figsize'] = pyplot.figsize = figsize
271 shell.user_ns_hidden['figsize'] = figsize
269 shell.user_ns_hidden['figsize'] = figsize
272
270
273 # Setup the default figure format
271 # Setup the default figure format
274 fmt = cfg.figure_format
272 fmt = cfg.figure_format
275 select_figure_format(shell, fmt)
273 select_figure_format(shell, fmt)
276
274
277 # The old pastefig function has been replaced by display
275 # The old pastefig function has been replaced by display
278 from IPython.core.display import display
276 from IPython.core.display import display
279 # Add display and display_png to the user's namespace
277 # Add display and display_png to the user's namespace
280 user_ns['display'] = display
278 user_ns['display'] = display
281 shell.user_ns_hidden['display'] = display
279 shell.user_ns_hidden['display'] = display
282 user_ns['getfigs'] = getfigs
280 user_ns['getfigs'] = getfigs
283 shell.user_ns_hidden['getfigs'] = getfigs
281 shell.user_ns_hidden['getfigs'] = getfigs
284
282
285 if import_all:
283 if import_all:
286 s = ("from matplotlib.pylab import *\n"
284 s = ("from matplotlib.pylab import *\n"
287 "from numpy import *\n")
285 "from numpy import *\n")
288 exec s in user_ns
286 exec s in user_ns
289 if shell is not None:
287 if shell is not None:
290 exec s in shell.user_ns_hidden
288 exec s in shell.user_ns_hidden
291
289
292
290
293 def pylab_activate(user_ns, gui=None, import_all=True):
291 def pylab_activate(user_ns, gui=None, import_all=True):
294 """Activate pylab mode in the user's namespace.
292 """Activate pylab mode in the user's namespace.
295
293
296 Loads and initializes numpy, matplotlib and friends for interactive use.
294 Loads and initializes numpy, matplotlib and friends for interactive use.
297
295
298 Parameters
296 Parameters
299 ----------
297 ----------
300 user_ns : dict
298 user_ns : dict
301 Namespace where the imports will occur.
299 Namespace where the imports will occur.
302
300
303 gui : optional, string
301 gui : optional, string
304 A valid gui name following the conventions of the %gui magic.
302 A valid gui name following the conventions of the %gui magic.
305
303
306 import_all : optional, boolean
304 import_all : optional, boolean
307 If true, an 'import *' is done from numpy and pylab.
305 If true, an 'import *' is done from numpy and pylab.
308
306
309 Returns
307 Returns
310 -------
308 -------
311 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
312 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.
313 """
311 """
314 gui, backend = find_gui_and_backend(gui)
312 gui, backend = find_gui_and_backend(gui)
315 activate_matplotlib(backend)
313 activate_matplotlib(backend)
316 import_pylab(user_ns, backend)
314 import_pylab(user_ns, backend)
317
315
318 print """
316 print """
319 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
317 Welcome to pylab, a matplotlib-based Python environment [backend: %s].
320 For more information, type 'help(pylab)'.""" % backend
318 For more information, type 'help(pylab)'.""" % backend
321
319
322 return gui
320 return gui
323
321
@@ -1,117 +1,117 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 import sys
9 import sys
10
10
11 # Third-party imports
11 # Third-party imports
12 import matplotlib
12 import matplotlib
13 from matplotlib.backends.backend_agg import new_figure_manager
13 from matplotlib.backends.backend_agg 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 IPython.config.configurable import SingletonConfigurable
17 from IPython.config.configurable import SingletonConfigurable
18 from IPython.core.displaypub import publish_display_data
18 from IPython.core.displaypub import publish_display_data
19 from IPython.lib.pylabtools import print_figure, select_figure_format
19 from IPython.lib.pylabtools import print_figure, select_figure_format
20 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum
20 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Configurable for inline backend options
22 # Configurable for inline backend options
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class InlineBackendConfig(SingletonConfigurable):
25 class InlineBackendConfig(SingletonConfigurable):
26 """An object to store configuration of the inline backend."""
26 """An object to store configuration of the inline backend."""
27
27
28 # The typical default figure size is too large for inline use,
28 # The typical default figure size is too large for inline use,
29 # so we shrink the figure size to 6x4, and tweak fonts to
29 # so we shrink the figure size to 6x4, and tweak fonts to
30 # make that fit. This is configurable via Global.pylab_inline_rc,
30 # make that fit. This is configurable via Global.pylab_inline_rc,
31 # or rather it will be once the zmq kernel is hooked up to
31 # or rather it will be once the zmq kernel is hooked up to
32 # the config system.
32 # the config system.
33 rc = Dict({'figure.figsize': (6.0,4.0),
33 rc = Dict({'figure.figsize': (6.0,4.0),
34 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
34 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
35 'font.size': 10,
35 'font.size': 10,
36 # 10pt still needs a little more room on the xlabel:
36 # 10pt still needs a little more room on the xlabel:
37 'figure.subplot.bottom' : .125
37 'figure.subplot.bottom' : .125
38 }, config=True,
38 }, config=True,
39 help="""Subset of matplotlib rcParams that should be different for the
39 help="""Subset of matplotlib rcParams that should be different for the
40 inline backend."""
40 inline backend."""
41 )
41 )
42 figure_format = CaselessStrEnum(['svg', 'png'], default_value='png', config=True,
42 figure_format = CaselessStrEnum(['svg', 'png'], default_value='png', config=True,
43 help="The image format for figures with the inline backend.")
43 help="The image format for figures with the inline backend.")
44
44
45 def _format_changed(self, name, old, new):
45 def _figure_format_changed(self, name, old, new):
46 if self.shell is None:
46 if self.shell is None:
47 return
47 return
48 else:
48 else:
49 select_figure_format(self.shell, new)
49 select_figure_format(self.shell, new)
50
50
51 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
51 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
52
52
53
53
54 #-----------------------------------------------------------------------------
54 #-----------------------------------------------------------------------------
55 # Functions
55 # Functions
56 #-----------------------------------------------------------------------------
56 #-----------------------------------------------------------------------------
57
57
58 def show(close=True):
58 def show(close=True):
59 """Show all figures as SVG payloads sent to the IPython clients.
59 """Show all figures as SVG payloads sent to the IPython clients.
60
60
61 Parameters
61 Parameters
62 ----------
62 ----------
63 close : bool, optional
63 close : bool, optional
64 If true, a ``plt.close('all')`` call is automatically issued after
64 If true, a ``plt.close('all')`` call is automatically issued after
65 sending all the SVG figures. If this is set, the figures will entirely
65 sending all the SVG figures. If this is set, the figures will entirely
66 removed from the internal list of figures.
66 removed from the internal list of figures.
67 """
67 """
68 for figure_manager in Gcf.get_all_fig_managers():
68 for figure_manager in Gcf.get_all_fig_managers():
69 send_figure(figure_manager.canvas.figure)
69 send_figure(figure_manager.canvas.figure)
70 if close:
70 if close:
71 matplotlib.pyplot.close('all')
71 matplotlib.pyplot.close('all')
72
72
73
73
74 # This flag will be reset by draw_if_interactive when called
74 # This flag will be reset by draw_if_interactive when called
75 show._draw_called = False
75 show._draw_called = False
76
76
77
77
78 def draw_if_interactive():
78 def draw_if_interactive():
79 """
79 """
80 Is called after every pylab drawing command
80 Is called after every pylab drawing command
81 """
81 """
82 # We simply flag we were called and otherwise do nothing. At the end of
82 # We simply flag we were called and otherwise do nothing. At the end of
83 # the code execution, a separate call to show_close() will act upon this.
83 # the code execution, a separate call to show_close() will act upon this.
84 show._draw_called = True
84 show._draw_called = True
85
85
86
86
87 def flush_figures():
87 def flush_figures():
88 """Call show, close all open figures, sending all figure images.
88 """Call show, close all open figures, sending all figure images.
89
89
90 This is meant to be called automatically and will call show() if, during
90 This is meant to be called automatically and will call show() if, during
91 prior code execution, there had been any calls to draw_if_interactive.
91 prior code execution, there had been any calls to draw_if_interactive.
92 """
92 """
93 if show._draw_called:
93 if show._draw_called:
94 show()
94 show()
95 show._draw_called = False
95 show._draw_called = False
96
96
97
97
98 def send_figure(fig):
98 def send_figure(fig):
99 """Draw the current figure and send it as a PNG payload.
99 """Draw the current figure and send it as a PNG payload.
100 """
100 """
101 # For an empty figure, don't even bother calling figure_to_svg, to avoid
101 # For an empty figure, don't even bother calling figure_to_svg, to avoid
102 # big blank spaces in the qt console
102 # big blank spaces in the qt console
103 if not fig.axes:
103 if not fig.axes:
104 return
104 return
105 fmt = InlineBackendConfig.instance().figure_format
105 fmt = InlineBackendConfig.instance().figure_format
106 data = print_figure(fig, fmt)
106 data = print_figure(fig, fmt)
107 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
107 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
108 mime = mimetypes[fmt]
108 mime = mimetypes[fmt]
109 # flush text streams before sending figures, helps a little with output
109 # flush text streams before sending figures, helps a little with output
110 # synchronization in the console (though it's a bandaid, not a real sln)
110 # synchronization in the console (though it's a bandaid, not a real sln)
111 sys.stdout.flush(); sys.stderr.flush()
111 sys.stdout.flush(); sys.stderr.flush()
112 publish_display_data(
112 publish_display_data(
113 'IPython.zmq.pylab.backend_inline.send_figure',
113 'IPython.zmq.pylab.backend_inline.send_figure',
114 'Matplotlib Plot',
114 'Matplotlib Plot',
115 {mime : data}
115 {mime : data}
116 )
116 )
117
117
General Comments 0
You need to be logged in to leave comments. Login now