2

I am writing a custom client (a web-based graph representation of an IPython Notebook) for an IPython application and the easiest way to manage IPython programmatically seems to be using the IPython.core.InteractiveShell instance.

Consider this example: when a Jupyter Notebook cell that uses rich output is executed with inline magic, Notebook shows the appropriate rich representation (a plotted image) of plt.show() inline:

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()

I want to be able to retrieve the image when using IPython programmatically via its API, namely InteractiveShell, like this:

from IPython.core.interactiveshell import InteractiveShell
shell = InteractiveShell()
result = shell.run_cell("...above code of the cell here...")
# result either gives an error when using %matplotlib inline or retrieves
# no useful info if no line magic is present

Problem is that InteractiveShell instance will not accept the %matplotlib inline magic, giving a NotImplementedError in its enable_gui method which is, wll, not implemented. I found very few information about this apart from a single issue on IPython's Github.

I know I can do this manually by using plt.save() but that doesn't seem right to me as I don't want to write manual interpretations each time I need another rich representation of the result. I feel like I'm missing a lot here in the way IPython works, so I'm asking for help in retrieving the results. What exactly does Jupyter Notebook do to retrieve the rich representation and perhaps can it be done painlessly via other means? I'm looking at using jupyter_client but for now that seems to be even more confusing.

UPDATE:

The io.capture_output context manager seems to be the way to go but I've been able to capture string outputs only (pretty much the same as using %%capture cell magic):

with io.capture_output() as captured:
    result = shell.run_cell(cell)
#captures strings only:

captured.stdout = {str} '<matplotlib.figure.Figure at 0x4f486d8>'
7
  • 1
    'Inline' plots are sent as a display data message to the frontend. So to use them, you need to have a frontend running a separate kernel process. This is what jupyter_client does. Have a look at nbconvert's ExecutePreprocessor to see how to use it. Commented May 10, 2016 at 16:44
  • Thank you! Your comment suggests using jupyter_client and this is probably the relevant part of ExecutePreprocessor: msg = self.kc.iopub_channel.get_msg(timeout=4). So this is essentially not possible with InteractiveShell? Commented May 11, 2016 at 8:34
  • Update: I found a io.capture_output context manager in the IPython API for handling IOpub channel and managed to capture output using it (see edit in the post), but strings only. Is it possible to do the job with this context manager and if yes, how? Could not find any examples. Commented May 11, 2016 at 10:03
  • 1
    When you use InteractiveShell, there is no iopub channel, so it can't be captured. Iopub and %matplotlib inline are specifically kernel features, so you have to run IPython as a Jupyter kernel to use them. Commented May 11, 2016 at 10:11
  • Thanks again for your answers. I seem to have found a temporary solution with InteractiveShell. capture_output() context manager does the trick and I can retrieve both text/plain and image/png data types from the result. I'm sure this omits a lot of more nuanced stuff with IPython's architecture but this will solve my issue for now. From what I can see inspecting Notebook source code, _handle_iopub_message that does rich display processing receives basically the same information as capture_output(). I will answer the question with this result. Commented May 12, 2016 at 18:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.