##// END OF EJS Templates
add InlineBackendConfig...
MinRK -
Show More
@@ -87,8 +87,8 b' def figsize(sizex, sizey):'
87 87 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
88 88
89 89
90 def figure_to_svg(fig):
91 """Convert a figure to svg for inline display."""
90 def print_figure(fig, fmt='png'):
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:
@@ -100,12 +100,15 b' def figure_to_svg(fig):'
100 100 fig.set_edgecolor('white')
101 101 try:
102 102 string_io = StringIO()
103 fig.canvas.print_figure(string_io, format='svg')
104 svg = string_io.getvalue()
103 # use 72 dpi to match QTConsole's dpi
104 fig.canvas.print_figure(string_io, format=fmt, dpi=72)
105 data = string_io.getvalue()
105 106 finally:
106 107 fig.set_facecolor(fc)
107 108 fig.set_edgecolor(ec)
108 return svg
109 if fmt == 'png':
110 data = data.encode('base64')
111 return data
109 112
110 113
111 114 # We need a little factory function here to create the closure where
@@ -150,6 +153,29 b' def mpl_runner(safe_execfile):'
150 153 return mpl_execfile
151 154
152 155
156 def select_figure_format(shell, fmt):
157 """Select figure format for inline backend, either 'png' or 'svg'.
158
159 Using this method ensures only one figure format is active at a time.
160 """
161 from matplotlib.figure import Figure
162 from IPython.zmq.pylab import backend_inline
163
164 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
165 png_formatter = shell.display_formatter.formatters['image/png']
166
167 if fmt=='png':
168 svg_formatter.type_printers.pop(Figure, None)
169 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
170 elif fmt=='svg':
171 png_formatter.type_printers.pop(Figure, None)
172 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
173 else:
174 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
175
176 # set the format to be used in the backend()
177 backend_inline._figure_format = fmt
178
153 179 #-----------------------------------------------------------------------------
154 180 # Code for initializing matplotlib and importing pylab
155 181 #-----------------------------------------------------------------------------
@@ -208,7 +234,6 b' def activate_matplotlib(backend):'
208 234 # For this, we wrap it into a decorator which adds a 'called' flag.
209 235 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
210 236
211
212 237 def import_pylab(user_ns, backend, import_all=True, shell=None):
213 238 """Import the standard pylab symbols into user_ns."""
214 239
@@ -228,43 +253,32 b' def import_pylab(user_ns, backend, import_all=True, shell=None):'
228 253 # If using our svg payload backend, register the post-execution
229 254 # function that will pick up the results for display. This can only be
230 255 # done with access to the real shell object.
256 #
257 from IPython.zmq.pylab.backend_inline import InlineBackendConfig
258
259 cfg = InlineBackendConfig.instance(config=shell.config)
260 cfg.shell = shell
261
231 262 if backend == backends['inline']:
232 from IPython.zmq.pylab.backend_inline import flush_svg
263 from IPython.zmq.pylab.backend_inline import flush_figures
233 264 from matplotlib import pyplot
234 shell.register_post_execute(flush_svg)
235 # The typical default figure size is too large for inline use,
236 # so we shrink the figure size to 6x4, and tweak fonts to
237 # make that fit. This is configurable via Global.pylab_inline_rc,
238 # or rather it will be once the zmq kernel is hooked up to
239 # the config system.
240
241 default_rc = {
242 'figure.figsize': (6.0,4.0),
243 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
244 'font.size': 10,
245 # 10pt still needs a little more room on the xlabel:
246 'figure.subplot.bottom' : .125
247 }
248 rc = getattr(shell.config.Global, 'pylab_inline_rc', default_rc)
249 pyplot.rcParams.update(rc)
250 shell.config.Global.pylab_inline_rc = rc
265 shell.register_post_execute(flush_figures)
266 # load inline_rc
267 pyplot.rcParams.update(cfg.rc)
251 268
252 269 # Add 'figsize' to pyplot and to the user's namespace
253 270 user_ns['figsize'] = pyplot.figsize = figsize
254 271 shell.user_ns_hidden['figsize'] = figsize
255 272
273 # Setup the default figure format
274 fmt = cfg.figure_format
275 select_figure_format(shell, fmt)
276
256 277 # The old pastefig function has been replaced by display
257 # Always add this svg formatter so display works.
258 from IPython.core.display import display, display_svg
259 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
260 svg_formatter.for_type_by_name(
261 'matplotlib.figure','Figure',figure_to_svg
262 )
278 from IPython.core.display import display
263 279 # Add display and display_png to the user's namespace
264 280 user_ns['display'] = display
265 281 shell.user_ns_hidden['display'] = display
266 user_ns['display_svg'] = display_svg
267 shell.user_ns_hidden['display_svg'] = display_svg
268 282 user_ns['getfigs'] = getfigs
269 283 shell.user_ns_hidden['getfigs'] = getfigs
270 284
@@ -10,12 +10,46 b' import sys'
10 10
11 11 # Third-party imports
12 12 import matplotlib
13 from matplotlib.backends.backend_svg import new_figure_manager
13 from matplotlib.backends.backend_agg import new_figure_manager
14 14 from matplotlib._pylab_helpers import Gcf
15 15
16 16 # Local imports.
17 from IPython.config.configurable import SingletonConfigurable
17 18 from IPython.core.displaypub import publish_display_data
18 from IPython.lib.pylabtools import figure_to_svg
19 from IPython.lib.pylabtools import print_figure, select_figure_format
20 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum
21 #-----------------------------------------------------------------------------
22 # Configurable for inline backend options
23 #-----------------------------------------------------------------------------
24
25 class InlineBackendConfig(SingletonConfigurable):
26 """An object to store configuration of the inline backend."""
27
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
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
32 # the config system.
33 rc = Dict({'figure.figsize': (6.0,4.0),
34 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
35 'font.size': 10,
36 # 10pt still needs a little more room on the xlabel:
37 'figure.subplot.bottom' : .125
38 }, config=True,
39 help="""Subset of matplotlib rcParams that should be different for the
40 inline backend."""
41 )
42 figure_format = CaselessStrEnum(['svg', 'png'], default_value='png', config=True,
43 help="The image format for figures with the inline backend.")
44
45 def _format_changed(self, name, old, new):
46 if self.shell is None:
47 return
48 else:
49 select_figure_format(self.shell, new)
50
51 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
52
19 53
20 54 #-----------------------------------------------------------------------------
21 55 # Functions
@@ -32,7 +66,7 b' def show(close=True):'
32 66 removed from the internal list of figures.
33 67 """
34 68 for figure_manager in Gcf.get_all_fig_managers():
35 send_svg_figure(figure_manager.canvas.figure)
69 send_figure(figure_manager.canvas.figure)
36 70 if close:
37 71 matplotlib.pyplot.close('all')
38 72
@@ -50,8 +84,8 b' def draw_if_interactive():'
50 84 show._draw_called = True
51 85
52 86
53 def flush_svg():
54 """Call show, close all open figures, sending all SVG images.
87 def flush_figures():
88 """Call show, close all open figures, sending all figure images.
55 89
56 90 This is meant to be called automatically and will call show() if, during
57 91 prior code execution, there had been any calls to draw_if_interactive.
@@ -61,21 +95,23 b' def flush_svg():'
61 95 show._draw_called = False
62 96
63 97
64 def send_svg_figure(fig):
65 """Draw the current figure and send it as an SVG payload.
98 def send_figure(fig):
99 """Draw the current figure and send it as a PNG payload.
66 100 """
67 101 # For an empty figure, don't even bother calling figure_to_svg, to avoid
68 102 # big blank spaces in the qt console
69 103 if not fig.axes:
70 104 return
71
72 svg = figure_to_svg(fig)
105 fmt = InlineBackendConfig.instance().figure_format
106 data = print_figure(fig, fmt)
107 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
108 mime = mimetypes[fmt]
73 109 # flush text streams before sending figures, helps a little with output
74 110 # synchronization in the console (though it's a bandaid, not a real sln)
75 111 sys.stdout.flush(); sys.stderr.flush()
76 112 publish_display_data(
77 'IPython.zmq.pylab.backend_inline.send_svg_figure',
113 'IPython.zmq.pylab.backend_inline.send_figure',
78 114 'Matplotlib Plot',
79 {'image/svg+xml' : svg}
115 {mime : data}
80 116 )
81 117
General Comments 0
You need to be logged in to leave comments. Login now