ParaMonte MATLAB 3.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
isolate_axes.m
Go to the documentation of this file.
1function fh = isolate_axes(ah, vis)
2%ISOLATE_AXES Isolate the specified axes in a figure on their own
3%
4% Examples:
5% fh = isolate_axes(ah)
6% fh = isolate_axes(ah, vis)
7%
8% This function will create a new figure containing the axes/uipanels
9% specified, and also their associated legends and colorbars. The objects
10% specified must all be in the same figure, but they will generally only be
11% a subset of the objects in the figure.
12%
13% IN:
14% ah - An array of axes and uipanel handles, which must come from the
15% same figure.
16% vis - A boolean indicating whether the new figure should be visible.
17% Default: false.
18%
19% OUT:
20% fh - The handle of the created figure.
21
22% Copyright (C) Oliver Woodford 2011-2014, Yair Altman 2015-
23%{
24% Thank you to Rosella Blatt for reporting a bug to do with axes in GUIs
25% 16/03/12: Moved copyfig to its own function. Thanks to Bob Fratantonio
26% for pointing out that the function is also used in export_fig.m
27% 12/12/12: Add support for isolating uipanels. Thanks to michael for suggesting it
28% 08/10/13: Bug fix to allchildren suggested by Will Grant (many thanks!)
29% 05/12/13: Bug fix to axes having different units. Thanks to Remington Reid for reporting
30% 21/04/15: Bug fix for exporting uipanels with legend/colorbar on HG1 (reported by Alvaro
31% on FEX page as a comment on 24-Apr-2014); standardized indentation & help section
32% 22/04/15: Bug fix: legends and colorbars were not exported when exporting axes handle in HG2
33% 02/02/21: Fix axes, figure size to preserve input axes image resolution (thanks @Optecks)
34% 25/10/21: Bug fix: subplots were not isolated properly leading to print error (issue #347)
35% 24/03/23: Remove any non-legendable objects from the legend (workaround for copyobj bug)
36%}
37
38 % Make sure we have an array of handles
39 if ~all(ishandle(ah))
40 error('ah must be an array of handles');
41 end
42
43 % Check that the handles are all for axes or uipanels, and are all in the same figure
44 fh = ancestor(ah(1), 'figure');
45 nAx = numel(ah);
46 for a = 1:nAx
47 if ~ismember(get(ah(a), 'Type'), {'axes', 'uipanel'})
48 error('All handles must be axes or uipanel handles.');
49 end
50 if ~isequal(ancestor(ah(a), 'figure'), fh)
51 error('Axes must all come from the same figure.');
52 end
53 end
54
55 % Tag the objects so we can find them in the copy
56 old_tag = get(ah, 'Tag');
57 if nAx == 1
58 old_tag = {old_tag};
59 end
60 set(ah, 'Tag', 'ObjectToCopy');
61
62 % Mark all non-legendable objects in the original figure (if any legend shown)
63 % a workaround to the copyobj bug of not copying the ApplicationData property
64 lh = findall(fh, 'Tag','legend');
65 if ~isempty(lh)
66 ax = arrayfun(@(h) get(h,'Axes'), lh);
67 c = findall(ax);
68 hb = ~arrayfun(@(h)hasbehavior(h,'legend'), c);
69 c = c(hb);
70 oldTags = get(c,'Tag');
71 set(c,'Tag','non-legendable!')
72 end
73
74 % Create a new figure exactly the same as the old one
75 fh = copyfig(fh); %copyobj(fh, 0);
76
77 % Fix Axes & Figure size for image catpuring to have almost exact resolution
78 % of the Input Axes (thanks @Optecks)
79 allaxes = findall(fh, 'type', 'axes');
80 if ~isempty(ah)
81 sz = get(ah(1), 'OuterPosition');
82 un = get(ah(1), 'Units');
83 set(allaxes(1), 'Units',un, 'OuterPosition', [0 0 sz(3) sz(4)]);
84 set(allaxes(1), 'Units','pixels');
85 sz = get(allaxes(1), 'OuterPosition');
86 set(fh, 'Units','pixels', 'Position',[0 0 sz(3) sz(4)]+1);
87 end
88
89 if nargin < 2 || ~vis
90 set(fh, 'Visible', 'off');
91 end
92
93 % Restore the axes tags in the original figure back to their original values
94 for a = 1:nAx
95 set(ah(a), 'Tag', old_tag{a});
96 end
97
98 % Find the objects to save
99 ah = findall(fh, 'Tag', 'ObjectToCopy');
100 if numel(ah) ~= nAx
101 close(fh);
102 error('Incorrect number of objects found.');
103 end
104
105 % Set the axes tags in the new figure to what they should be
106 for a = 1:nAx
107 set(ah(a), 'Tag', old_tag{a});
108 end
109
110 % Keep any legends and colorbars which overlap the subplots
111 % Note: in HG1 these are axes objects; in HG2 they are separate objects, therefore we
112 % don't test for the type, only the tag (hopefully nobody but Matlab uses them!)
113 lh = findall(fh, 'Tag','legend', '-or', 'Tag','Colorbar');
114 nLeg = numel(lh);
115 if nLeg > 0
116 % Remove any non-legendable objects from the legend (if previously set)
117 c2 = findall(ah,'Tag','non-legendable!');
118 if ~isempty(c2)
119 arrayfun(@(h)hasbehavior(h,'legend',false), c2);
120 arrayfun(@(h,t)set(h,'Tag',t{1}),c,oldTags); %restore object tags to orig values
121 end
122
123 set([ah(:); lh(:)], 'Units', 'normalized');
124 try
125 ax_pos = get(ah, 'OuterPosition'); % axes and figures have the OuterPosition property
126 catch
127 ax_pos = get(ah, 'Position'); % uipanels only have Position, not OuterPosition
128 end
129 if nAx > 1
130 ax_pos = cell2mat(ax_pos(:));
131 end
132 ax_pos(:,3:4) = ax_pos(:,3:4) + ax_pos(:,1:2);
133 try
134 leg_pos = get(lh, 'OuterPosition');
135 catch
136 leg_pos = get(lh, 'Position'); % No OuterPosition in HG2, only in HG1
137 end
138 if nLeg > 1
139 leg_pos = cell2mat(leg_pos);
140 end
141 leg_pos(:,3:4) = leg_pos(:,3:4) + leg_pos(:,1:2);
142 ax_pos = shiftdim(ax_pos, -1);
143 % Overlap test
144 M = bsxfun(@lt, leg_pos(:,1), ax_pos(:,:,3)) & ...
145 bsxfun(@lt, leg_pos(:,2), ax_pos(:,:,4)) & ...
146 bsxfun(@gt, leg_pos(:,3), ax_pos(:,:,1)) & ...
147 bsxfun(@gt, leg_pos(:,4), ax_pos(:,:,2));
148 ah = [ah; lh(any(M, 2))];
149 end
150
151 % Get all the objects in the figure
152 axs = findall(fh);
153
154 % Delete everything except for the input objects and associated items
155 delete(axs(~ismember(axs, [ah; allchildren(ah); allancestors(ah)])));
156end
157
158function ah = allchildren(ah)
159 ah = findall(ah);
160 if iscell(ah)
161 ah = cell2mat(ah);
162 end
163 ah = ah(:);
164end
165
166function ph = allancestors(ah)
167 ph = [];
168 for a = 1:numel(ah)
169 h = get(ah(a), 'parent');
170 while h ~= 0
171 ph = [ph; h]; %#ok<AGROW>
172 h = get(h, 'parent');
173 end
174 end
175end
This is the class for generating instances of objects that contain the specifications of various type...
Definition: Axes.m:622
This is the abstract class for generating instances of objects that contain the specifications of var...
Definition: Figure.m:27
function copy(in from, in to, in fields)
Copy the contents of the struct/object from to the struct/object to recursively and without destroyin...
function copyfig(in fh)
function find(in vendor)
Return a list of scalar MATLAB strings containing the paths to all detected mpiexec binaries installe...
function allancestors(in ah)
function isolate_axes(in ah, in vis)
function allchildren(in ah)
function which(in vendor)
Return the a MATLAB string containing the path to the first mpiexec executable binary found in system...