test_pylabtools.py
270 lines
| 7.7 KiB
| text/x-python
|
PythonLexer
Fernando Perez
|
r3734 | """Tests for pylab tools module. | ||
""" | ||||
Min RK
|
r21765 | |||
# Copyright (c) IPython Development Team. | ||||
Fernando Perez
|
r3734 | # Distributed under the terms of the Modified BSD License. | ||
Min RK
|
r26812 | from binascii import a2b_base64 | ||
from io import BytesIO | ||||
MinRK
|
r15684 | |||
Nikita Kniazev
|
r26998 | import pytest | ||
matplotlib = pytest.importorskip("matplotlib") | ||||
MinRK
|
r15390 | matplotlib.use('Agg') | ||
from matplotlib.figure import Figure | ||||
Fernando Perez
|
r3734 | |||
from matplotlib import pyplot as plt | ||||
Samuel Gaist
|
r26907 | from matplotlib_inline import backend_inline | ||
Fernando Perez
|
r5468 | import numpy as np | ||
Fernando Perez
|
r3734 | |||
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 | |||
def test_figure_to_svg(): | ||||
# simple empty-figure test | ||||
fig = plt.figure() | ||||
Samuel Gaist
|
r26907 | assert pt.print_figure(fig, "svg") is 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() | ||||
Samuel Gaist
|
r26907 | svg = pt.print_figure(fig, "svg")[:100].lower() | ||
assert "doctype svg" in 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__ | ||||
Samuel Gaist
|
r26907 | raise pytest.skip("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) from e | ||
MinRK
|
r15684 | |||
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() | ||||
Matthias Bussonnier
|
r25633 | jpeg = pt.print_figure(fig, 'jpeg', pil_kwargs={'optimize': 50})[:100].lower() | ||
MinRK
|
r15684 | assert jpeg.startswith(_JPEG) | ||
Daniel B. Vasquez
|
r14775 | |||
MinRK
|
r15390 | def test_retina_figure(): | ||
Christopher Roach
|
r21813 | # simple empty-figure test | ||
fig = plt.figure() | ||||
Samuel Gaist
|
r26907 | assert pt.retina_figure(fig) == None | ||
Christopher Roach
|
r21813 | plt.close('all') | ||
MinRK
|
r15390 | 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) | ||||
Samuel Gaist
|
r26907 | assert "width" in md | ||
assert "height" in md | ||||
MinRK
|
r15390 | |||
_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: | ||||
Samuel Gaist
|
r26907 | assert Figure in f | ||
MinRK
|
r15390 | else: | ||
Samuel Gaist
|
r26907 | assert Figure not in f | ||
MinRK
|
r15390 | |||
def test_select_figure_formats_kwargs(): | ||||
ip = get_ipython() | ||||
Nikita Kniazev
|
r27009 | kwargs = dict(bbox_inches="tight") | ||
pt.select_figure_formats(ip, "png", **kwargs) | ||||
formatter = ip.display_formatter.formatters["image/png"] | ||||
MinRK
|
r15390 | f = formatter.lookup_by_type(Figure) | ||
Min RK
|
r26812 | cell = f.keywords | ||
expected = kwargs | ||||
expected["base64"] = True | ||||
expected["fmt"] = "png" | ||||
assert cell == expected | ||||
Thomas A Caswell
|
r24290 | |||
MinRK
|
r15390 | # 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) | ||||
Min RK
|
r26812 | assert isinstance(png, str) | ||
png_bytes = a2b_base64(png) | ||||
assert png_bytes.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: | ||||
Samuel Gaist
|
r26907 | assert Figure in f | ||
MinRK
|
r15390 | else: | ||
Samuel Gaist
|
r26907 | assert Figure not in f | ||
MinRK
|
r15390 | |||
def test_select_figure_formats_bad(): | ||||
ip = get_ipython() | ||||
Samuel Gaist
|
r26907 | with pytest.raises(ValueError): | ||
MinRK
|
r15390 | pt.select_figure_formats(ip, 'foo') | ||
Samuel Gaist
|
r26907 | with pytest.raises(ValueError): | ||
MinRK
|
r15390 | pt.select_figure_formats(ip, {'png', 'foo'}) | ||
Samuel Gaist
|
r26907 | with pytest.raises(ValueError): | ||
MinRK
|
r15390 | pt.select_figure_formats(ip, ['retina', 'pdf', 'bar', 'bad']) | ||
def test_import_pylab(): | ||||
Fernando Perez
|
r5469 | ns = {} | ||
pt.import_pylab(ns, import_all=False) | ||||
Samuel Gaist
|
r26907 | assert "plt" in ns | ||
assert ns["np"] == np | ||||
Ryan May
|
r7966 | |||
class TestPylabSwitch(object): | ||||
MinRK
|
r11329 | class Shell(InteractiveShell): | ||
Matthias Bussonnier
|
r26428 | def init_history(self): | ||
"""Sets up the command history, and starts regular autosaves.""" | ||||
self.config.HistoryManager.hist_file = ":memory:" | ||||
super().init_history() | ||||
MinRK
|
r11329 | def enable_gui(self, gui): | ||
pass | ||||
Thomas A Caswell
|
r24290 | |||
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 | ||||
Samuel Gaist
|
r26907 | self._save_cis = backend_inline.configure_inline_support | ||
backend_inline.configure_inline_support = lambda *a, **kw: None | ||||
Ryan May
|
r7966 | |||
def teardown(self): | ||||
pt.activate_matplotlib = self._save_am | ||||
pt.import_pylab = self._save_ip | ||||
Samuel Gaist
|
r26907 | backend_inline.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) | ||
Samuel Gaist
|
r26907 | assert gui == "qt" | ||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("qt") | ||
assert gui == "qt" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
MinRK
|
r11329 | gui, backend = s.enable_matplotlib() | ||
Samuel Gaist
|
r26907 | assert gui == "qt" | ||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
def test_inline(self): | ||||
s = self.Shell() | ||||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
assert s.pylab_gui_select == None | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
assert s.pylab_gui_select == None | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("qt") | ||
assert gui == "qt" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Jan Schulz
|
r21756 | def test_inline_twice(self): | ||
"Using '%matplotlib inline' twice should not reset formatters" | ||||
Min RK
|
r21765 | ip = self.Shell() | ||
Samuel Gaist
|
r26907 | gui, backend = ip.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
Jan Schulz
|
r21756 | |||
fmts = {'png'} | ||||
active_mimes = {_fmt_mime_map[fmt] for fmt in fmts} | ||||
pt.select_figure_formats(ip, fmts) | ||||
Samuel Gaist
|
r26907 | gui, backend = ip.enable_matplotlib("inline") | ||
assert gui == "inline" | ||||
Jan Schulz
|
r21756 | |||
for mime, f in ip.display_formatter.formatters.items(): | ||||
if mime in active_mimes: | ||||
Samuel Gaist
|
r26907 | assert Figure in f | ||
Jan Schulz
|
r21756 | else: | ||
Samuel Gaist
|
r26907 | assert Figure not in f | ||
Jan Schulz
|
r21756 | |||
Ryan May
|
r7966 | def test_qt_gtk(self): | ||
s = self.Shell() | ||||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("qt") | ||
assert gui == "qt" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Samuel Gaist
|
r26907 | gui, backend = s.enable_matplotlib("gtk") | ||
assert gui == "qt" | ||||
assert s.pylab_gui_select == "qt" | ||||
Ryan May
|
r7966 | |||
Thomas A Caswell
|
r24290 | |||
def test_no_gui_backends(): | ||||
for k in ['agg', 'svg', 'pdf', 'ps']: | ||||
assert k not in pt.backend2gui | ||||
Thomas A Caswell
|
r25419 | |||
def test_figure_no_canvas(): | ||||
fig = Figure() | ||||
fig.canvas = None | ||||
pt.print_figure(fig) | ||||