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]]]

array sim


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]]
]

enter image description here

Please let me know if you discover any failures induced by this patch.