-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from ccordoba12/ipdb-mpl-support
PR: Add %matplotlib magic to the IPdb kernel
- Loading branch information
Showing
9 changed files
with
234 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2018- Spyder Kernels Contributors | ||
# Copyright (c) IPython Development Team. | ||
# Distributed under the terms of the Modified BSD License. | ||
# ----------------------------------------------------------------------------- | ||
|
||
""" | ||
Functions for our inline backend. | ||
This is a simplified version of some functions present in | ||
ipykernel/pylab/backend_inline.py | ||
""" | ||
|
||
from ipykernel.pylab.backend_inline import _fetch_figure_metadata | ||
from IPython.display import Image | ||
from metakernel.display import display | ||
|
||
from spyder_kernels.py3compat import io, PY2 | ||
|
||
|
||
def get_image(figure): | ||
""" | ||
Get image display object from a Matplotlib figure. | ||
The idea to get png/svg from a figure was taken from | ||
https://stackoverflow.com/a/12145161/438386 | ||
""" | ||
# Print figure to a bytes stream | ||
if PY2: | ||
data = io.StringIO() | ||
else: | ||
data = io.BytesIO() | ||
figure.canvas.print_figure(data, bbox_inches='tight') | ||
|
||
# Get figure metadata | ||
metadata = _fetch_figure_metadata(figure) | ||
|
||
img = Image(data=data.getvalue(), metadata=metadata) | ||
return img | ||
|
||
|
||
def show(): | ||
""" | ||
Show all figures as PNG payloads sent to the Jupyter clients. | ||
""" | ||
import matplotlib | ||
from matplotlib._pylab_helpers import Gcf | ||
|
||
try: | ||
for figure_manager in Gcf.get_all_fig_managers(): | ||
display(get_image(figure_manager.canvas.figure)) | ||
finally: | ||
if Gcf.get_all_fig_managers(): | ||
matplotlib.pyplot.close('all') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2018- Spyder Kernels Contributors | ||
# | ||
# Licensed under the terms of the MIT License | ||
# (see spyder_kernels/__init__.py for details) | ||
# ----------------------------------------------------------------------------- | ||
|
||
from metakernel import Magic | ||
|
||
|
||
class MatplotlibMagic(Magic): | ||
|
||
def line_matplotlib(self, gui): | ||
""" | ||
Matplotlib magic | ||
You can set all backends you can with the IPython %matplotlib | ||
magic. | ||
""" | ||
gui, backend = self.kernel.ipyshell.enable_matplotlib(gui=gui) | ||
self.kernel.mpl_gui = gui | ||
|
||
|
||
def register_magics(kernel): | ||
kernel.register_magics(MatplotlibMagic) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# -*- coding: utf-8 -*- | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2018- Spyder Kernels Contributors | ||
# | ||
# Licensed under the terms of the MIT License | ||
# (see spyder_kernels/__init__.py for details) | ||
# ----------------------------------------------------------------------------- | ||
|
||
from qtconsole.qtconsoleapp import JupyterQtConsoleApp | ||
import pytest | ||
|
||
|
||
SHELL_TIMEOUT = 20000 | ||
|
||
|
||
@pytest.fixture | ||
def qtconsole(qtbot): | ||
"""Qtconsole fixture.""" | ||
# Create a console with the ipdb kernel | ||
console = JupyterQtConsoleApp() | ||
console.initialize(argv=['--kernel', 'ipdb_kernel']) | ||
|
||
qtbot.addWidget(console.window) | ||
console.window.confirm_exit = False | ||
console.window.show() | ||
return console | ||
|
||
|
||
def test_matplotlib_inline(qtconsole, qtbot): | ||
"""Test that %matplotlib inline is working.""" | ||
window = qtconsole.window | ||
shell = window.active_frontend | ||
|
||
# Wait until the console is fully up | ||
qtbot.waitUntil(lambda: shell._prompt_html is not None, | ||
timeout=SHELL_TIMEOUT) | ||
|
||
# Set inline backend | ||
with qtbot.waitSignal(shell.executed): | ||
shell.execute("%matplotlib inline") | ||
|
||
# Make a plot | ||
with qtbot.waitSignal(shell.executed): | ||
shell.execute("import matplotlib.pyplot as plt; plt.plot(range(10))") | ||
|
||
# Assert that there's a plot in the console | ||
assert shell._control.toHtml().count('img src') == 1 | ||
|
||
|
||
def test_matplotlib_qt(qtconsole, qtbot): | ||
"""Test that %matplotlib qt is working.""" | ||
window = qtconsole.window | ||
shell = window.active_frontend | ||
|
||
# Wait until the console is fully up | ||
qtbot.waitUntil(lambda: shell._prompt_html is not None, | ||
timeout=SHELL_TIMEOUT) | ||
|
||
# Set qt backend | ||
with qtbot.waitSignal(shell.executed): | ||
shell.execute("%matplotlib qt") | ||
|
||
# Make a plot | ||
with qtbot.waitSignal(shell.executed): | ||
shell.execute("import matplotlib.pyplot as plt; plt.plot(range(10))") | ||
|
||
# Assert we have three prompts in the console, meaning that the | ||
# previous plot command was non-blocking | ||
assert '3' in shell._prompt_html | ||
|
||
# Running QApplication.instance() should return a QApplication | ||
# object because "%matplotlib qt" creates one | ||
with qtbot.waitSignal(shell.executed): | ||
shell.execute("from PyQt5.QtWidgets import QApplication; QApplication.instance()") | ||
|
||
# Assert the previous command returns the object | ||
assert 'PyQt5.QtWidgets.QApplication object' in shell._control.toPlainText() | ||
|
||
|
||
if __name__ == "__main__": | ||
pytest.main() |