##// END OF EJS Templates
Forgot to import TraitError....
Daniel B. Vasquez -
Show More
@@ -1,344 +1,346 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
29 29 # If user specifies a GUI, that dictates the backend, otherwise we read the
30 30 # user's mpl default from the mpl rc structure
31 31 backends = {'tk': 'TkAgg',
32 32 'gtk': 'GTKAgg',
33 33 'gtk3': 'GTK3Agg',
34 34 'wx': 'WXAgg',
35 35 'qt': 'Qt4Agg', # qt3 not supported
36 36 'qt4': 'Qt4Agg',
37 37 'osx': 'MacOSX',
38 38 'inline' : 'module://IPython.kernel.zmq.pylab.backend_inline'}
39 39
40 40 # We also need a reverse backends2guis mapping that will properly choose which
41 41 # GUI support to activate based on the desired matplotlib backend. For the
42 42 # most part it's just a reverse of the above dict, but we also need to add a
43 43 # few others that map to the same GUI manually:
44 44 backend2gui = dict(zip(backends.values(), backends.keys()))
45 45 # Our tests expect backend2gui to just return 'qt'
46 46 backend2gui['Qt4Agg'] = 'qt'
47 47 # In the reverse mapping, there are a few extra valid matplotlib backends that
48 48 # map to the same GUI support
49 49 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
50 50 backend2gui['GTK3Cairo'] = 'gtk3'
51 51 backend2gui['WX'] = 'wx'
52 52 backend2gui['CocoaAgg'] = 'osx'
53 53
54 54 #-----------------------------------------------------------------------------
55 55 # Matplotlib utilities
56 56 #-----------------------------------------------------------------------------
57 57
58 58
59 59 def getfigs(*fig_nums):
60 60 """Get a list of matplotlib figures by figure numbers.
61 61
62 62 If no arguments are given, all available figures are returned. If the
63 63 argument list contains references to invalid figures, a warning is printed
64 64 but the function continues pasting further figures.
65 65
66 66 Parameters
67 67 ----------
68 68 figs : tuple
69 69 A tuple of ints giving the figure numbers of the figures to return.
70 70 """
71 71 from matplotlib._pylab_helpers import Gcf
72 72 if not fig_nums:
73 73 fig_managers = Gcf.get_all_fig_managers()
74 74 return [fm.canvas.figure for fm in fig_managers]
75 75 else:
76 76 figs = []
77 77 for num in fig_nums:
78 78 f = Gcf.figs.get(num)
79 79 if f is None:
80 80 print('Warning: figure %s not available.' % num)
81 81 else:
82 82 figs.append(f.canvas.figure)
83 83 return figs
84 84
85 85
86 86 def figsize(sizex, sizey):
87 87 """Set the default figure size to be [sizex, sizey].
88 88
89 89 This is just an easy to remember, convenience wrapper that sets::
90 90
91 91 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
92 92 """
93 93 import matplotlib
94 94 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
95 95
96 96
97 97 def print_figure(fig, fmt='png', quality=90):
98 """Convert a figure to svg, png or jpg for inline display."""
98 """Convert a figure to svg, png or jpg for inline display.
99 Quality is only relevant for jpg.
100 """
99 101 from matplotlib import rcParams
100 102 # When there's an empty figure, we shouldn't return anything, otherwise we
101 103 # get big blank areas in the qt console.
102 104 if not fig.axes and not fig.lines:
103 105 return
104 106
105 107 fc = fig.get_facecolor()
106 108 ec = fig.get_edgecolor()
107 109 bytes_io = BytesIO()
108 110 dpi = rcParams['savefig.dpi']
109 111 if fmt == 'retina':
110 112 dpi = dpi * 2
111 113 fmt = 'png'
112 114 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
113 115 facecolor=fc, edgecolor=ec, dpi=dpi, quality=quality)
114 116 data = bytes_io.getvalue()
115 117 return data
116 118
117 119 def retina_figure(fig):
118 120 """format a figure as a pixel-doubled (retina) PNG"""
119 121 pngdata = print_figure(fig, fmt='retina')
120 122 w, h = _pngxy(pngdata)
121 123 metadata = dict(width=w//2, height=h//2)
122 124 return pngdata, metadata
123 125
124 126 # We need a little factory function here to create the closure where
125 127 # safe_execfile can live.
126 128 def mpl_runner(safe_execfile):
127 129 """Factory to return a matplotlib-enabled runner for %run.
128 130
129 131 Parameters
130 132 ----------
131 133 safe_execfile : function
132 134 This must be a function with the same interface as the
133 135 :meth:`safe_execfile` method of IPython.
134 136
135 137 Returns
136 138 -------
137 139 A function suitable for use as the ``runner`` argument of the %run magic
138 140 function.
139 141 """
140 142
141 143 def mpl_execfile(fname,*where,**kw):
142 144 """matplotlib-aware wrapper around safe_execfile.
143 145
144 146 Its interface is identical to that of the :func:`execfile` builtin.
145 147
146 148 This is ultimately a call to execfile(), but wrapped in safeties to
147 149 properly handle interactive rendering."""
148 150
149 151 import matplotlib
150 152 import matplotlib.pylab as pylab
151 153
152 154 #print '*** Matplotlib runner ***' # dbg
153 155 # turn off rendering until end of script
154 156 is_interactive = matplotlib.rcParams['interactive']
155 157 matplotlib.interactive(False)
156 158 safe_execfile(fname,*where,**kw)
157 159 matplotlib.interactive(is_interactive)
158 160 # make rendering call now, if the user tried to do it
159 161 if pylab.draw_if_interactive.called:
160 162 pylab.draw()
161 163 pylab.draw_if_interactive.called = False
162 164
163 165 return mpl_execfile
164 166
165 167
166 168 def select_figure_format(shell, fmt, quality):
167 169 """Select figure format for inline backend, can be 'png', 'retina', 'jpg', or 'svg'.
168 170
169 171 Using this method ensures only one figure format is active at a time.
170 172 """
171 173 from matplotlib.figure import Figure
172 174 from IPython.kernel.zmq.pylab import backend_inline
173 175
174 176 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
175 177 png_formatter = shell.display_formatter.formatters['image/png']
176 178 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
177 179
178 180 [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ]
179 181
180 182 if fmt == 'png':
181 183 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
182 184 elif fmt in ('png2x', 'retina'):
183 185 png_formatter.for_type(Figure, retina_figure)
184 186 elif fmt in ('jpg', 'jpeg'):
185 187 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality))
186 188 elif fmt == 'svg':
187 189 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
188 190 else:
189 191 raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', not %r" % fmt)
190 192
191 193 # set the format to be used in the backend()
192 194 backend_inline._figure_format = fmt
193 195
194 196 #-----------------------------------------------------------------------------
195 197 # Code for initializing matplotlib and importing pylab
196 198 #-----------------------------------------------------------------------------
197 199
198 200
199 201 def find_gui_and_backend(gui=None, gui_select=None):
200 202 """Given a gui string return the gui and mpl backend.
201 203
202 204 Parameters
203 205 ----------
204 206 gui : str
205 207 Can be one of ('tk','gtk','wx','qt','qt4','inline').
206 208 gui_select : str
207 209 Can be one of ('tk','gtk','wx','qt','qt4','inline').
208 210 This is any gui already selected by the shell.
209 211
210 212 Returns
211 213 -------
212 214 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
213 215 'WXAgg','Qt4Agg','module://IPython.kernel.zmq.pylab.backend_inline').
214 216 """
215 217
216 218 import matplotlib
217 219
218 220 if gui and gui != 'auto':
219 221 # select backend based on requested gui
220 222 backend = backends[gui]
221 223 else:
222 224 # We need to read the backend from the original data structure, *not*
223 225 # from mpl.rcParams, since a prior invocation of %matplotlib may have
224 226 # overwritten that.
225 227 # WARNING: this assumes matplotlib 1.1 or newer!!
226 228 backend = matplotlib.rcParamsOrig['backend']
227 229 # In this case, we need to find what the appropriate gui selection call
228 230 # should be for IPython, so we can activate inputhook accordingly
229 231 gui = backend2gui.get(backend, None)
230 232
231 233 # If we have already had a gui active, we need it and inline are the
232 234 # ones allowed.
233 235 if gui_select and gui != gui_select:
234 236 gui = gui_select
235 237 backend = backends[gui]
236 238
237 239 return gui, backend
238 240
239 241
240 242 def activate_matplotlib(backend):
241 243 """Activate the given backend and set interactive to True."""
242 244
243 245 import matplotlib
244 246 matplotlib.interactive(True)
245 247
246 248 # Matplotlib had a bug where even switch_backend could not force
247 249 # the rcParam to update. This needs to be set *before* the module
248 250 # magic of switch_backend().
249 251 matplotlib.rcParams['backend'] = backend
250 252
251 253 import matplotlib.pyplot
252 254 matplotlib.pyplot.switch_backend(backend)
253 255
254 256 # This must be imported last in the matplotlib series, after
255 257 # backend/interactivity choices have been made
256 258 import matplotlib.pylab as pylab
257 259
258 260 pylab.show._needmain = False
259 261 # We need to detect at runtime whether show() is called by the user.
260 262 # For this, we wrap it into a decorator which adds a 'called' flag.
261 263 pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive)
262 264
263 265
264 266 def import_pylab(user_ns, import_all=True):
265 267 """Populate the namespace with pylab-related values.
266 268
267 269 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
268 270
269 271 Also imports a few names from IPython (figsize, display, getfigs)
270 272
271 273 """
272 274
273 275 # Import numpy as np/pyplot as plt are conventions we're trying to
274 276 # somewhat standardize on. Making them available to users by default
275 277 # will greatly help this.
276 278 s = ("import numpy\n"
277 279 "import matplotlib\n"
278 280 "from matplotlib import pylab, mlab, pyplot\n"
279 281 "np = numpy\n"
280 282 "plt = pyplot\n"
281 283 )
282 284 exec(s, user_ns)
283 285
284 286 if import_all:
285 287 s = ("from matplotlib.pylab import *\n"
286 288 "from numpy import *\n")
287 289 exec(s, user_ns)
288 290
289 291 # IPython symbols to add
290 292 user_ns['figsize'] = figsize
291 293 from IPython.core.display import display
292 294 # Add display and getfigs to the user's namespace
293 295 user_ns['display'] = display
294 296 user_ns['getfigs'] = getfigs
295 297
296 298
297 299 def configure_inline_support(shell, backend):
298 300 """Configure an IPython shell object for matplotlib use.
299 301
300 302 Parameters
301 303 ----------
302 304 shell : InteractiveShell instance
303 305
304 306 backend : matplotlib backend
305 307 """
306 308 # If using our svg payload backend, register the post-execution
307 309 # function that will pick up the results for display. This can only be
308 310 # done with access to the real shell object.
309 311
310 312 # Note: if we can't load the inline backend, then there's no point
311 313 # continuing (such as in terminal-only shells in environments without
312 314 # zeromq available).
313 315 try:
314 316 from IPython.kernel.zmq.pylab.backend_inline import InlineBackend
315 317 except ImportError:
316 318 return
317 319 from matplotlib import pyplot
318 320
319 321 cfg = InlineBackend.instance(parent=shell)
320 322 cfg.shell = shell
321 323 if cfg not in shell.configurables:
322 324 shell.configurables.append(cfg)
323 325
324 326 if backend == backends['inline']:
325 327 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
326 328 shell.register_post_execute(flush_figures)
327 329
328 330 # Save rcParams that will be overwrittern
329 331 shell._saved_rcParams = dict()
330 332 for k in cfg.rc:
331 333 shell._saved_rcParams[k] = pyplot.rcParams[k]
332 334 # load inline_rc
333 335 pyplot.rcParams.update(cfg.rc)
334 336 else:
335 337 from IPython.kernel.zmq.pylab.backend_inline import flush_figures
336 338 if flush_figures in shell._post_execute:
337 339 shell._post_execute.pop(flush_figures)
338 340 if hasattr(shell, '_saved_rcParams'):
339 341 pyplot.rcParams.update(shell._saved_rcParams)
340 342 del shell._saved_rcParams
341 343
342 344 # Setup the default figure format
343 345 select_figure_format(shell, cfg.figure_format, cfg.quality)
344 346
@@ -1,108 +1,108 b''
1 1 """Configurable for configuring the IPython inline backend
2 2
3 3 This module does not import anything from matplotlib.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2011 The IPython Development Team
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 from IPython.config.configurable import SingletonConfigurable
17 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, Bool, Int
17 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, Bool, Int, TraitError
18 18 from IPython.utils.warn import warn
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Configurable for inline backend options
22 22 #-----------------------------------------------------------------------------
23 23
24 24 def pil_available():
25 25 """Test if PIL/Pillow is available"""
26 26 out = False
27 27 try:
28 28 from PIL import Image
29 29 out = True
30 30 except:
31 31 pass
32 32 return out
33 33
34 34 # inherit from InlineBackendConfig for deprecation purposes
35 35 class InlineBackendConfig(SingletonConfigurable):
36 36 pass
37 37
38 38 class InlineBackend(InlineBackendConfig):
39 39 """An object to store configuration of the inline backend."""
40 40
41 41 def _config_changed(self, name, old, new):
42 42 # warn on change of renamed config section
43 43 if new.InlineBackendConfig != old.InlineBackendConfig:
44 44 warn("InlineBackendConfig has been renamed to InlineBackend")
45 45 super(InlineBackend, self)._config_changed(name, old, new)
46 46
47 47 # The typical default figure size is too large for inline use,
48 48 # so we shrink the figure size to 6x4, and tweak fonts to
49 49 # make that fit.
50 50 rc = Dict({'figure.figsize': (6.0,4.0),
51 51 # play nicely with white background in the Qt and notebook frontend
52 52 'figure.facecolor': (1,1,1,0),
53 53 'figure.edgecolor': (1,1,1,0),
54 54 # 12pt labels get cutoff on 6x4 logplots, so use 10pt.
55 55 'font.size': 10,
56 56 # 72 dpi matches SVG/qtconsole
57 57 # this only affects PNG export, as SVG has no dpi setting
58 58 'savefig.dpi': 72,
59 59 # 10pt still needs a little more room on the xlabel:
60 60 'figure.subplot.bottom' : .125
61 61 }, config=True,
62 62 help="""Subset of matplotlib rcParams that should be different for the
63 63 inline backend."""
64 64 )
65 65
66 66
67 67 figure_format = CaselessStrEnum(['svg', 'png', 'retina', 'jpg'],
68 68 default_value='png', config=True,
69 help="""The image format for figures with the inline backend.
70 JPEG requires the PIL/Pillow library.""")
69 help="""The image format for figures with the inline
70 backend. JPEG requires the PIL/Pillow library.""")
71 71
72 72 def _figure_format_changed(self, name, old, new):
73 73 from IPython.core.pylabtools import select_figure_format
74 74 if new in {"jpg", "jpeg"}:
75 75 if not pil_available():
76 76 raise TraitError("Requires PIL/Pillow for JPG figures")
77 77 if self.shell is None:
78 78 return
79 79 else:
80 80 select_figure_format(self.shell, new)
81 81
82 82 quality = Int(default_value=90, config=True,
83 help="Quality of compression [0-100], currently for lossy JPEG only.")
83 help="Quality of compression [10-100], currently for lossy JPEG only.")
84 84
85 85 def _quality_changed(self, name, old, new):
86 if new < 0 or new > 100:
87 raise TraitError("figure quality must be in [0-100] range.")
86 if new < 10 or new > 100:
87 raise TraitError("figure JPEG quality must be in [10-100] range.")
88 88
89 89 close_figures = Bool(True, config=True,
90 90 help="""Close all figures at the end of each cell.
91 91
92 92 When True, ensures that each cell starts with no active figures, but it
93 93 also means that one must keep track of references in order to edit or
94 94 redraw figures in subsequent cells. This mode is ideal for the notebook,
95 95 where residual plots from other cells might be surprising.
96 96
97 97 When False, one must call figure() to create new figures. This means
98 98 that gcf() and getfigs() can reference figures created in other cells,
99 99 and the active figure can continue to be edited with pylab/pyplot
100 100 methods that reference the current active figure. This mode facilitates
101 101 iterative editing of figures, and behaves most consistently with
102 102 other matplotlib backends, but figure barriers between cells must
103 103 be explicit.
104 104 """)
105 105
106 106 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
107 107
108 108
General Comments 0
You need to be logged in to leave comments. Login now