In a custom Mathematica frontend based on MathLink I try to make use of plots produced in Notebooks. The idea is to write them to files whenever they get produced.
According to C-code snippets I found online the following should store all plots in postscript cells in a Mathematica file "picture_book" if $Display = "stdout"
is executed in the beginning:
case DISPLAYPKT:
if(MLGetString(link, &output_string)){
if(first_PS_piece){
first_PS_piece = FALSE;
if(picture_book){
fprintf(picture_book, "%s", ps_cellheader);
}
}
if(picture_book){
fprintf(picture_book, "%s", output_string);
}
MLDisownString(link, output_string);
}
break;
case DISPLAYENDPKT:
if(MLGetString(link, &output_string)){
if(picture_book){
fprintf(picture_book, "%s", output_string);
}
MLDisownString(link, output_string);
}
first_PS_piece = TRUE;
break;
However, when I run $Display = "stdout"
at first, I get the error message
Graphics::opset: Option DefaultAxesStyle is not set in Options[Graphics].
twice, each time I try Plot
. Trying to set DefaultAxesStyle
did not work.
The code above appears in the loop which handles the output after running Mathematica commands with MathLink. I verified that it retrieves other output packets (not shown), but DISPLAYPKT
packages are never received.
This code might be outdated and so I wonder if I need to do anything else in order to obtain proper output packets. Note that I am on Linux.
A different (disfavored) approach would be to use the Export["plot.eps",plot]
function in order to export each plot to a separate file. How would I achieve this with minimal impact on existing Notebooks? I.e. can I redefine the Plot
command such that each is automatically exported to a separate file with automatic naming?
Edit
After some changes my frontend receives textual Output of the following kind when I call Plot
or similar (abreviated example output)
Graphics[{{{}, {}, {Hue[0.67, 0.6, 0.6], Line}}}, {AspectRatio -> GoldenRatio^(-1), Axes -> True, AxesLabel -> {None, None}, AxesOrigin -> {1., 0.05}, Method -> {}, PlotRange -> {{1, 3}, {0.04978707039998921, 0.3678794261559552}}, PlotRangeClipping -> True, PlotRangePadding -> {Scaled[0.02], Scaled[0.02]}}]
If I execute these outputs manually inside a Notebook in the default frontend it seems to produce the plots. Is it a consistent approach to detect this Graphics[]
output and to write it to a file (which kind of file) and then execute that file manually (or later automatically) in the Mathematica interface to produce visual plots? Or could this output be missing some information or be more general for different plot commands?
Edit 2
Motivated by the answers and comments below and the Mathematica documentation I tried the command:
Off[FrontEndObject::notavail]; Get["Version5`Graphics`"]; Plot[Sin[t], {t, 0, Pi}]
Together with custom Format
definitions for Graphics
(and similar) this would re-enable the 'old fashioned' way of retrieving display output described above. However I do not completely understand how to deal with the abbreviate postscript output (shown below in shortened form). Obviously postscript is missing some definitions to render it. How do I convert this to a complete consistent postscript file?
%!
%%Creator: Mathematica
%%AspectRatio: .61803
MathPictureStart
/Mabs {
Mgmatrix idtransform
Mtmatrix dtransform
} bind def
/Mabsadd { Mabs
3 -1 roll add
3 1 roll add
exch } bind def
%% Graphics
%%IncludeResource: font Courier
%%IncludeFont: Courier
/Courier findfont 10 scalefont setfont
% Scaling calculations
0 0.31831 0 0.618034 [
[.15915 -0.0125 -9 -9 ]
Mfstroke
% End of Graphics
MathPictureEnd
:[font = postscript; PostScript; formatAsPostScript; output; inactive; pictureLeft = 100; pictureWidth = 300; pictureHeight = 300;]
It is probably not feasible without the official front end, is it?
Edit 3
Following advice given below in comments I tried the following definitions to print all plots to files. Is this consistent or is there a better way to do it? (First I had tried to redefine Graphics
and Graphics3D
directly, because it seems more elegant to me. However this resulted in recursions or it would have no effect whatsoever.)
useMyGraphics[vars__] :=
Block[{Graphics = myGraphics, Graphics3D = myGraphics3D}, vars]
Format[myGraphics[vars__]] :=
Export["picture.png", Graphics[vars], ImageResolution -> 300]
Format[myGraphics3D[vars__]] :=
Export["picture3D.png", Graphics3D[vars], ImageResolution -> 300]
Protect[myGraphics];
Protect[myGraphics3D];
Protect[useMyGraphics];
$Pre = useMyGraphics