##// END OF EJS Templates
Backport PR #11087: FIX: Remove the non-interactive backends from pylabtools.backend2gui
Thomas Kluyver -
Show More
@@ -1,413 +1,416 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Pylab (matplotlib) support utilities."""
3 3 from __future__ import print_function
4 4
5 5 # Copyright (c) IPython Development Team.
6 6 # Distributed under the terms of the Modified BSD License.
7 7
8 8 from io import BytesIO
9 9
10 10 from IPython.core.display import _pngxy
11 11 from IPython.utils.decorators import flag_calls
12 12 from IPython.utils import py3compat
13 13
14 14 # If user specifies a GUI, that dictates the backend, otherwise we read the
15 15 # user's mpl default from the mpl rc structure
16 16 backends = {'tk': 'TkAgg',
17 17 'gtk': 'GTKAgg',
18 18 'gtk3': 'GTK3Agg',
19 19 'wx': 'WXAgg',
20 20 'qt4': 'Qt4Agg',
21 21 'qt5': 'Qt5Agg',
22 22 'qt': 'Qt5Agg',
23 23 'osx': 'MacOSX',
24 24 'nbagg': 'nbAgg',
25 25 'notebook': 'nbAgg',
26 26 'agg': 'agg',
27 27 'svg': 'svg',
28 28 'pdf': 'pdf',
29 29 'ps': 'ps',
30 30 'inline': 'module://ipykernel.pylab.backend_inline',
31 31 'ipympl': 'module://ipympl.backend_nbagg',
32 32 'widget': 'module://ipympl.backend_nbagg',
33 33 }
34 34
35 35 # We also need a reverse backends2guis mapping that will properly choose which
36 36 # GUI support to activate based on the desired matplotlib backend. For the
37 37 # most part it's just a reverse of the above dict, but we also need to add a
38 38 # few others that map to the same GUI manually:
39 39 backend2gui = dict(zip(backends.values(), backends.keys()))
40 40 # Our tests expect backend2gui to just return 'qt'
41 41 backend2gui['Qt4Agg'] = 'qt'
42 42 # In the reverse mapping, there are a few extra valid matplotlib backends that
43 43 # map to the same GUI support
44 44 backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk'
45 45 backend2gui['GTK3Cairo'] = 'gtk3'
46 46 backend2gui['WX'] = 'wx'
47 47 backend2gui['CocoaAgg'] = 'osx'
48 48 # And some backends that don't need GUI integration
49 49 del backend2gui['nbAgg']
50 50 del backend2gui['agg']
51 del backend2gui['svg']
52 del backend2gui['pdf']
53 del backend2gui['ps']
51 54 del backend2gui['module://ipykernel.pylab.backend_inline']
52 55
53 56 #-----------------------------------------------------------------------------
54 57 # Matplotlib utilities
55 58 #-----------------------------------------------------------------------------
56 59
57 60
58 61 def getfigs(*fig_nums):
59 62 """Get a list of matplotlib figures by figure numbers.
60 63
61 64 If no arguments are given, all available figures are returned. If the
62 65 argument list contains references to invalid figures, a warning is printed
63 66 but the function continues pasting further figures.
64 67
65 68 Parameters
66 69 ----------
67 70 figs : tuple
68 71 A tuple of ints giving the figure numbers of the figures to return.
69 72 """
70 73 from matplotlib._pylab_helpers import Gcf
71 74 if not fig_nums:
72 75 fig_managers = Gcf.get_all_fig_managers()
73 76 return [fm.canvas.figure for fm in fig_managers]
74 77 else:
75 78 figs = []
76 79 for num in fig_nums:
77 80 f = Gcf.figs.get(num)
78 81 if f is None:
79 82 print('Warning: figure %s not available.' % num)
80 83 else:
81 84 figs.append(f.canvas.figure)
82 85 return figs
83 86
84 87
85 88 def figsize(sizex, sizey):
86 89 """Set the default figure size to be [sizex, sizey].
87 90
88 91 This is just an easy to remember, convenience wrapper that sets::
89 92
90 93 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
91 94 """
92 95 import matplotlib
93 96 matplotlib.rcParams['figure.figsize'] = [sizex, sizey]
94 97
95 98
96 99 def print_figure(fig, fmt='png', bbox_inches='tight', **kwargs):
97 100 """Print a figure to an image, and return the resulting file data
98 101
99 102 Returned data will be bytes unless ``fmt='svg'``,
100 103 in which case it will be unicode.
101 104
102 105 Any keyword args are passed to fig.canvas.print_figure,
103 106 such as ``quality`` or ``bbox_inches``.
104 107 """
105 108 from matplotlib import rcParams
106 109 # When there's an empty figure, we shouldn't return anything, otherwise we
107 110 # get big blank areas in the qt console.
108 111 if not fig.axes and not fig.lines:
109 112 return
110 113
111 114 dpi = fig.dpi
112 115 if fmt == 'retina':
113 116 dpi = dpi * 2
114 117 fmt = 'png'
115 118
116 119 # build keyword args
117 120 kw = dict(
118 121 format=fmt,
119 122 facecolor=fig.get_facecolor(),
120 123 edgecolor=fig.get_edgecolor(),
121 124 dpi=dpi,
122 125 bbox_inches=bbox_inches,
123 126 )
124 127 # **kwargs get higher priority
125 128 kw.update(kwargs)
126 129
127 130 bytes_io = BytesIO()
128 131 fig.canvas.print_figure(bytes_io, **kw)
129 132 data = bytes_io.getvalue()
130 133 if fmt == 'svg':
131 134 data = data.decode('utf-8')
132 135 return data
133 136
134 137 def retina_figure(fig, **kwargs):
135 138 """format a figure as a pixel-doubled (retina) PNG"""
136 139 pngdata = print_figure(fig, fmt='retina', **kwargs)
137 140 # Make sure that retina_figure acts just like print_figure and returns
138 141 # None when the figure is empty.
139 142 if pngdata is None:
140 143 return
141 144 w, h = _pngxy(pngdata)
142 145 metadata = dict(width=w//2, height=h//2)
143 146 return pngdata, metadata
144 147
145 148 # We need a little factory function here to create the closure where
146 149 # safe_execfile can live.
147 150 def mpl_runner(safe_execfile):
148 151 """Factory to return a matplotlib-enabled runner for %run.
149 152
150 153 Parameters
151 154 ----------
152 155 safe_execfile : function
153 156 This must be a function with the same interface as the
154 157 :meth:`safe_execfile` method of IPython.
155 158
156 159 Returns
157 160 -------
158 161 A function suitable for use as the ``runner`` argument of the %run magic
159 162 function.
160 163 """
161 164
162 165 def mpl_execfile(fname,*where,**kw):
163 166 """matplotlib-aware wrapper around safe_execfile.
164 167
165 168 Its interface is identical to that of the :func:`execfile` builtin.
166 169
167 170 This is ultimately a call to execfile(), but wrapped in safeties to
168 171 properly handle interactive rendering."""
169 172
170 173 import matplotlib
171 174 import matplotlib.pyplot as plt
172 175
173 176 #print '*** Matplotlib runner ***' # dbg
174 177 # turn off rendering until end of script
175 178 is_interactive = matplotlib.rcParams['interactive']
176 179 matplotlib.interactive(False)
177 180 safe_execfile(fname,*where,**kw)
178 181 matplotlib.interactive(is_interactive)
179 182 # make rendering call now, if the user tried to do it
180 183 if plt.draw_if_interactive.called:
181 184 plt.draw()
182 185 plt.draw_if_interactive.called = False
183 186
184 187 # re-draw everything that is stale
185 188 try:
186 189 da = plt.draw_all
187 190 except AttributeError:
188 191 pass
189 192 else:
190 193 da()
191 194
192 195 return mpl_execfile
193 196
194 197
195 198 def _reshow_nbagg_figure(fig):
196 199 """reshow an nbagg figure"""
197 200 try:
198 201 reshow = fig.canvas.manager.reshow
199 202 except AttributeError:
200 203 raise NotImplementedError()
201 204 else:
202 205 reshow()
203 206
204 207
205 208 def select_figure_formats(shell, formats, **kwargs):
206 209 """Select figure formats for the inline backend.
207 210
208 211 Parameters
209 212 ==========
210 213 shell : InteractiveShell
211 214 The main IPython instance.
212 215 formats : str or set
213 216 One or a set of figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
214 217 **kwargs : any
215 218 Extra keyword arguments to be passed to fig.canvas.print_figure.
216 219 """
217 220 import matplotlib
218 221 from matplotlib.figure import Figure
219 222
220 223 svg_formatter = shell.display_formatter.formatters['image/svg+xml']
221 224 png_formatter = shell.display_formatter.formatters['image/png']
222 225 jpg_formatter = shell.display_formatter.formatters['image/jpeg']
223 226 pdf_formatter = shell.display_formatter.formatters['application/pdf']
224 227
225 228 if isinstance(formats, py3compat.string_types):
226 229 formats = {formats}
227 230 # cast in case of list / tuple
228 231 formats = set(formats)
229 232
230 233 [ f.pop(Figure, None) for f in shell.display_formatter.formatters.values() ]
231 234 mplbackend = matplotlib.get_backend().lower()
232 235 if mplbackend == 'nbagg' or mplbackend == 'module://ipympl.backend_nbagg':
233 236 formatter = shell.display_formatter.ipython_display_formatter
234 237 formatter.for_type(Figure, _reshow_nbagg_figure)
235 238
236 239 supported = {'png', 'png2x', 'retina', 'jpg', 'jpeg', 'svg', 'pdf'}
237 240 bad = formats.difference(supported)
238 241 if bad:
239 242 bs = "%s" % ','.join([repr(f) for f in bad])
240 243 gs = "%s" % ','.join([repr(f) for f in supported])
241 244 raise ValueError("supported formats are: %s not %s" % (gs, bs))
242 245
243 246 if 'png' in formats:
244 247 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
245 248 if 'retina' in formats or 'png2x' in formats:
246 249 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
247 250 if 'jpg' in formats or 'jpeg' in formats:
248 251 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
249 252 if 'svg' in formats:
250 253 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
251 254 if 'pdf' in formats:
252 255 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))
253 256
254 257 #-----------------------------------------------------------------------------
255 258 # Code for initializing matplotlib and importing pylab
256 259 #-----------------------------------------------------------------------------
257 260
258 261
259 262 def find_gui_and_backend(gui=None, gui_select=None):
260 263 """Given a gui string return the gui and mpl backend.
261 264
262 265 Parameters
263 266 ----------
264 267 gui : str
265 268 Can be one of ('tk','gtk','wx','qt','qt4','inline').
266 269 gui_select : str
267 270 Can be one of ('tk','gtk','wx','qt','qt4','inline').
268 271 This is any gui already selected by the shell.
269 272
270 273 Returns
271 274 -------
272 275 A tuple of (gui, backend) where backend is one of ('TkAgg','GTKAgg',
273 276 'WXAgg','Qt4Agg','module://ipykernel.pylab.backend_inline').
274 277 """
275 278
276 279 import matplotlib
277 280
278 281 if gui and gui != 'auto':
279 282 # select backend based on requested gui
280 283 backend = backends[gui]
281 284 else:
282 285 # We need to read the backend from the original data structure, *not*
283 286 # from mpl.rcParams, since a prior invocation of %matplotlib may have
284 287 # overwritten that.
285 288 # WARNING: this assumes matplotlib 1.1 or newer!!
286 289 backend = matplotlib.rcParamsOrig['backend']
287 290 # In this case, we need to find what the appropriate gui selection call
288 291 # should be for IPython, so we can activate inputhook accordingly
289 292 gui = backend2gui.get(backend, None)
290 293
291 294 # If we have already had a gui active, we need it and inline are the
292 295 # ones allowed.
293 296 if gui_select and gui != gui_select:
294 297 gui = gui_select
295 298 backend = backends[gui]
296 299
297 300 return gui, backend
298 301
299 302
300 303 def activate_matplotlib(backend):
301 304 """Activate the given backend and set interactive to True."""
302 305
303 306 import matplotlib
304 307 matplotlib.interactive(True)
305 308
306 309 # Matplotlib had a bug where even switch_backend could not force
307 310 # the rcParam to update. This needs to be set *before* the module
308 311 # magic of switch_backend().
309 312 matplotlib.rcParams['backend'] = backend
310 313
311 314 import matplotlib.pyplot
312 315 matplotlib.pyplot.switch_backend(backend)
313 316
314 317 # This must be imported last in the matplotlib series, after
315 318 # backend/interactivity choices have been made
316 319 import matplotlib.pyplot as plt
317 320
318 321 plt.show._needmain = False
319 322 # We need to detect at runtime whether show() is called by the user.
320 323 # For this, we wrap it into a decorator which adds a 'called' flag.
321 324 plt.draw_if_interactive = flag_calls(plt.draw_if_interactive)
322 325
323 326
324 327 def import_pylab(user_ns, import_all=True):
325 328 """Populate the namespace with pylab-related values.
326 329
327 330 Imports matplotlib, pylab, numpy, and everything from pylab and numpy.
328 331
329 332 Also imports a few names from IPython (figsize, display, getfigs)
330 333
331 334 """
332 335
333 336 # Import numpy as np/pyplot as plt are conventions we're trying to
334 337 # somewhat standardize on. Making them available to users by default
335 338 # will greatly help this.
336 339 s = ("import numpy\n"
337 340 "import matplotlib\n"
338 341 "from matplotlib import pylab, mlab, pyplot\n"
339 342 "np = numpy\n"
340 343 "plt = pyplot\n"
341 344 )
342 345 exec(s, user_ns)
343 346
344 347 if import_all:
345 348 s = ("from matplotlib.pylab import *\n"
346 349 "from numpy import *\n")
347 350 exec(s, user_ns)
348 351
349 352 # IPython symbols to add
350 353 user_ns['figsize'] = figsize
351 354 from IPython.core.display import display
352 355 # Add display and getfigs to the user's namespace
353 356 user_ns['display'] = display
354 357 user_ns['getfigs'] = getfigs
355 358
356 359
357 360 def configure_inline_support(shell, backend):
358 361 """Configure an IPython shell object for matplotlib use.
359 362
360 363 Parameters
361 364 ----------
362 365 shell : InteractiveShell instance
363 366
364 367 backend : matplotlib backend
365 368 """
366 369 # If using our svg payload backend, register the post-execution
367 370 # function that will pick up the results for display. This can only be
368 371 # done with access to the real shell object.
369 372
370 373 # Note: if we can't load the inline backend, then there's no point
371 374 # continuing (such as in terminal-only shells in environments without
372 375 # zeromq available).
373 376 try:
374 377 from ipykernel.pylab.backend_inline import InlineBackend
375 378 except ImportError:
376 379 return
377 380 import matplotlib
378 381
379 382 cfg = InlineBackend.instance(parent=shell)
380 383 cfg.shell = shell
381 384 if cfg not in shell.configurables:
382 385 shell.configurables.append(cfg)
383 386
384 387 if backend == backends['inline']:
385 388 from ipykernel.pylab.backend_inline import flush_figures
386 389 shell.events.register('post_execute', flush_figures)
387 390
388 391 # Save rcParams that will be overwrittern
389 392 shell._saved_rcParams = dict()
390 393 for k in cfg.rc:
391 394 shell._saved_rcParams[k] = matplotlib.rcParams[k]
392 395 # load inline_rc
393 396 matplotlib.rcParams.update(cfg.rc)
394 397 new_backend_name = "inline"
395 398 else:
396 399 from ipykernel.pylab.backend_inline import flush_figures
397 400 try:
398 401 shell.events.unregister('post_execute', flush_figures)
399 402 except ValueError:
400 403 pass
401 404 if hasattr(shell, '_saved_rcParams'):
402 405 matplotlib.rcParams.update(shell._saved_rcParams)
403 406 del shell._saved_rcParams
404 407 new_backend_name = "other"
405 408
406 409 # only enable the formats once -> don't change the enabled formats (which the user may
407 410 # has changed) when getting another "%matplotlib inline" call.
408 411 # See https://github.com/ipython/ipykernel/issues/29
409 412 cur_backend = getattr(configure_inline_support, "current_backend", "unset")
410 413 if new_backend_name != cur_backend:
411 414 # Setup the default figure format
412 415 select_figure_formats(shell, cfg.figure_formats, **cfg.print_figure_kwargs)
413 416 configure_inline_support.current_backend = new_backend_name
@@ -1,247 +1,251 b''
1 1 """Tests for pylab tools module.
2 2 """
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 from __future__ import print_function
8 8
9 9 from io import UnsupportedOperation, BytesIO
10 10
11 11 import matplotlib
12 12 matplotlib.use('Agg')
13 13 from matplotlib.figure import Figure
14 14
15 15 from nose import SkipTest
16 16 import nose.tools as nt
17 17
18 18 from matplotlib import pyplot as plt
19 19 import numpy as np
20 20
21 21 from IPython.core.getipython import get_ipython
22 22 from IPython.core.interactiveshell import InteractiveShell
23 23 from IPython.core.display import _PNG, _JPEG
24 24 from .. import pylabtools as pt
25 25
26 26 from IPython.testing import decorators as dec
27 27
28 28
29 29 def test_figure_to_svg():
30 30 # simple empty-figure test
31 31 fig = plt.figure()
32 32 nt.assert_equal(pt.print_figure(fig, 'svg'), None)
33 33
34 34 plt.close('all')
35 35
36 36 # simple check for at least svg-looking output
37 37 fig = plt.figure()
38 38 ax = fig.add_subplot(1,1,1)
39 39 ax.plot([1,2,3])
40 40 plt.draw()
41 41 svg = pt.print_figure(fig, 'svg')[:100].lower()
42 42 nt.assert_in(u'doctype svg', svg)
43 43
44 44 def _check_pil_jpeg_bytes():
45 45 """Skip if PIL can't write JPEGs to BytesIO objects"""
46 46 # PIL's JPEG plugin can't write to BytesIO objects
47 47 # Pillow fixes this
48 48 from PIL import Image
49 49 buf = BytesIO()
50 50 img = Image.new("RGB", (4,4))
51 51 try:
52 52 img.save(buf, 'jpeg')
53 53 except Exception as e:
54 54 ename = e.__class__.__name__
55 55 raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e))
56 56
57 57 @dec.skip_without("PIL.Image")
58 58 def test_figure_to_jpeg():
59 59 _check_pil_jpeg_bytes()
60 60 # simple check for at least jpeg-looking output
61 61 fig = plt.figure()
62 62 ax = fig.add_subplot(1,1,1)
63 63 ax.plot([1,2,3])
64 64 plt.draw()
65 65 jpeg = pt.print_figure(fig, 'jpeg', quality=50)[:100].lower()
66 66 assert jpeg.startswith(_JPEG)
67 67
68 68 def test_retina_figure():
69 69 # simple empty-figure test
70 70 fig = plt.figure()
71 71 nt.assert_equal(pt.retina_figure(fig), None)
72 72 plt.close('all')
73 73
74 74 fig = plt.figure()
75 75 ax = fig.add_subplot(1,1,1)
76 76 ax.plot([1,2,3])
77 77 plt.draw()
78 78 png, md = pt.retina_figure(fig)
79 79 assert png.startswith(_PNG)
80 80 nt.assert_in('width', md)
81 81 nt.assert_in('height', md)
82 82
83 83 _fmt_mime_map = {
84 84 'png': 'image/png',
85 85 'jpeg': 'image/jpeg',
86 86 'pdf': 'application/pdf',
87 87 'retina': 'image/png',
88 88 'svg': 'image/svg+xml',
89 89 }
90 90
91 91 def test_select_figure_formats_str():
92 92 ip = get_ipython()
93 93 for fmt, active_mime in _fmt_mime_map.items():
94 94 pt.select_figure_formats(ip, fmt)
95 95 for mime, f in ip.display_formatter.formatters.items():
96 96 if mime == active_mime:
97 97 nt.assert_in(Figure, f)
98 98 else:
99 99 nt.assert_not_in(Figure, f)
100 100
101 101 def test_select_figure_formats_kwargs():
102 102 ip = get_ipython()
103 103 kwargs = dict(quality=10, bbox_inches='tight')
104 104 pt.select_figure_formats(ip, 'png', **kwargs)
105 105 formatter = ip.display_formatter.formatters['image/png']
106 106 f = formatter.lookup_by_type(Figure)
107 107 cell = f.__closure__[0].cell_contents
108 108 nt.assert_equal(cell, kwargs)
109
109
110 110 # check that the formatter doesn't raise
111 111 fig = plt.figure()
112 112 ax = fig.add_subplot(1,1,1)
113 113 ax.plot([1,2,3])
114 114 plt.draw()
115 115 formatter.enabled = True
116 116 png = formatter(fig)
117 117 assert png.startswith(_PNG)
118 118
119 119 def test_select_figure_formats_set():
120 120 ip = get_ipython()
121 121 for fmts in [
122 122 {'png', 'svg'},
123 123 ['png'],
124 124 ('jpeg', 'pdf', 'retina'),
125 125 {'svg'},
126 126 ]:
127 127 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
128 128 pt.select_figure_formats(ip, fmts)
129 129 for mime, f in ip.display_formatter.formatters.items():
130 130 if mime in active_mimes:
131 131 nt.assert_in(Figure, f)
132 132 else:
133 133 nt.assert_not_in(Figure, f)
134 134
135 135 def test_select_figure_formats_bad():
136 136 ip = get_ipython()
137 137 with nt.assert_raises(ValueError):
138 138 pt.select_figure_formats(ip, 'foo')
139 139 with nt.assert_raises(ValueError):
140 140 pt.select_figure_formats(ip, {'png', 'foo'})
141 141 with nt.assert_raises(ValueError):
142 142 pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad'])
143 143
144 144 def test_import_pylab():
145 145 ns = {}
146 146 pt.import_pylab(ns, import_all=False)
147 147 nt.assert_true('plt' in ns)
148 148 nt.assert_equal(ns['np'], np)
149 149
150 150 class TestPylabSwitch(object):
151 151 class Shell(InteractiveShell):
152 152 def enable_gui(self, gui):
153 153 pass
154
154
155 155 def setup(self):
156 156 import matplotlib
157 157 def act_mpl(backend):
158 158 matplotlib.rcParams['backend'] = backend
159 159
160 160 # Save rcParams since they get modified
161 161 self._saved_rcParams = matplotlib.rcParams
162 162 self._saved_rcParamsOrig = matplotlib.rcParamsOrig
163 163 matplotlib.rcParams = dict(backend='Qt4Agg')
164 164 matplotlib.rcParamsOrig = dict(backend='Qt4Agg')
165 165
166 166 # Mock out functions
167 167 self._save_am = pt.activate_matplotlib
168 168 pt.activate_matplotlib = act_mpl
169 169 self._save_ip = pt.import_pylab
170 170 pt.import_pylab = lambda *a,**kw:None
171 171 self._save_cis = pt.configure_inline_support
172 172 pt.configure_inline_support = lambda *a,**kw:None
173 173
174 174 def teardown(self):
175 175 pt.activate_matplotlib = self._save_am
176 176 pt.import_pylab = self._save_ip
177 177 pt.configure_inline_support = self._save_cis
178 178 import matplotlib
179 179 matplotlib.rcParams = self._saved_rcParams
180 180 matplotlib.rcParamsOrig = self._saved_rcParamsOrig
181 181
182 182 def test_qt(self):
183 183 s = self.Shell()
184 184 gui, backend = s.enable_matplotlib(None)
185 185 nt.assert_equal(gui, 'qt')
186 186 nt.assert_equal(s.pylab_gui_select, 'qt')
187 187
188 188 gui, backend = s.enable_matplotlib('inline')
189 189 nt.assert_equal(gui, 'inline')
190 190 nt.assert_equal(s.pylab_gui_select, 'qt')
191 191
192 192 gui, backend = s.enable_matplotlib('qt')
193 193 nt.assert_equal(gui, 'qt')
194 194 nt.assert_equal(s.pylab_gui_select, 'qt')
195 195
196 196 gui, backend = s.enable_matplotlib('inline')
197 197 nt.assert_equal(gui, 'inline')
198 198 nt.assert_equal(s.pylab_gui_select, 'qt')
199 199
200 200 gui, backend = s.enable_matplotlib()
201 201 nt.assert_equal(gui, 'qt')
202 202 nt.assert_equal(s.pylab_gui_select, 'qt')
203 203
204 204 def test_inline(self):
205 205 s = self.Shell()
206 206 gui, backend = s.enable_matplotlib('inline')
207 207 nt.assert_equal(gui, 'inline')
208 208 nt.assert_equal(s.pylab_gui_select, None)
209 209
210 210 gui, backend = s.enable_matplotlib('inline')
211 211 nt.assert_equal(gui, 'inline')
212 212 nt.assert_equal(s.pylab_gui_select, None)
213 213
214 214 gui, backend = s.enable_matplotlib('qt')
215 215 nt.assert_equal(gui, 'qt')
216 216 nt.assert_equal(s.pylab_gui_select, 'qt')
217 217
218 218 def test_inline_twice(self):
219 219 "Using '%matplotlib inline' twice should not reset formatters"
220 220
221 221 ip = self.Shell()
222 222 gui, backend = ip.enable_matplotlib('inline')
223 223 nt.assert_equal(gui, 'inline')
224 224
225 225 fmts = {'png'}
226 226 active_mimes = {_fmt_mime_map[fmt] for fmt in fmts}
227 227 pt.select_figure_formats(ip, fmts)
228 228
229 229 gui, backend = ip.enable_matplotlib('inline')
230 230 nt.assert_equal(gui, 'inline')
231 231
232 232 for mime, f in ip.display_formatter.formatters.items():
233 233 if mime in active_mimes:
234 234 nt.assert_in(Figure, f)
235 235 else:
236 236 nt.assert_not_in(Figure, f)
237 237
238 238 def test_qt_gtk(self):
239 239 s = self.Shell()
240 240 gui, backend = s.enable_matplotlib('qt')
241 241 nt.assert_equal(gui, 'qt')
242 242 nt.assert_equal(s.pylab_gui_select, 'qt')
243 243
244 244 gui, backend = s.enable_matplotlib('gtk')
245 245 nt.assert_equal(gui, 'qt')
246 246 nt.assert_equal(s.pylab_gui_select, 'qt')
247 247
248
249 def test_no_gui_backends():
250 for k in ['agg', 'svg', 'pdf', 'ps']:
251 assert k not in pt.backend2gui
General Comments 0
You need to be logged in to leave comments. Login now