test_pylabtools.py
261 lines
| 8.2 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r3734 | """Tests for pylab tools module. | ||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (c) 2011, the IPython Development Team. | ||||
# | ||||
# Distributed under the terms of the Modified BSD License. | ||||
# | ||||
# The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
from __future__ import print_function | ||||
MinRK
|
r15684 | from io import UnsupportedOperation, BytesIO | ||
MinRK
|
r15390 | import matplotlib | ||
matplotlib.use('Agg') | ||||
from matplotlib.figure import Figure | ||||
Fernando Perez
|
r3734 | |||
MinRK
|
r15684 | from nose import SkipTest | ||
Fernando Perez
|
r3734 | import nose.tools as nt | ||
from matplotlib import pyplot as plt | ||||
Fernando Perez
|
r5468 | import numpy as np | ||
Fernando Perez
|
r3734 | |||
# Our own imports | ||||
MinRK
|
r15390 | from IPython.core.getipython import get_ipython | ||
MinRK
|
r11329 | from IPython.core.interactiveshell import InteractiveShell | ||
MinRK
|
r15390 | from IPython.core.display import _PNG, _JPEG | ||
Fernando Perez
|
r3734 | from .. import pylabtools as pt | ||
Daniel B. Vasquez
|
r14777 | from IPython.testing import decorators as dec | ||
Fernando Perez
|
r3734 | #----------------------------------------------------------------------------- | ||
# Globals and constants | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Local utilities | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Classes and functions | ||||
#----------------------------------------------------------------------------- | ||||
def test_figure_to_svg(): | ||||
# simple empty-figure test | ||||
fig = plt.figure() | ||||
Thomas Kluyver
|
r12374 | nt.assert_equal(pt.print_figure(fig, 'svg'), None) | ||
Fernando Perez
|
r3734 | |||
plt.close('all') | ||||
# simple check for at least svg-looking output | ||||
Fernando Perez
|
r3745 | fig = plt.figure() | ||
ax = fig.add_subplot(1,1,1) | ||||
Fernando Perez
|
r3734 | ax.plot([1,2,3]) | ||
plt.draw() | ||||
MinRK
|
r3984 | svg = pt.print_figure(fig, 'svg')[:100].lower() | ||
MinRK
|
r16048 | nt.assert_in(u'doctype svg', svg) | ||
Fernando Perez
|
r5468 | |||
MinRK
|
r15684 | def _check_pil_jpeg_bytes(): | ||
"""Skip if PIL can't write JPEGs to BytesIO objects""" | ||||
MinRK
|
r15686 | # PIL's JPEG plugin can't write to BytesIO objects | ||
# Pillow fixes this | ||||
MinRK
|
r15684 | from PIL import Image | ||
buf = BytesIO() | ||||
img = Image.new("RGB", (4,4)) | ||||
try: | ||||
img.save(buf, 'jpeg') | ||||
except Exception as e: | ||||
ename = e.__class__.__name__ | ||||
raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) | ||||
Daniel B. Vasquez
|
r14777 | @dec.skip_without("PIL.Image") | ||
MinRK
|
r15684 | def test_figure_to_jpeg(): | ||
_check_pil_jpeg_bytes() | ||||
# simple check for at least jpeg-looking output | ||||
Daniel B. Vasquez
|
r14777 | fig = plt.figure() | ||
ax = fig.add_subplot(1,1,1) | ||||
ax.plot([1,2,3]) | ||||
plt.draw() | ||||
MinRK
|
r15684 | jpeg = pt.print_figure(fig, 'jpeg', quality=50)[:100].lower() | ||
assert jpeg.startswith(_JPEG) | ||||
Daniel B. Vasquez
|
r14775 | |||
MinRK
|
r15390 | def test_retina_figure(): | ||
fig = plt.figure() | ||||
ax = fig.add_subplot(1,1,1) | ||||
ax.plot([1,2,3]) | ||||
plt.draw() | ||||
png, md = pt.retina_figure(fig) | ||||
assert png.startswith(_PNG) | ||||
nt.assert_in('width', md) | ||||
nt.assert_in('height', md) | ||||
_fmt_mime_map = { | ||||
'png': 'image/png', | ||||
'jpeg': 'image/jpeg', | ||||
'pdf': 'application/pdf', | ||||
'retina': 'image/png', | ||||
'svg': 'image/svg+xml', | ||||
} | ||||
def test_select_figure_formats_str(): | ||||
ip = get_ipython() | ||||
for fmt, active_mime in _fmt_mime_map.items(): | ||||
pt.select_figure_formats(ip, fmt) | ||||
for mime, f in ip.display_formatter.formatters.items(): | ||||
if mime == active_mime: | ||||
nt.assert_in(Figure, f) | ||||
else: | ||||
nt.assert_not_in(Figure, f) | ||||
def test_select_figure_formats_kwargs(): | ||||
ip = get_ipython() | ||||
kwargs = dict(quality=10, bbox_inches='tight') | ||||
pt.select_figure_formats(ip, 'png', **kwargs) | ||||
formatter = ip.display_formatter.formatters['image/png'] | ||||
f = formatter.lookup_by_type(Figure) | ||||
cell = f.__closure__[0].cell_contents | ||||
nt.assert_equal(cell, kwargs) | ||||
# check that the formatter doesn't raise | ||||
fig = plt.figure() | ||||
ax = fig.add_subplot(1,1,1) | ||||
ax.plot([1,2,3]) | ||||
plt.draw() | ||||
formatter.enabled = True | ||||
png = formatter(fig) | ||||
assert png.startswith(_PNG) | ||||
Fernando Perez
|
r5468 | |||
MinRK
|
r15390 | def test_select_figure_formats_set(): | ||
Fernando Perez
|
r5468 | ip = get_ipython() | ||
MinRK
|
r15390 | for fmts in [ | ||
{'png', 'svg'}, | ||||
['png'], | ||||
('jpeg', 'pdf', 'retina'), | ||||
{'svg'}, | ||||
]: | ||||
active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} | ||||
pt.select_figure_formats(ip, fmts) | ||||
for mime, f in ip.display_formatter.formatters.items(): | ||||
if mime in active_mimes: | ||||
nt.assert_in(Figure, f) | ||||
else: | ||||
nt.assert_not_in(Figure, f) | ||||
def test_select_figure_formats_bad(): | ||||
ip = get_ipython() | ||||
with nt.assert_raises(ValueError): | ||||
pt.select_figure_formats(ip, 'foo') | ||||
with nt.assert_raises(ValueError): | ||||
pt.select_figure_formats(ip, {'png', 'foo'}) | ||||
with nt.assert_raises(ValueError): | ||||
pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad']) | ||||
def test_import_pylab(): | ||||
Fernando Perez
|
r5469 | ns = {} | ||
pt.import_pylab(ns, import_all=False) | ||||
nt.assert_true('plt' in ns) | ||||
nt.assert_equal(ns['np'], np) | ||||
Ryan May
|
r7966 | |||
class TestPylabSwitch(object): | ||||
MinRK
|
r11329 | class Shell(InteractiveShell): | ||
def enable_gui(self, gui): | ||||
pass | ||||
Ryan May
|
r7966 | def setup(self): | ||
Ryan May
|
r8003 | import matplotlib | ||
def act_mpl(backend): | ||||
matplotlib.rcParams['backend'] = backend | ||||
# Save rcParams since they get modified | ||||
self._saved_rcParams = matplotlib.rcParams | ||||
Thomas Kluyver
|
r12924 | self._saved_rcParamsOrig = matplotlib.rcParamsOrig | ||
Ryan May
|
r8003 | matplotlib.rcParams = dict(backend='Qt4Agg') | ||
Thomas Kluyver
|
r12924 | matplotlib.rcParamsOrig = dict(backend='Qt4Agg') | ||
Ryan May
|
r8003 | |||
# Mock out functions | ||||
Ryan May
|
r7966 | self._save_am = pt.activate_matplotlib | ||
Ryan May
|
r8003 | pt.activate_matplotlib = act_mpl | ||
Ryan May
|
r7966 | self._save_ip = pt.import_pylab | ||
pt.import_pylab = lambda *a,**kw:None | ||||
self._save_cis = pt.configure_inline_support | ||||
pt.configure_inline_support = lambda *a,**kw:None | ||||
def teardown(self): | ||||
pt.activate_matplotlib = self._save_am | ||||
pt.import_pylab = self._save_ip | ||||
pt.configure_inline_support = self._save_cis | ||||
Ryan May
|
r8003 | import matplotlib | ||
matplotlib.rcParams = self._saved_rcParams | ||||
Thomas Kluyver
|
r12924 | matplotlib.rcParamsOrig = self._saved_rcParamsOrig | ||
Ryan May
|
r7966 | |||
def test_qt(self): | ||||
s = self.Shell() | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib(None) | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('inline') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'inline') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('qt') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('inline') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'inline') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib() | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
def test_inline(self): | ||||
s = self.Shell() | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('inline') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'inline') | ||
nt.assert_equal(s.pylab_gui_select, None) | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('inline') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'inline') | ||
nt.assert_equal(s.pylab_gui_select, None) | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('qt') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
Jan Schulz
|
r21756 | def test_inline_twice(self): | ||
"Using '%matplotlib inline' twice should not reset formatters" | ||||
ip = get_ipython() | ||||
gui, backend = ip.enable_matplotlib('inline') | ||||
nt.assert_equal(gui, 'inline') | ||||
fmts = {'png'} | ||||
active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} | ||||
pt.select_figure_formats(ip, fmts) | ||||
gui, backend = ip.enable_matplotlib('inline') | ||||
nt.assert_equal(gui, 'inline') | ||||
for mime, f in ip.display_formatter.formatters.items(): | ||||
if mime in active_mimes: | ||||
nt.assert_in(Figure, f) | ||||
else: | ||||
nt.assert_not_in(Figure, f) | ||||
Ryan May
|
r7966 | def test_qt_gtk(self): | ||
s = self.Shell() | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('qt') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib('gtk') | ||
Ryan May
|
r7966 | nt.assert_equal(gui, 'qt') | ||
nt.assert_equal(s.pylab_gui_select, 'qt') | ||||