Inset in ArrayPlot
This does seem to be a bug because it doesn't happen in other related functions, such as ReliefPlot
.
Here is a way to emulate the desired behavior with ReliefPlot
:
ReliefPlot[CellularAutomaton[30, {{1}, 0}, 10],
LightingAngle -> None,
ColorFunction -> Function[Blend[{White, Black}, #]],
DataReversed -> True,
Epilog -> Inset[Plot[Sin[x], {x, -10, 10}, Frame -> True]]]
When you compare the output expression of your two examples, you see that the Graphics
object that is inset into the ArrayPlot
is stripped off the Frame
option. Knowing this, there are several ways to prevent this.
A very easy and not hacked solution is to evaluate the ArrayPlot
and insert the Epilog
in the final Graphics
:
Append[
ArrayPlot[CellularAutomaton[30, {{1}, 0}, 10]],
Epilog -> Inset[Plot[Sin[x], {x, -10, 10}, Frame -> True]]
]
This is interesting and peculiar. Spelunking this example lead my discovery of the function:
Needs["GeneralUtilities`"]
Graphics`ArrayPlotDump`Private`stripOptions // PrintDefinitions
Graphics`ArrayPlotDump`Private`stripOptions[opt2___, discard_List] := Module[{opt = Flatten[{opt2}]}, ((opt = Graphics`ArrayPlotDump`Private`stripOptions[opt, #1]) &) /@ discard; opt]; Graphics`ArrayPlotDump`Private`stripOptions[opt2___, OP_] := Module[{opt = opt2}, Delete[opt, Position[opt, g_?(System`Utilities`StringName[#1] === System`Utilities`StringName[OP] &) -> _]]];
So there exists a function specifically for discarding unwanted options within an expression.
It is used by ArrayPlot
expressly for Frame
:
tr = Trace @ ArrayPlot[{Range@5}, Epilog -> Inset["foo"]];
Cases[tr, x : HoldPattern[Graphics`ArrayPlotDump`Private`stripOptions[_, Frame]] :>
HoldForm[x], -1, 1]
{Graphics`ArrayPlotDump`Private`stripOptions[ Graphics`ArrayPlotDump`Private`opt$7350, Frame]}
Graphics`ArrayPlotDump`Private`opt$xxx
contains our Inset
:
{Epilog -> Inset["foo"], GridLinesStyle -> Directive[GrayLevel[0.5, 0.4]]}
I believe that stripOptions
should not have been written to operate at all levels of the expression. It could instead have been written to operate at only levelspec {1}
if first the option list were flattened.
Here is a patch to effect this:
Graphics`ArrayPlotDump`Private`stripOptions[opt2___, OP_] :=
Module[{opt = Flatten @ {opt2}},
Delete[opt,
Position[opt,
g_?(System`Utilities`StringName[#1] ===
System`Utilities`StringName[OP] &) -> _,
{1}
]
]
];
Now:
ArrayPlot[
CellularAutomaton[30, {{1}, 0}, 10],
Epilog -> Inset[Plot[Sin[x], {x, -10, 10}, Frame -> True]]
]
Please let me know if you discover any failures induced by this patch.