How do you capture the cell output in jupyter notebook while simultaneously showing the results? I do not want to wait for everything to finish and then running a variable.show().
-
Yeah I also need to both save the results in a variable and see the results as its printedJobHunter69– JobHunter692021-05-14 06:01:19 +00:00Commented May 14, 2021 at 6:01
-
Does this answer your question? Jupyter notebook show and capture output at the same timeMr Tsjolder from codidact– Mr Tsjolder from codidact2023-04-05 09:42:13 +00:00Commented Apr 5, 2023 at 9:42
2 Answers
I adapted the following custom cell magic from the implementation of the built-in %%capture:
from io import StringIO
import sys
from IPython.core import magic_arguments
from IPython.core.magic import Magics, cell_magic, magics_class
from IPython.utils.capture import CapturedIO
class Tee(StringIO):
def __init__(self, initial_value='', newline='\n', stream=None):
self.stream = stream
super().__init__(initial_value, newline)
def write(self, data):
if self.stream is not None:
self.stream.write(data)
super().write(data)
class capture_and_print_output(object):
stdout = True
stderr = True
display = True
def __init__(self, stdout=True, stderr=True, display=True):
self.stdout = stdout
self.stderr = stderr
self.display = display
self.shell = None
def __enter__(self):
from IPython.core.getipython import get_ipython
from IPython.core.displaypub import CapturingDisplayPublisher
from IPython.core.displayhook import CapturingDisplayHook
self.sys_stdout = sys.stdout
self.sys_stderr = sys.stderr
if self.display:
self.shell = get_ipython()
if self.shell is None:
self.save_display_pub = None
self.display = False
stdout = stderr = outputs = None
if self.stdout:
stdout = sys.stdout = Tee(stream=sys.stdout)
if self.stderr:
stderr = sys.stderr = Tee(stream=sys.stderr)
if self.display:
self.save_display_pub = self.shell.display_pub
self.shell.display_pub = CapturingDisplayPublisher()
outputs = self.shell.display_pub.outputs
self.save_display_hook = sys.displayhook
sys.displayhook = CapturingDisplayHook(shell=self.shell,
outputs=outputs)
return CapturedIO(stdout, stderr, outputs)
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self.sys_stdout
sys.stderr = self.sys_stderr
if self.display and self.shell:
self.shell.display_pub = self.save_display_pub
sys.displayhook = self.save_display_hook
@magics_class
class CustomMagics(Magics):
@magic_arguments.magic_arguments()
@magic_arguments.argument('output', type=str, default='', nargs='?')
@magic_arguments.argument('--no-stderr', action='store_true')
@magic_arguments.argument('--no-stdout', action='store_true')
@magic_arguments.argument('--no-display', action='store_true')
@cell_magic
def tee(self, line, cell):
args = magic_arguments.parse_argstring(self.tee, line)
out = not args.no_stdout
err = not args.no_stderr
disp = not args.no_display
with capture_and_print_output(out, err, disp) as io:
self.shell.run_cell(cell)
if args.output:
self.shell.user_ns[args.output] = io
You need to register this cell magic, usually either in your startup profile or by defining it as an extension you load later, for example:
from IPython import get_ipython
get_ipython().register_magics(CustomMagics)
Now you can use it as follows:
>>> %%tee output
print(42)
42
>>> output.show()
42
One thing to note: it will capture rich outputs as the original %%capture does, but it won't print them in the original cell. If that's important, you may find some way to adapt the above to include rich outputs, perhaps by subclassing CapturingDisplayPublisher/Hook.
2 Comments
This one works perfectly for me :
Jupyter notebook show and capture output at the same time
It will show the output while simultaneously capturing it, and one can show the captured output in the next cell.
