##// END OF EJS Templates
generate supported formats in ValueError
MinRK -
Show More
@@ -1,373 +1,374 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 from __future__ import print_function
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2009 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import sys
24 24 from io import BytesIO
25 25
26 26 from IPython.core.display import _pngxy
27 27 from IPython.utils.decorators import flag_calls
28 28 from IPython.utils import py3compat
29 29
30 30 # If user specifies a GUI, that dictates the backend, otherwise we read the
31 31 # user's mpl default from the mpl rc structure
32 32 backends = {'tk': 'TkAgg',
33 33 'gtk': 'GTKAgg',
34 34 'gtk3': 'GTK3Agg',
35 35 'wx': 'WXAgg',
36 36 'qt': 'Qt4Agg', # qt3 not supported
37 37 'qt4': 'Qt4Agg',
38 38 'osx': 'MacOSX',
39 39 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
40 40
41 41 # We also need a reverse backends2guis mapping that will properly choose which
42 42 # GUI support to activate based on the desired matplotlib backend. For the
43 43 # most part it's just a reverse of the above dict, but we also need to add a
44 44 # few others that map to the same GUI manually:
45 45 backend2gui = dict(zip(backends.values(), backends.keys()))
46 46 # Our tests expect backend2gui to just return 'qt'
47 47 backend2gui['Qt4Agg'] = 'qt'
48 48 # In the reverse mapping, there are a few extra valid matplotlib backends that
49 49 # map to the same GUI support
50 50 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
51 51 backend2gui['GTK3Cairo'] = 'gtk3'
52 52 backend2gui['WX'] = 'wx'
53 53 backend2gui['CocoaAgg'] = 'osx'
54 54
55 55 #-----------------------------------------------------------------------------
56 56 # Matplotlib utilities
57 57 #-----------------------------------------------------------------------------
58 58
59 59
60 60 def getfigs(*fig_nums):
61 61 """Get a list of matplotlib figures by figure numbers.
62 62
63 63 If no arguments are given, all available figures are returned. If the
64 64 argument list contains references to invalid figures, a warning is printed
65 65 but the function continues pasting further figures.
66 66
67 67 Parameters
68 68 ----------
69 69 figs : tuple
70 70 A tuple of ints giving the figure numbers of the figures to return.
71 71 """
72 72 from matplotlib._pylab_helpers import Gcf
73 73 if not fig_nums:
74 74 fig_managers = Gcf.get_all_fig_managers()
75 75 return [fm.canvas.figure for fm in fig_managers]
76 76 else:
77 77 figs = []
78 78 for num in fig_nums:
79 79 f = Gcf.figs.get(num)
80 80 if f is None:
81 81 print('Warning: figure %s not available.' % num)
82 82 else:
83 83 figs.append(f.canvas.figure)
84 84 return figs
85 85
86 86
87 87 def figsize(sizex, sizey):
88 88 """Set the default figure size to be [sizex, sizey].
89 89
90 90 This is just an easy to remember, convenience wrapper that sets::
91 91
92 92 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
93 93 """
94 94 import matplotlib
95 95 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
96 96
97 97
98 98 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
99 99 """Print a figure to an image, and return the resulting bytes
100 100
101 101 Any keyword args are passed to fig.canvas.print_figure,
102 102 such as ``quality`` or ``bbox_inches``.
103 103 """
104 104 from matplotlib import rcParams
105 105 # When there's an empty figure, we shouldn't return anything, otherwise we
106 106 # get big blank areas in the qt console.
107 107 if not fig.axes and not fig.lines:
108 108 return
109 109
110 110 dpi = rcParams['savefig.dpi']
111 111 if fmt == 'retina':
112 112 dpi = dpi * 2
113 113 fmt = 'png'
114 114
115 115 # build keyword args
116 116 kw = dict(
117 117 format=fmt,
118 118 fc=fig.get_facecolor(),
119 119 ec=fig.get_edgecolor(),
120 120 dpi=dpi,
121 121 bbox_inches=bbox_inches,
122 122 )
123 123 # **kwargs get higher priority
124 124 kw.update(kwargs)
125 125
126 126 bytes_io = BytesIO()
127 127 fig.canvas.print_figure(bytes_io, **kw)
128 128 return bytes_io.getvalue()
129 129
130 130 def retina_figure(fig, **kwargs):
131 131 """format a figure as a pixel-doubled (retina) PNG"""
132 132 pngdata = print_figure(fig, fmt='retina', **kwargs)
133 133 w, h = _pngxy(pngdata)
134 134 metadata = dict(width=w//2, height=h//2)
135 135 return pngdata, metadata
136 136
137 137 # We need a little factory function here to create the closure where
138 138 # safe_execfile can live.
139 139 def mpl_runner(safe_execfile):
140 140 """Factory to return a matplotlib-enabled runner for %run.
141 141
142 142 Parameters
143 143 ----------
144 144 safe_execfile : function
145 145 This must be a function with the same interface as the
146 146 :meth:`safe_execfile` method of IPython.
147 147
148 148 Returns
149 149 -------
150 150 A function suitable for use as the ``runner`` argument of the %run magic
151 151 function.
152 152 """
153 153
154 154 def mpl_execfile(fname,*where,**kw):
155 155 """matplotlib-aware wrapper around safe_execfile.
156 156
157 157 Its interface is identical to that of the :func:`execfile` builtin.
158 158
159 159 This is ultimately a call to execfile(), but wrapped in safeties to
160 160 properly handle interactive rendering."""
161 161
162 162 import matplotlib
163 163 import matplotlib.pylab as pylab
164 164
165 165 #print '*** Matplotlib runner ***' # dbg
166 166 # turn off rendering until end of script
167 167 is_interactive = matplotlib.rcParams['interactive']
168 168 matplotlib.interactive(False)
169 169 safe_execfile(fname,*where,**kw)
170 170 matplotlib.interactive(is_interactive)
171 171 # make rendering call now, if the user tried to do it
172 172 if pylab.draw_if_interactive.called:
173 173 pylab.draw()
174 174 pylab.draw_if_interactive.called = False
175 175
176 176 return mpl_execfile
177 177
178 178
179 179 def select_figure_formats(shell, formats, **kwargs):
180 180 """Select figure formats for the inline backend.
181 181
182 182 Parameters
183 183 ==========
184 184 shell : InteractiveShell
185 185 The main IPython instance.
186 186 formats : str or set
187 187 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
188 188 **kwargs : any
189 189 Extra keyword arguments to be passed to fig.canvas.print_figure.
190 190 """
191 191 from matplotlib.figure import Figure
192 192 from IPython.kernel.zmq.pylab import backend_inline
193 193
194 194 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
195 195 png_formatter = shell.display_formatter.formatters['image/png']
196 196 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
197 197 pdf_formatter = shell.display_formatter.formatters['application/pdf']
198 198
199 199 if isinstance(formats, py3compat.string_types):
200 200 formats = {formats}
201 201 # cast in case of list / tuple
202 202 formats = set(formats)
203 203
204 204 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
205 205
206 206 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
207 207 bad = formats.difference(supported)
208 208 if bad:
209 s = "{%s}" % ",".join([repr(f) for f in bad])
210 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', 'pdf' not %s" % s)
209 bs = "%s" % ','.join([repr(f) for f in bad])
210 gs = "%s" % ','.join([repr(f) for f in supported])
211 raise ValueError("supported formats are: %s not %s" % (gs, bs))
211 212
212 213 if 'png' in formats:
213 214 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
214 215 if 'retina' in formats or 'png2x' in formats:
215 216 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
216 217 if 'jpg' in formats or 'jpeg' in formats:
217 218 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
218 219 if 'svg' in formats:
219 220 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
220 221 if 'pdf' in formats:
221 222 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
222 223
223 224 #-----------------------------------------------------------------------------
224 225 # Code for initializing matplotlib and importing pylab
225 226 #-----------------------------------------------------------------------------
226 227
227 228
228 229 def find_gui_and_backend(gui=None, gui_select=None):
229 230 """Given a gui string return the gui and mpl backend.
230 231
231 232 Parameters
232 233 ----------
233 234 gui : str
234 235 Can be one of ('tk','gtk','wx','qt','qt4','inline').
235 236 gui_select : str
236 237 Can be one of ('tk','gtk','wx','qt','qt4','inline').
237 238 This is any gui already selected by the shell.
238 239
239 240 Returns
240 241 -------
241 242 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
242 243 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
243 244 """
244 245
245 246 import matplotlib
246 247
247 248 if gui and gui != 'auto':
248 249 # select backend based on requested gui
249 250 backend = backends[gui]
250 251 else:
251 252 # We need to read the backend from the original data structure, *not*
252 253 # from mpl.rcParams, since a prior invocation of %matplotlib may have
253 254 # overwritten that.
254 255 # WARNING: this assumes matplotlib 1.1 or newer!!
255 256 backend = matplotlib.rcParamsOrig['backend']
256 257 # In this case, we need to find what the appropriate gui selection call
257 258 # should be for IPython, so we can activate inputhook accordingly
258 259 gui = backend2gui.get(backend, None)
259 260
260 261 # If we have already had a gui active, we need it and inline are the
261 262 # ones allowed.
262 263 if gui_select and gui != gui_select:
263 264 gui = gui_select
264 265 backend = backends[gui]
265 266
266 267 return gui, backend
267 268
268 269
269 270 def activate_matplotlib(backend):
270 271 """Activate the given backend and set interactive to True."""
271 272
272 273 import matplotlib
273 274 matplotlib.interactive(True)
274 275
275 276 # Matplotlib had a bug where even switch_backend could not force
276 277 # the rcParam to update. This needs to be set *before* the module
277 278 # magic of switch_backend().
278 279 matplotlib.rcParams['backend'] = backend
279 280
280 281 import matplotlib.pyplot
281 282 matplotlib.pyplot.switch_backend(backend)
282 283
283 284 # This must be imported last in the matplotlib series, after
284 285 # backend/interactivity choices have been made
285 286 import matplotlib.pylab as pylab
286 287
287 288 pylab.show._needmain = False
288 289 # We need to detect at runtime whether show() is called by the user.
289 290 # For this, we wrap it into a decorator which adds a 'called' flag.
290 291 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
291 292
292 293
293 294 def import_pylab(user_ns, import_all=True):
294 295 """Populate the namespace with pylab-related values.
295 296
296 297 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
297 298
298 299 Also imports a few names from IPython (figsize, display, getfigs)
299 300
300 301 """
301 302
302 303 # Import numpy as np/pyplot as plt are conventions we're trying to
303 304 # somewhat standardize on. Making them available to users by default
304 305 # will greatly help this.
305 306 s = ("import numpy\n"
306 307 "import matplotlib\n"
307 308 "from matplotlib import pylab, mlab, pyplot\n"
308 309 "np = numpy\n"
309 310 "plt = pyplot\n"
310 311 )
311 312 exec(s, user_ns)
312 313
313 314 if import_all:
314 315 s = ("from matplotlib.pylab import *\n"
315 316 "from numpy import *\n")
316 317 exec(s, user_ns)
317 318
318 319 # IPython symbols to add
319 320 user_ns['figsize'] = figsize
320 321 from IPython.core.display import display
321 322 # Add display and getfigs to the user's namespace
322 323 user_ns['display'] = display
323 324 user_ns['getfigs'] = getfigs
324 325
325 326
326 327 def configure_inline_support(shell, backend):
327 328 """Configure an IPython shell object for matplotlib use.
328 329
329 330 Parameters
330 331 ----------
331 332 shell : InteractiveShell instance
332 333
333 334 backend : matplotlib backend
334 335 """
335 336 # If using our svg payload backend, register the post-execution
336 337 # function that will pick up the results for display. This can only be
337 338 # done with access to the real shell object.
338 339
339 340 # Note: if we can't load the inline backend, then there's no point
340 341 # continuing (such as in terminal-only shells in environments without
341 342 # zeromq available).
342 343 try:
343 344 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
344 345 except ImportError:
345 346 return
346 347 from matplotlib import pyplot
347 348
348 349 cfg = InlineBackend.instance(parent=shell)
349 350 cfg.shell = shell
350 351 if cfg not in shell.configurables:
351 352 shell.configurables.append(cfg)
352 353
353 354 if backend == backends['inline']:
354 355 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
355 356 shell.register_post_execute(flush_figures)
356 357
357 358 # Save rcParams that will be overwrittern
358 359 shell._saved_rcParams = dict()
359 360 for k in cfg.rc:
360 361 shell._saved_rcParams[k] = pyplot.rcParams[k]
361 362 # load inline_rc
362 363 pyplot.rcParams.update(cfg.rc)
363 364 else:
364 365 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
365 366 if flush_figures in shell._post_execute:
366 367 shell._post_execute.pop(flush_figures)
367 368 if hasattr(shell, '_saved_rcParams'):
368 369 pyplot.rcParams.update(shell._saved_rcParams)
369 370 del shell._saved_rcParams
370 371
371 372 # Setup the default figure format
372 373 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
373 374
General Comments 0
You need to be logged in to leave comments. Login now