ParaMonte MATLAB 3.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
fitAxes.m
Go to the documentation of this file.
1%> \brief
2%> Alters the figure size corresponding to the input figure
3%> handle ``fig`` such that it has the minimum size necessary to
4%> enclose all axes in the figure without excess space around them.<br>
5%>
6%> \note
7%> This function expands the figure to completely encompass all axes if necessary.<br>
8%> If any 3D axes are present which have been zoomed, the procedure will produce an error,
9%> as these cannot easily be dealt with.<br>
10%>
11%> \param[in] fig : The input scalar MATLAB object representing the
12%> handle to the figure whose axes must be tightly fit.<br>
13%> (**optional**. If missing, the current figure will be used.)
14%>
15%> \interface{fitAxes}
16%> \code{.m}
17%>
18%> pm.vis.fitAxes()
19%> pm.vis.fitAxes([])
20%> pm.vis.fitAxes(fig)
21%>
22%> \endcode
23%>
24%> \final{fitAxes}
25%>
26%> This function build upon the work of,
27%> Richard Crozier (2024) [tightfig (hfig)](https://www.mathworks.com/matlabcentral/fileexchange/34055-tightfig-hfig),
28%> MATLAB Central File Exchange. Retrieved May 12, 2024.<br>
29%>
30%> \author
31%> \JoshuaOsborne, May 21 2024, 6:12 AM, University of Texas at Arlington<br>
32%> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
33%> \AmirShahmoradi, May 16 2016, 9:03 AM, Oden Institute for Computational Engineering and Sciences (ICES), UT Austin<br>
34function fitAxes(fig)
35
36 if nargin == 0
37 fig = [];
38 end
39 if isempty(fig)
40 fig = gcf;
41 end
42
43 %%%% There can be an issue with tightfig when the user has been modifying
44 %%%% the contents manually, the code below is an attempt to resolve this,
45 %%%% but it has not yet been satisfactorily fixed
46 %%%% origwindowstyle = get(fig, 'WindowStyle');
47
48 set(fig, 'WindowStyle', 'normal');
49
50 %%%% 1 point is 0.3528 mm for future use get all the axes handles
51 %%%% note this will also fetch legends and color bars as well.
52
53 hax = findall(fig, 'type', 'axes');
54
55 % TODO: fix for modern matlab, colorbars and legends are no longer axes.
56
57 hcbar = findall(fig, 'type', 'colorbar');
58 hleg = findall(fig, 'type', 'legend');
59
60 % get the original axes units, so we can change and reset these again later.
61
62 origaxunits = get(hax, 'Units');
63
64 % change the axes units to cm.
65
66 set(hax, 'Units', 'centimeters');
67
68 pos = [];
69 ti = [];
70
71 % get various position parameters of the axes.
72
73 if 1 < numel(hax)
74 % fsize = cell2mat(get(hax, 'FontSize'));
75 ti = cell2mat(get(hax,'TightInset'));
76 pos = [pos; cell2mat(get(hax, 'Position')) ];
77 else
78 % fsize = get(hax, 'FontSize');
79 ti = get(hax,'TightInset');
80 pos = [pos; get(hax, 'Position') ];
81 end
82
83 if ~isempty (hcbar)
84 set(hcbar, 'Units', 'centimeters');
85 % colorbars do not have tightinset property
86 for cbind = 1:numel(hcbar)
87 % fsize = cell2mat(get(hax, 'FontSize'));
88 [cbarpos, cbarti] = colorbarpos (hcbar);
89 pos = [pos; cbarpos];
90 ti = [ti; cbarti];
91 end
92 end
93
94 if ~isempty(hleg)
95
96 set(hleg, 'Units', 'centimeters');
97
98 % legends do not have tightinset property
99 if numel(hleg) > 1
100 % fsize = cell2mat(get(hax, 'FontSize'));
101 pos = [pos; cell2mat(get(hleg, 'Position')) ];
102 else
103 % fsize = get(hax, 'FontSize');
104 pos = [pos; get(hleg, 'Position') ];
105 end
106 ti = [ti; repmat([0,0,0,0], numel(hleg), 1); ];
107 end
108
109 % ensure very tiny border so outer box always appears.
110
111 ti(ti < 0.1) = 0.15;
112
113 % we will check if any 3d axes are zoomed, to do this we will
114 % check if they are not being viewed in any of the 2d directions.
115
116 views2d = [0,90; 0,0; 90,0];
117
118 for i = 1:numel(hax)
119
120 set(hax(i), 'LooseInset', ti(i,:));
121 % set(hax(i), 'LooseInset', [0,0,0,0]);
122
123 % get the current viewing angle of the axes
124 [az,el] = view(hax(i));
125
126 % determine if the axes are zoomed
127 iszoomed = strcmp(get(hax(i), 'CameraViewAngleMode'), 'manual');
128
129 % test if we are viewing in 2d mode or a 3d view
130 is2d = all(bsxfun(@eq, [az,el], views2d), 2);
131
132 if iszoomed && ~any(is2d)
133 error('fitAxes:haszoomed3d', 'Cannot make figures containing zoomed 3D axes tight.')
134 end
135
136 end
137
138 % we will move all the axes down and to the left by the amount
139 % necessary to just show the bottom and leftmost axes and labels etc.
140
141 moveleft = min(pos(:,1) - ti(:,1));
142 movedown = min(pos(:,2) - ti(:,2));
143
144 % we will also alter the height and width of the figure to
145 % just encompass the topmost and rightmost axes and labels.
146
147 figwidth = max(pos(:,1) + pos(:,3) + ti(:,3) - moveleft);
148 figheight = max(pos(:,2) + pos(:,4) + ti(:,4) - movedown);
149
150 % move all the axes.
151
152 for i = 1:numel(hax)
153 set(hax(i), 'Position', [pos(i,1:2) - [moveleft,movedown], pos(i,3:4)]);
154 end
155
156 for i = 1:numel(hcbar)
157 set(hcbar(i), 'Position', [pos(i+numel(hax),1:2) - [moveleft,movedown], pos(i+numel(hax),3:4)]);
158 end
159
160 for i = 1:numel(hleg)
161 set(hleg(i), 'Position', [pos(i+numel(hax)+numel(hcbar),1:2) - [moveleft,movedown], pos(i+numel(hax)+numel(hcbar),3:4)]);
162 end
163
164 origfigunits = get(fig, 'Units');
165 set(fig, 'Units', 'centimeters');
166
167 % change the size of the figure.
168
169 figpos = get(fig, 'Position');
170
171 set(fig, 'Position', [figpos(1), figpos(2), figwidth, figheight]);
172
173 % change the size of the paper.
174
175 set(fig, 'PaperUnits','centimeters');
176 set(fig, 'PaperSize', [figwidth, figheight]);
177 set(fig, 'PaperPositionMode', 'manual');
178 set(fig, 'PaperPosition',[0 0 figwidth figheight]);
179
180 % reset to original units for axes and figure.
181
182 if ~iscell(origaxunits)
183 origaxunits = {origaxunits};
184 end
185 for i = 1:numel(hax)
186 set(hax(i), 'Units', origaxunits{i});
187 end
188 set(fig, 'Units', origfigunits);
189
190 % set(fig, 'WindowStyle', origwindowstyle);
191end
192
193%> \cond excluded
194
195function [pos, ti] = colorbarpos(hcbar)
196 % 1 point is 0.3528 mm
197 pos = hcbar.Position;
198 ti = [0,0,0,0];
199 if ~isempty (strfind (hcbar.Location, 'outside'))
200 if strcmp (hcbar.AxisLocation, 'out')
201 tlabels = hcbar.TickLabels;
202 fsize = hcbar.FontSize;
203 switch hcbar.Location
204 case 'northoutside'
205 % make exta space a little more than the font size/height
206 ticklablespace_cm = 1.1 * (0.3528/10) * fsize;
207 ti(4) = ti(4) + ticklablespace_cm;
208 case 'eastoutside'
209 maxlabellen = max ( cellfun (@numel, tlabels, 'UniformOutput', true) );
210 % 0.62 factor is arbitrary and added because we don't
211 % know the width of every character in the label, the
212 % fsize refers to the height of the font
213 ticklablespace_cm = (0.3528/10) * fsize * maxlabellen * 0.62;
214 ti(3) = ti(3) + ticklablespace_cm;
215 case 'southoutside'
216 % make exta space a little more than the font size/height
217 ticklablespace_cm = 1.1 * (0.3528/10) * fsize;
218 ti(2) = ti(2) + ticklablespace_cm;
219 case 'westoutside'
220 maxlabellen = max ( cellfun (@numel, tlabels, 'UniformOutput', true) );
221 % 0.62 factor is arbitrary and added because we don't
222 % know the width of every character in the label, the
223 % fsize refers to the height of the font
224 ticklablespace_cm = (0.3528/10) * fsize * maxlabellen * 0.62;
225 ti(1) = ti(1) + ticklablespace_cm;
226 end
227 end
228 end
229end
230
231%> \endcond
function fitAxes(in fig)
Alters the figure size corresponding to the input figure handle fig such that it has the minimum size...
function show(in obj, in name, in hidden)
Display the components of an input MATLAB variable on MATLAB Console recursively.
excluded
Definition: show.m:173
function which(in vendor)
Return the a MATLAB string containing the path to the first mpiexec executable binary found in system...