MATLAB: How to re-open a closed figure from a stored plot handle

graphicshandlessurface

Hi, I'm working on a script where I calculate some variables and generate surface plots and save those plots in an array. Something like:
x = linspace(0,10); y = x;
[X,Y] = meshgrid(x,y);
for k = 1:10
Z = X+Y.^k;
surface_plot = surf(X,Y,Z);
plot_data(k) = copy(surface_plot);
end
close all
Later on, to better organize my plots as subplots in custom windows I plot them again using the information in the plot_data array.
for k = 1:10
new_plot = plot_data(k)
surf(new_plot.XData, new_plot.YData, new_plot.ZData)
end
This however means that I am generating surface plots twice, which probably affects performance. Is there any way to re-open the closed figures from a stored handles in plot_data?

Best Answer

No. All the plot_data array contains is the handles to the chart surface objects that were created by surf.
However, even though the array contains in the sample code 10 elements, at the end of the for...end loop only the last one is still pointing to an active/existing surface object; the first nine (9) have been implicitly deleted because the state of the 'NextPlot' property of the axes is set to 'Replace' by default and | surf| is a high-level routine that then deletes the existing content of the axes and replaces it with the new surface object. The close all statement then deleted the remaining figure itself so at that point all you have is an array of deleted and no longer valid surface objects.
>> figure
>> x = linspace(0,10); y = x;
[X,Y] = meshgrid(x,y);
for k = 1:3 % illustrates problem just as well as 10
Z = X+Y.^k;
plot_data(k) = surf(X,Y,Z);
end
>>
% stop before close all statement to look at what have...
whos plot_data
Name Size Bytes Class Attributes
plot_data 1x3 8 matlab.graphics.chart.primitive.Surface
>> plot_data(1)
ans =
handle to deleted Surface
>> plot_data(2)
ans =
handle to deleted Surface
>> plot_data(end)
ans =
Surface with properties:
EdgeColor: [0 0 0]
LineStyle: '-'
FaceColor: 'flat'
FaceLighting: 'flat'
FaceAlpha: 1.00
XData: [100×100 double]
YData: [100×100 double]
ZData: [100×100 double]
CData: [100×100 double]
Show all properties
>>
NB: Above; both array elements besides the last are already deleted and invalid handles at the end of the loop; you've nothing left except it; there was no real point in running the loop at all other than the last index value.
>> close all % now close the figure (and all others as well, by the way)
>> plot_data(end)
ans =
handle to deleted Surface
>> new_plot=plot_data(1)
new_plot =
handle to deleted Surface
>> new_plot.XData
Invalid or deleted object.
>>
And now you have no handles left pointing to anything that is still extant so there was no point in running the loop at all this way.
If there is going to be need to show those figures again, but not have them visible for a while, set the 'Visible' property of the figure to 'Off', but do not close the figure and you'll need to set
hold on
in order to preserve all surface objects. This is, of course, going to make for a very messy axes with all these surfaces on one axis at the same time, although you would still be able to refer to each one of them independently with the saved handle and put them on another axes of your choosing.
You may be looking for copyobj instead rather than replotting, however.