Let's say I define tick marks for a plot in a separate function outside of the plot:
tick[xmin_, xmax_] :=
Map[{#, "", .03} &, FindDivisions[{xmin, xmax}, 4]];
p = Plot[Sin[x], {x, -Pi, Pi}, Frame -> True,
FrameTicks -> {{tick, tick}, {tick, tick}}];
q = Plot[Sin[x], {x, -Pi, Pi}, Axes -> True,
Ticks -> {tick, tick}];
Now these boring plots can be made much more colorful by evaluating this additional command:
Clear[tick]
The result of evaluating p
(and similarly q
) is now:
I didn't say it's colorful in a good way.
This is a problem especially if you have defined your tick function in the initialization of the notebook via SetOptions[Plot,...]
, and then at a later stage decide to copy and paste the Graphics
output by one of these plots to another notebook where this initialization is not performed. Assuming that the Graphics
is a self-contained drawing that can be copied in this way leads to an unpleasant surprise: although you can paste the graphic, you'll get an error when you paste it into a Show[...]
expression and evaluate it:
So what to do about this? Of course, I could always embed all the tick functions in the plot itself, as in
q = Plot[Sin[x], {x, -Pi, Pi}, Axes -> True,
Ticks -> ({#, #} &[
Function[{xmin, xmax},
Map[{#, "", .03} &, FindDivisions[{xmin, xmax}, 4]]]])];
But this seems very cumbersome.
Alternatively, one could convert to PDF
and back to Graphics
using First@ImportString[ExportString[q,"PDF"],"PDF"]
. But that's a big gun for a very specialized problem.
Another possibility is to hit the plot output with FullGraphics
. However, that's buggy. For example,
FullGraphics[Plot[x^2, {x, -1, 1}, TicksStyle -> RGBColor[1, 0, 0]]]
can't seem to reproduce the red color for the tick marks (confirmed by Wolfram as a bug).
So are there any better ways to "burn in" the externally defined tick functions in the above examples so that the plot results can be considered self-contained? I guess I'm thinking of something like SaveDefinitions->True
for plots. Come to think of it, maybe putting the plot in a Manipulate
is another option... but ideally, I'd like to have a Graphics
object. So at the time of generating the plot, one should force Mathematica to store the table of actually generated ticks in the graphic. Actually, something like this already happens in the notebook when I copy and paste a graphic (some data corresponding to the currently displayed graphic are cached). It would be nice if the tick function itself could take care of replacing itself with an explicit tick list.
Edit
The first screenshot is fixed by Rojo's answer, and that part of the question is really not caused by a bug in Mathematica. It's the special status of tick marks that requires the tick function to be available whenever we decide to show the plot output with a different plot range (using Show
, e.g.).
The second screen shot above is caused by a bug (also suggested by Heike's observation), and therefore I can't expect anyone to give a good answer here (except for work-arounds). To show the bug more clearly: I still get an error even with this simple (apparently self-contained) definition:
q1 = Plot[Sin[x], {x, -Pi, Pi}, Axes -> True,
Ticks -> {Function[{xmin, xmax},
Map[{#, "", .03} &, Evaluate@FindDivisions[{xmin, xmax}, 4]]],
Automatic}]
Here is the result of pasting the output from above into a Show[ ]
statement:
However, this is "fixed" by changing FindDivisions[{xmin, xmax}, 4]
to FindDivisions[{xmin, xmax}, Round[4]]
FullGraphics
is far too inconsistent and buggy for general use. $\endgroup$AbsoluteOptions
give an error onp
. $\endgroup$