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