7
$\begingroup$

How can I capture output from Print from a function which does not leave the printed object as its final output, (and which I do not wish to edit)? E.g.

Module[{},
 Print[Plot[Sin[x], {x, 0, 2 Pi}]];
 a = 123]

I would like to use something like a temporary setting for $PrePrint or $Post, rather than use cell selection (SelectionMove, NotebookRead).

The aim is somehow to intercept the Print output -- the plot object -- and set it to a variable, (without altering the module).

This attempt did not work:-

enter image description here

$\endgroup$
8
  • $\begingroup$ I probably don't understand the problem but doesn't Print[Sow@Plot[Sin[x], {x, 0, 2 Pi}]] and // Reap at the end captures Print output? $\endgroup$
    – BoLe
    Commented Apr 3, 2013 at 11:00
  • $\begingroup$ Do you want the 123 being stored, the plot, or both? $\endgroup$ Commented Apr 3, 2013 at 11:14
  • $\begingroup$ I just want to pick up the plot object. The problem is the module should not be edited, otherwise it would be simple to set a variable inside the Print command. $\endgroup$ Commented Apr 3, 2013 at 12:11
  • $\begingroup$ So you want something like $PrePrint or $Post which would also capture the output of Plot[Sin[x],{x,-5,5}];? $\endgroup$
    – acl
    Commented Apr 3, 2013 at 12:32
  • $\begingroup$ @acl - Yes, as I have done below using $Output. But setting a variable with $PrePrint could be neater. $\endgroup$ Commented Apr 3, 2013 at 12:56

2 Answers 2

6
$\begingroup$

You can temporarily redefine Print, like so:

fun[] := Module[{}, Print[Plot[Sin[x], {x, 0, 2 Pi}]];
  a = 123]

list = {};
Block[{Print = AppendTo[list, {##}] &}, fun[]]

Now list contains everything that was printed. (Of course in a practical application you'd probably want to do something smarter than an inefficient periodic AppendTo)

If you still want to print the expressions while simultaneously saving them, use the Villegas-Gayley trick to redefine Print.

$\endgroup$
9
$\begingroup$

I have found one solution, using a temporary file:-

streams = AppendTo[$Output, OpenWrite[]];

Module[{},
  Print[Plot[Sin[x], {x, 0, 2 Pi}]];
  a = 123];

Close@Last@streams;
$Output = Most@streams;
printoutput = ReadList@First@Last@streams

enter image description here

$\endgroup$
3
  • $\begingroup$ This is great! Anyway to modify it so that the printed text is not outputted at all, but still captured to printoutput? $\endgroup$
    – Kvothe
    Commented Jun 16, 2021 at 15:50
  • $\begingroup$ @Kvothe Yes, use Block as per Szabolcs' answer. (Writes to list.) $\endgroup$ Commented Jun 16, 2021 at 16:48
  • $\begingroup$ Thanks. I wrongly assumed that the Block method would not work for my case since the printed output is printed in python during ExternalEvaluate. Upon testing it does actually work so apparently these statements still get printed in Mathematica by internally using Print. $\endgroup$
    – Kvothe
    Commented Jun 17, 2021 at 7:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.