Can I print output to another cell in a jupyter notebook?

Question:

Let’s assume there is a jupyter notebook that has two cells. In the second cell, we generate some output, e.g. by running print('foo'). Is there a way to change that print command in such a way that the output will be displayed as output of the first cell?

Why? In a typical data analysis workflow, I access several data sources somewhere in the notebook. It would be nice if I could extend my access_data method in such a way that all sources that I have used are listed in the first cell.

Asked By: Arco Bast

||

Answers:

First example:

# cell 1
from IPython.display import display
import random as rd
import pandas as pd
import numpy as np
import matplotlib.pylab as plt

# cell 2
h = display(display_id='my-display')

# cell 3
h.display(None)
# ==> output is updated at each h.update() command in cells below

# cell 4
s = ''.join(rd.choices('abcedfghijklmn', k=5))
h.update(s)

# cell 5
a, b, c, d = rd.choices(range(10), k=4)
arr = np.array([[a,b,c,d], [d,c,b,a]])
h.update(arr)

# cell 6
a, b, c, d = rd.choices(range(10), k=4)
df = pd.DataFrame(data=[[a,b],[c,d]], columns=['A', 'B'])
h.update(df)

# cell 7
a, b, c, d = rd.choices(range(10), k=4)
df = pd.DataFrame(data=[[a,b],[c,d]], columns=['a', 'b'])
ax = df.plot();
fig = ax.get_figure()
h.update(fig)
plt.close()

# cell 8
fig, ax = plt.subplots()
a,b,c,d = rd.choices(range(10), k=4)
ax.plot([a,b,c,d]);
h.update(fig)
plt.close()

Second example with helper class and some mime types management:

# cell 1
from IPython.display import display

import random as rd
import numpy as np
import pandas as pd
import matplotlib.pylab as plt

# cell 2
class Output:
    """
    Helper class
    """
    def __init__(self, name='my-display'):
        self.h = display(display_id=name)
        self.content = ''
        self.mime_type = None
        self.dic_kind = {
            'text': 'text/plain',
            'markdown': 'text/markdown',
            'html': 'text/html',
        }

    def display(self):
        self.h.display({'text/plain': ''}, raw=True)

    def _build_obj(self, content, kind, append, new_line):
        self.mime_type = self.dic_kind.get(kind)
        if not self.mime_type:
            return content, False
        if append:
            sep = 'n' if new_line else ''
            self.content = self.content + sep + content
        else:
            self.content = content
        return {self.mime_type: self.content}, True

    def update(self, content, kind=None, append=False, new_line=True):
        obj, raw = self._build_obj(content, kind, append, new_line)
        self.h.update(obj, raw=raw)


# cell 3
out = Output(name='my-display-2')
out.display()
# ==> output is updated at each h.update() command in cells below

# cell 4
s = ''.join(rd.choices('abcedfghijklmn', k=5))
out.update(s, kind='text', append=False)

# cell 5
a, b = rd.choices(range(10), k=2)
s = f'''
# Heading one {a}

This is a sample  {b}

* a
* list
'''
out.update(s, kind='markdown', append=True)

# cell 6
a, b = rd.choices(range(10), k=2)
s = f'''
<h3>My Title {a}</h3>
<p>My paragraph {b}</p>
'''
out.update(s, kind='html')

# cell 7
a, b, c, d = rd.choices(range(10), k=4)
arr = np.array([[a,b,c,d], [d,c,b,a]])
out.update(arr)

# cell 8
a, b, c, d = rd.choices(range(10), k=4)
df = pd.DataFrame(data=[[a,b],[c,d]], columns=['A', 'B'])
out.update(df)

# cell 9
a, b, c, d = rd.choices(range(10), k=4)
df = pd.DataFrame(data=[[a,b],[c,d]], columns=['a', 'b'])
ax = df.plot();
fig = ax.get_figure()
out.update(fig)
plt.close()

# cell 10
fig, ax = plt.subplots()
a,b,c,d = rd.choices(range(10), k=4)
ax.plot([a,b,c,d]);
out.update(fig)
plt.close()
Answered By: Oscar6E

Yes. Using %%capture var magic

+Info on https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-capture

enter image description here

%%capture captured
# First cell
x="""Let's assume there is a jupyter notebook that has two cells. In the second cell, we generate some output, e.g. by running print('foo'). Is there a way to change that print command in such a way that the output will be displayed as output of the first cell?"""
print(x)
y=[1,2]*3
print(y)
a=list(range(10))
print(a)
m=f'There are lots of ways: {a}'
m


# second cell
print(captured)

Note: m Is not captured as it wasn’t ‘output’. (I added it intentionally)

Tested on JupyterLab / Jupyter Notebook with Python 3.7

Answered By: Rub
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.