While daren shan's answer is correct, it's bizarre enough behavior that I was curious to see what is behind it.
Stepping through the source of plotmatrix
we can find the line that deletes our slider object:
% Create/find BigAx and make it invisible
BigAx = newplot(cax);
Nothing obvious here, what does newplot
do?
Use newplot
at the beginning of high-level graphics code to determine
which figure and axes to target for graphics output. Calling newplot
can change the current figure and current axes. Basically, there are
three options when you are drawing graphics in existing figures and
axes:
Add the new graphics without changing any properties or deleting any objects.
Delete all existing objects whose handles are not hidden before drawing the new objects.
Delete all existing objects regardless of whether or not their handles are hidden, and reset most properties to their defaults before
drawing the new objects (refer to the following table for specific
information).
Oh...
So newplot
is deleting the slider object.
So why does hold
prevent the slider from being deleted, despite it being an axis method and not a figure method? To start, take a look at the "Algorithms" topic in the documentation:
The hold
function sets the NextPlot
property of the Axes
or PolarAxes
object to either 'add'
or 'replace'
.
So hold on
sets this to 'add'
for the current axes. However, for a reason I can't currently figure out, this also sets the NextPlot
of the figure to add
as well.
We can see this with a short snippet:
f = figure('NextPlot', 'replacechildren');
ax = axes;
fprintf('NextPlot Status, base:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)
hold on
fprintf('NextPlot Status, hold on:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)
Which prints:
NextPlot Status, base:
Fig: replacechildren, Ax(1): replace
NextPlot Status, hold on:
Fig: add, Ax(1): add
Weird behavior, but I won't dwell on that.
Why does this matter? Go back to the newplot
documentation. First, newplot
reads the figure's NextPlot
property to determine what to do. By default, a figure's NextPlot
property is set to 'add'
, so it would retain all of the present graphics objects but plotmatrix
explicitly changes this:
if ~hold_state
set(fig,'NextPlot','replacechildren')
end
So newplot
goes from:
Draw to the current figure without clearing any graphics objects already present.
To:
Remove all child objects whose HandleVisibility
property is set to on
and reset figure NextPlot
property to add
.
This clears the current figure and is equivalent to issuing the clf
command.
Which explains why the slider disappears and why hold on
fixes the problem.
Per the documentation for newplot
we can also set the HandleVisibility
of the slider UIcontrol to save it from being destroyed:
% create slider
uicontrol('Parent',f,...
'Style','slider','Callback',{@sliderCallback,AX_main},...
'Units','normalized','Position',[0.05 0.05 0.9 0.05], ...
'HandleVisibility', 'off');