ParaMonte MATLAB 3.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
Triplex.m
Go to the documentation of this file.
1%> \brief
2%> This is the base class for generating instances of
3%> figures containing a square symmetric tiling of subplots.<br>
4%>
5%> \details
6%> This class generates figures containing three types of plots in the
7%> upper-triangle, lower-triangle, and diagonal subplots of the figure.<br>
8%> The dataset is assumed to be common among all plots (though not necessarily).<br>
9%> As such, all axes labels and tick marks of all subplots are dropped by default,
10%> except for subplots in the the left and bottom boundaries of the figure.<br>
11%>
12%> If any of the three input subplot types has colorbar, it is disabled for individual subplots.<br>
13%> Instead, a universal colorbar will be visualized on the right side of the Triplex plot.<br>
14%>
15%> \note
16%> See the list of class attributes below,
17%> also those of the superclass [pm.vis.figure.Figure](@ref Figure).<br>
18%>
19%> \note
20%> See also the documentation of the constructor of the class [pm.vis.Triplex::Triplex](@ref Triplex::Triplex).<br>
21%>
22%> \final
23%>
24%> \author
25%> \AmirShahmoradi, August 31 2024, 6:40 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
26classdef Triplex < pm.vis.figure.Figure
27
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29
30 properties(Access = public)
31 %>
32 %> ``layout``
33 %>
34 %> The MATLAB ``struct`` containing the default layout of the Triplex plot.<br>
35 %> Such information includes the margin of the subplots from the
36 %> figure border and the interspaces between the subplots.<br>
37 %> This information is applied only to figure
38 %> components whose positions are unset.<br>
39 %>
40 layout = struct();
41 %>
42 %> ``subplot``
43 %>
44 %> The MATLAB cell matrix containing objects of superclass [pm.vis.Subplot](@ref Subplot)
45 %> each of which represents one subplot axes to display in the figure.<br>
46 %>
47 subplot = cell(0, 0);
48 end
49
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 properties(Access = public, Hidden)
53 %>
54 %> ``colorbared``
55 %>
56 %> The scalar MATLAB ``logical`` that is true **if and only if** any subplot requires colorbar.<br>
57 %> In such a case, all colorbar subplots will be disabled and a single global subplot will be added to the figure.<br>
58 %> If multiple plot types contain require colorbars.<br>
59 %>
60 colorbared = false;
61 end
62
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64
65 methods(Access = public)
66
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68
69 %> \brief
70 %> Construct and return an object of class [pm.vis.Triplex](@ref Triplex).<br>
71 %>
72 %> \details
73 %> This is the constructor of the class [pm.vis.Triplex](@ref Triplex).<br>
74 %>
75 %> \param[in] subplot : The input cell matrix of MATLAB objects of superclass [pm.vis.Subplot](@ref Subplot).<br>
76 %> \param[in] varargin : Any ``property, value`` pair of the parent object.<br>
77 %> If the property is a ``struct()``, then its value must be given as a cell array,
78 %> with consecutive elements representing the struct ``property-name, property-value`` pairs.<br>
79 %> Note that all of these property-value pairs can be also directly set via the
80 %> parent object attributes, before calling the ``make()`` method.<br>
81 %>
82 %> \return
83 %> ``self`` : The output scalar object of class [pm.vis.Triplex](@ref Triplex).<br>
84 %>
85 %> \interface{Triplex}
86 %> \code{.m}
87 %>
88 %> g = pm.vis.Triplex(subplot);
89 %> g = pm.vis.Triplex(subplot, varargin);
90 %>
91 %> \endcode
92 %>
93 %> \note
94 %> See the list of class attributes below,
95 %> also those of the superclass [pm.vis.figure.Figure](@ref Figure).<br>
96 %>
97 %> \final{Triplex}
98 %>
99 %> \author
100 %> \AmirShahmoradi, August 31 2024, 6:40 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
101 function self = Triplex(subplot, varargin)
102 if nargin < 1
103 subplot = cell(0, 0);
104 end
105 failed = ~iscell(subplot);
106 if ~failed
107 for irow = 1 : size(subplot, 1)
108 for icol = 1 : size(subplot, 2)
109 failed = ~isempty(subplot{irow, icol}) && ~pm.introspection.istype(subplot{irow, icol}, "pm.vis.Subplot");
110 if failed
111 break;
112 end
113 end
114 if failed
115 break;
116 end
117 end
118 end
119 if ~failed
120 varargin = {"subplot", subplot, varargin{:}};
121 else
122 help("pm.vis.Triplex");
123 error ( newline ...
124 + "The input argument ``subplot`` must be a MATLAB cell matrix of " + newline ...
125 + "empty objects or objects of superclass [pm.vis.Subplot](@ref Subplot)." + newline ...
126 + "For more information, see the class documentation displayed above." + newline ...
127 + newline ...
128 );
129 end
130 self = self@pm.vis.figure.Figure(varargin{:});
131 end
132
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134
135 %> \brief
136 %> Reset the properties of the figure to the original default settings.<br>
137 %>
138 %> \details
139 %> Use this method when you change many attributes of the plot and
140 %> you want to clean up and go back to the default settings.<br>
141 %>
142 %> \param[in] varargin : Any ``property, value`` pair of the parent object.<br>
143 %> If the property is a ``struct()``, then its value must be given as a cell array,
144 %> with consecutive elements representing the struct ``property-name, property-value`` pairs.<br>
145 %> Note that all of these property-value pairs can be also directly set via the
146 %> parent object attributes, before calling the ``make()`` method.<br>
147 %>
148 %> \interface{reset}
149 %> \code{.m}
150 %>
151 %> g = pm.vis.Triplex(subplot, varargin) % reset all object properties to the default settings.
152 %> g.reset(varargin);
153 %>
154 %> \endcode
155 %>
156 %> \final{reset}
157 %>
158 %> \author
159 %> \JoshuaOsborne, May 21 2024, 9:25 AM, University of Texas at Arlington<br>
160 %> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
161 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
162 function reset(self, varargin)
163
164 self.layout.margin.bottom = 0.07; % 0.14;
165 self.layout.margin.right = 0.10;
166 self.layout.margin.left = 0.07; %0.1;
167 self.layout.margin.top = 0.0;
168 self.layout.origin.x = 0.02;
169 self.layout.origin.y = 0.00;
170 self.layout.height = 1 - self.layout.margin.top;
171 self.layout.width = 1 - self.layout.margin.right;
172
173 self.layout.subplot = struct();
174 self.layout.subplot.width = [];
175 self.layout.subplot.height = [];
176 self.layout.subplot.interspacex = 0.015; % space between subplots in x direction;
177 self.layout.subplot.interspacey = 0.015; % space between subplots in y direction;
178
179 reset@pm.vis.figure.Figure(self, varargin{:}); % this will automatically call the ``premake()`` method of the object.
180
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 %%%% RULE 0: Any non-MATLAB-default setting must be preferably set in the make() method to override user null values.
183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184
185 %self.premake(varargin{:}); % This is the subclass method!
186
187 end
188
189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190
191 %> \brief
192 %> Preset the tiling settings before making it.<br>
193 %>
194 %> \warning
195 %> This method causes side-effects by manipulating
196 %> the existing attributes of the object.<br>
197 %>
198 %> \param[in] varargin : Any ``property, value`` pair of the parent object.<br>
199 %> If the property is a ``struct()``, then its value must be given as a cell array,
200 %> with consecutive elements representing the struct ``property-name, property-value`` pairs.<br>
201 %> Note that all of these property-value pairs can be also directly set via the
202 %> parent object attributes, before calling the ``make()`` method.<br>
203 %>
204 %> \interface{premake}
205 %> \code{.m}
206 %>
207 %> g = pm.vis.Triplex(subplot, varargin);
208 %> g.premake(varargin);
209 %>
210 %> \endcode
211 %>
212 %> \example{premake}
213 %>
214 %> \final{premake}
215 %>
216 %> \author
217 %> \JoshuaOsborne, May 21 2024, 9:28 AM, University of Texas at Arlington<br>
218 %> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
219 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
220 function premake(self, varargin)
221 premake@pm.vis.figure.Figure(self, varargin{:});
222 %if isempty(self.figure.position)
223 % self.figure.position = [ 50 ... origin x-start
224 % , 100 ... origin y-start
225 % , self.figure.width ... width
226 % , self.figure.height ... height
227 % ];
228 %end
229 end
230
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232
233 %> \brief
234 %> Configure the figure settings and specifications,
235 %> make the figure and the subplots, and return nothing.<br>
236 %>
237 %> \details
238 %> The subplots are made by calling their ``make()`` methods.<br>
239 %>
240 %> \warning
241 %> This method has side-effects by manipulating
242 %> the existing attributes of the parent object.<br>
243 %>
244 %> \param[in] varargin : Any ``property, value`` pair of the parent object.<br>
245 %> If the property is a ``struct()``, then its value must be given as a cell array,
246 %> with consecutive elements representing the struct ``property-name, property-value`` pairs.<br>
247 %> Note that all of these property-value pairs can be also directly set via the
248 %> parent object attributes, before calling the ``make()`` method.<br>
249 %>
250 %> \interface{make}
251 %> \code{.m}
252 %>
253 %> g = pm.vis.Triplex(subplot, varargin);
254 %> g.make(varargin);
255 %>
256 %> \endcode
257 %>
258 %> \final{make}
259 %>
260 %> \author
261 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
262 function make(self, varargin)
263
264 make@pm.vis.figure.Figure(self, varargin{:});
265
266 %%%% Resize the figure to allow good default visualization.
267
268 if isempty(self.figure.outerPosition) && 0 < numel(self.subplot)
269 fullSize = get(0, 'ScreenSize');
270 maxSize = fullSize;
271 maxSize(1:2) = .05 * maxSize(3:4);
272 maxSize(3:4) = maxSize(3:4) - maxSize(1:2);
273 figSize = self.fout.figure.OuterPosition;
274 maxScale = maxSize(3:4) ./ figSize(3:4);
275 newWidth = figSize(3) * min(maxScale(1), size(self.subplot, 2));
276 newHeight = figSize(4) * min(maxScale(2), size(self.subplot, 1));
277 figStart = [(fullSize(3) - newWidth) / 2, (fullSize(4) - newHeight) / 2];
278 set(self.fout.figure, "OuterPosition", [figStart(1:2), newWidth, newHeight]);
279 end
280
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 %%%% RULE 0: No component of ``self`` is allowed to appear to the left of assignment operator, except ``fout``.
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284
285 %kws = struct();
286 %for prop = [ "axes" ...
287 % ]
288 % if isprop(self, prop)
289 % kws.(prop) = self.comp2hash(prop);
290 % end
291 %end
292
293 %%%%
294 %%%% Setup the main axes.
295 %%%%
296
297 %self.setKeyVal(kws.axes, "xlim", [0, 1]);
298 %self.setKeyVal(kws.axes, "ylim", [0, 1]);
299 %self.setKeyVal(kws.axes, "color", "none");
300 %self.setKeyVal(kws.axes, "position", self.getAxesPositionMain());
301 %self.fout.axes = axes("Parent", self.fout.figure, kws.axes{:});
302 self.fout.axes = axes ( "Parent", self.fout.figure ...
303 , "position", self.getAxesPositionMain() ...
304 , "xlim", [0, 1], "ylim", [0, 1] ...
305 , "color", "none" ...
306 );
307 axis(self.fout.axes, "off");
308
309 iplt = 0;
310 timer = pm.timing.Timer();
311 spinner = pm.timing.Spinner();
312 for irow = 1 : size(self.subplot, 1)
313 for icol = 1 : size(self.subplot, 2)
314 iplt = iplt + 1;
315 spinner.spin(iplt / numel(self.subplot));
316 if pm.introspection.istype(self.subplot{irow, icol}, "pm.vis.Subplot")
317 self.subplot{irow, icol}.axes.position = self.getAxesPositionSubplot(jrow, icol);
318 self.subplot{irow, icol}.make();
319 end
320 end
321 end
322 if 0 < iplt
323 disp("done in " + sprintf("%.6f", string(timer.toc())) + " seconds.");
324 end
325
326 end % function
327
328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329
330 %> \brief
331 %> Hide the requested section(s) of the Triplex, and return nothing.<br>
332 %>
333 %> \warning
334 %> This method has side-effects by manipulating
335 %> the existing attributes of the parent object.<br>
336 %>
337 %> \param[in] varargin : A comma-separated sequence of strings to char-vectors each of which can be one of the following:
338 %> <ol>
339 %> <li> ``"diag"`` : corresponding to the diagonal subplots in the Triplex plot.
340 %> <li> ``"lower"`` : corresponding to the lower triangle of the Triplex plot.
341 %> <li> ``"upper"`` : corresponding to the upper triangle of the Triplex plot.
342 %> <li> ``"colorbar"`` : corresponding to the colorbar object of the Triplex plot.
343 %> </ol>
344 %> If no input argument is provided, the action is performed for all plot sections listed in the above.<br>
345 %>
346 %> \interface{hide}
347 %> \code{.m}
348 %>
349 %> g = pm.vis.Triplex(subplot, varargin);
350 %> g.make(varargin);
351 %> g.hide(varargin);
352 %>
353 %> \endcode
354 %>
355 %> \example{hide}
356 %> \code{.m}
357 %>
358 %> g = pm.vis.Triplex(subplot, varargin);
359 %> g.make(varargin);
360 %> g.hide() % hide all parts of the Triplex plot.
361 %> g.hide("diag","colorbar") % hide the diagonal subplots and the colorbar of the Triplex plot.
362 %> g.hide("lower") % hide the lower triangle subplots of the Triplex plot.
363 %>
364 %> \endcode
365 %>
366 %> \final{hide}
367 %>
368 %> \author
369 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
370 function hide(self, varargin)
371 self.hideShow("hide", varargin{:})
372 end
373
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375
376 %> \brief
377 %> Show the requested section(s) of the Triplex, and return nothing.<br>
378 %>
379 %> \warning
380 %> This method has side-effects by manipulating
381 %> the existing attributes of the parent object.<br>
382 %>
383 %> \param[in] varargin : A comma-separated sequence of strings to char-vectors each of which can be one of the following:
384 %> <ol>
385 %> <li> ``"diag"`` : corresponding to the diagonal subplots in the Triplex plot.
386 %> <li> ``"lower"`` : corresponding to the lower triangle of the Triplex plot.
387 %> <li> ``"upper"`` : corresponding to the upper triangle of the Triplex plot.
388 %> <li> ``"colorbar"`` : corresponding to the colorbar object of the Triplex plot.
389 %> </ol>
390 %> If no input argument is provided, the action is performed for all plot sections listed in the above.<br>
391 %>
392 %> \interface{show}
393 %> \code{.m}
394 %>
395 %> g = pm.vis.Triplex(subplot, varargin);
396 %> g.make(varargin);
397 %> g.show(varargin);
398 %>
399 %> \endcode
400 %>
401 %> \example{show}
402 %> \code{.m}
403 %>
404 %> g = pm.vis.Triplex(subplot, varargin);
405 %> g.make(varargin);
406 %> g.show() % show all parts of the Triplex plot.
407 %> g.show("diag","colorbar") % show the diagonal subplots and the colorbar of the Triplex plot.
408 %> g.show("lower") % show the lower triangle subplots of the Triplex plot.
409 %>
410 %> \endcode
411 %>
412 %> \final{show}
413 %>
414 %> \author
415 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
416 function show(self, varargin)
417 self.hideShow("show", varargin{:})
418 end
419
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421
422 %> \brief
423 %> Rotate the axes labels of the subplots of the Triplex, and return nothing.<br>
424 %>
425 %> \warning
426 %> This method has side-effects by manipulating
427 %> the existing attributes of the parent object.<br>
428 %>
429 %> \param[in] degx : The input scalar MATLAB positive whole-number, representing the amount of
430 %> rotation to be applied to the x-axis labels with respect to the horizontal line.<br>
431 %> If it is set to empty ``[]``, the axis label orientation will remain intact.<br>
432 %> (**optional**, default = ``45``. It must be present if and only if ``degy`` is also present.)
433 %> \param[in] degy : The input scalar MATLAB positive whole-number, representing the amount of
434 %> rotation to be applied to the y-axis labels with respect to the horizontal line.<br>
435 %> If it is set to empty ``[]``, the axis label orientation will remain intact.<br>
436 %> (**optional**, default = ``45``. It must be present if and only if ``degx`` is also present.)
437 %>
438 %> \interface{rotateAxesLabels}
439 %> \code{.m}
440 %>
441 %> g = pm.vis.Triplex(subplot, varargin);
442 %> g.make(varargin);
443 %> g.rotateAxesLabels(); % rotate all axes labels by 45 degrees.
444 %> g.rotateAxesLabels(degx, []); % rotate x-axis labels by ``degx`` degrees.
445 %> g.rotateAxesLabels([], degy); % rotate y-axis labels by ``degy`` degrees.
446 %> g.rotateAxesLabels(degx, degy); % rotate x-axis and y-axis labels by ``degx`` and ``degy`` degrees.
447 %>
448 %> \endcode
449 %>
450 %> \final{rotateAxesLabels}
451 %>
452 %> \author
453 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
454 function rotateAxesLabels(self, degx, degy)
455 if nargin < 2
456 degx = 45;
457 degy = 45;
458 elseif nargin ~= 3
459 help("pm.vis.Triplex.rotateAxesLabels");
460 error ( newline ...
461 + "The ``rotateAxesLabels()`` method takes either no or exactly two input arguments." + newline ...
462 + "If no argument is passed, axes labels will be rotated 45 degrees." + newline ...
463 + "For more information, see the class documentation displayed above." + newline ...
464 + newline ...
465 );
466 end
467 for icol = 1 : size(self.subplot, 2)
468 for irow = 1 : size(self.subplot, 2)
469 axisLabelX = get(self.subplot{irow,icol}.fout.axes, "XLabel");
470 axisLabelY = get(self.subplot{irow,icol}.fout.axes, "YLabel");
471 set(axisLabelX, "rotation", degx, "VerticalAlignment", "top", "HorizontalAlignment", "right");
472 set(axisLabelY, "rotation", degy, "VerticalAlignment", "middle", "HorizontalAlignment", "right");
473 end
474 end
475
476 end % rotateAxesLabels
477
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479
480 end
481
482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
483
484 methods(Access = public, Hidden)
485
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
487
488 function hideShow(self, varargin)
489
490 diagRequested = false;
491 lowerRequested = false;
492 upperRequested = false;
493 colorbarRequested = false;
494 action = string(varargin{1});
495 actionIsShow = strcmpi(action, "show");
496 actionIsHide = strcmpi(action, "hide");
497 if actionIsShow
498 switchValue = "on";
499 elseif actionIsHide
500 switchValue = "off";
501 end
502 %%%% act on all parts of the figure.
503 if nargin == 2
504 diagRequested = true;
505 lowerRequested = true;
506 upperRequested = true;
507 colorbarRequested = true;
508 elseif nargin > 2
509 for i = 2 : length(varargin)
510 part = string(varargin{i});
511 if strcmpi(part, "diag")
512 diagRequested = true;
513 elseif strcmpi(part, "upper")
514 upperRequested = true;
515 elseif strcmpi(part, "lower")
516 lowerRequested = true;
517 elseif strcmpi(part, "colorbar") || strcmpi(part, "cbar")
518 colorbarRequested = true;
519 else
520 error ( newline ...
521 + "Unrecognized input argument pass to the " + action + "() method: " + newline ...
522 + newline ...
523 + join(part, " ") + newline ...
524 + newline ...
525 + "The " + action + "() method accepts only a list of comma-separated string" ...
526 + "values representing the ""part"" of the grid plot to " + action + ". " ...
527 + "Alternatively, if no argument is passed to " + action + "(), then all subplots will be affected." + newline ...
528 );
529 end
530 end
531 else
532 error ( newline ...
533 + "Internal error occurred. Not enough input arguments to hideShow()." ...
534 + newline ...
535 );
536 end
537
538 if colorbarRequested
539
540 if actionIsShow
541
542 if getVecLen(self.colormap.values)
543 colormap(self.currentFig.axes, self.colormap.values);
544 elseif strcmp(self.plotType.upper.value,"lineScatter") || strcmp(self.plotType.lower.value,"lineScatter")
545 if self.template.lineScatter.colormap.enabled && getVecLen(self.template.lineScatter.colormap.values)
546 colormap(self.currentFig.axes, self.template.lineScatter.colormap.values);
547 end
548 else
549 cornerList = ["upper","lower"];
550 for i = 1:length(cornerList)
551 cornerValue = self.plotType.(cornerList(i)).value;
552 if contains(cornerValue,"contour")
553 if self.template.(cornerValue).colormap.enabled && getVecLen(self.template.(cornerValue).colormap.values)
554 colormap(self.currentFig.axes, self.template.(cornerValue).colormap.values);
555 break;
556 end
557 end
558 end
559 end
560
561 % get column names
562
563 if getVecLen(self.ccolumn)
564 [self.ccolnames, self.ccolindex] = getColNamesIndex(self.dfref.Properties.VariableNames,self.ccolumn);
565 ccolumnValues = self.dfref.(self.ccolnames);
566 else
567 ccolumnValues = self.rows;
568 self.ccolnames = "Count";
569 disp( newline ...
570 + "the component ""ccolumn"" of the GridPlot object appears to be empty. " ...
571 + "Using the data counts instead for colormapping..." ...
572 + newline ...
573 );
574 end
575
576 colorbarLimit = [ min(ccolumnValues) max(ccolumnValues) ]; % Colorbar range
577 caxis(self.currentFig.axes,colorbarLimit);
578 set(self.currentFig.axes,"CLim",colorbarLimit);
579 self.currentFig.colorbar = colorbar(self.currentFig.axes,colorbar_kws_cell{:});
580
581 colorbarLabel = self.ccolnames;
582 ylabel(self.currentFig.colorbar,colorbarLabel,"fontSize",self.colorbar.kws.fontSize);
583
584 set ( self.currentFig.colorbar ...
585 , "position" ...
586 , self.getColorbarAxisPosition() ...
587 , "fontSize", self.colorbar.kws.fontSize ...
588 ) ;
589
590 elseif actionIsHide
591
592 %colorbar("off");
593 set(self.currentFig.colorbar,'visible','off');
594
595 end
596
597 end
598
599 for icol = 1:self.axes.main.ncol
600 for irow = 1:self.axes.main.nrow
601 if (icol<irow && lowerRequested) || (icol>irow && upperRequested) || (icol==irow && diagRequested)
602 set(self.currentFig.subplotList{irow,icol}.currentFig.axes,"visible",switchValue);
603 set(get(self.currentFig.subplotList{irow,icol}.currentFig.axes,"children"),"visible",switchValue);
604 end
605 end
606 end
607
608 if lowerRequested || upperRequested || diagRequested
609 self.hideShowAxesLabels();
610 end
611
612 end % function hideShow
613
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615
616 %> \brief
617 %> Hide or show axis labels and ticks depending on the presence of the neighbor subplots.<br>
618 %>
619 %> \warning
620 %> This method causes side-effects by manipulating
621 %> the existing attributes of the object.<br>
622 %>
623 %> \interface{hideShowAxesLabels}
624 %> \code{.m}
625 %>
626 %> g = pm.vis.Triplex(subplot, varargin);
627 %> g.hideShowAxesLabels();
628 %>
629 %> \endcode
630 %>
631 %> \example{hideShowAxesLabels}
632 %>
633 %> \final{hideShowAxesLabels}
634 %>
635 %> \author
636 %> \JoshuaOsborne, May 21 2024, 9:28 AM, University of Texas at Arlington<br>
637 %> \FatemehBagheri, May 20 2024, 1:25 PM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
638 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
639 function hideShowAxesLabels(self)
640
641 for icol = 1 : size(self.subplot, 2)
642
643 %%%%
644 %%%% Set the axes labels.
645 %%%%
646
647 for irow = 1 : size(self.subplot, 1)
648
649 subplotExists = ~isempty(self.subplot{irow, icol});
650
651 if subplotExists
652 if irow < size(self.subplot, 1)
653 if ~isempty(self.subplot{irow + 1, icol}) && strcmp(self.subplot{irow + 1, icol}.fout.axes.Visible, "on")
654 set(self.subplot{irow, icol}.fout.axes, "XTickLabel", []);
655 self.subplot{irow, icol}.fout.axes.XLabel.String = "";
656 else
657 set(self.subplot{irow, icol}.fout.axes, "XTickLabelMode", "auto");
658 self.subplot{irow, icol}.fout.axes.XLabel.String = self.colnames(icol);
659 end
660 end
661
662 if icol > 1
663 if ~isempty(self.subplot{irow, icol - 1}) && strcmp(self.subplot{irow, icol - 1}.fout.axes.Visible, "on")
664 set(self.subplot{irow, icol}.fout.axes, "YTickLabel", [])
665 self.subplot{irow, icol}.fout.axes.YLabel.String = "";
666 elseif ~isempty(self.subplot{irow, icol})
667 set(self.subplot{irow, icol}.fout.axes, "YTickLabelMode", "auto")
668 self.subplot{irow, icol}.fout.axes.YLabel.String = self.colnames(irow);
669 end
670 end
671 end
672
673 if icol ~= 1 && subplotExists
674 axisLabelY = get(self.subplot{irow, icol}.fout.axes, "YLabel");
675 set(axisLabelY, "rotation", 45, "VerticalAlignment", "middle", "HorizontalAlignment", "right");
676 end
677 if irow ~= size(self.subplot, 1) && subplotExists
678 axisLabelX = get(self.subplot{irow, icol}.fout.axes, "XLabel");
679 set(axisLabelX, "rotation", 45, "VerticalAlignment", "top", "HorizontalAlignment", "right");
680 end
681
682 end
683
684 end % icol
685
686 self.adjustAxesTicks();
687
688 end
689
690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691
692 function adjustAxesTicks(self)
693
694 %%%%
695 %%%% reset the ytick labels of the diagonal subplots to x-axis ticks when there are subplots to their right.
696 %%%%
697
698 for icol = 1 : size(self.subplot, 2)
699
700 if ~isempty(self.subplot{icol, icol}) && strcmp(self.subplot{icol, icol}.fout.axes.Visible, "on")
701
702 % do NOT change the order of conditions in the if blocks. short-circuit is at work.
703 if (icol == size(self.subplot, 2) && (isempty(self.subplot{icol, icol - 1}) || strcmp(self.subplot{icol, icol - 1}.fout.axes.Visible, "off"))) ...
704 || (icol == 1 && (isempty(self.subplot{icol, icol + 1}) || strcmp(self.subplot{icol, icol+1}.fout.axes.Visible, "off"))) ...
705 || (icol ~=1 && icol ~= size(self.subplot, 2) ...
706 && ...
707 ( isempty(self.subplot{icol, icol + 1}) || strcmp(self.subplot{icol, icol + 1}.fout.axes.Visible, "off")) ...
708 && ...
709 ( isempty(self.subplot{icol, icol - 1}) || strcmp(self.subplot{icol, icol - 1}.fout.axes.Visible, "off")) ...
710 )
711
712 %%%% Let the histograms have their own y-ranges.
713
714 set(self.subplot{icol, icol}.fout.axes, "YTickMode", "auto", "YTickLabelMode", "auto");
715
716 elseif icol < size(self.subplot, 2)
717
718 currentSubplot = self.subplot{icol, icol}.fout;
719
720 %%%% Set the y-range and ticklabels according to the needs of the neighbor plots.
721
722 if icol == 1 || isempty(self.subplot{icol, icol - 1}) || strcmp(self.subplot{icol, icol - 1}.fout.axes.Visible, "off")
723
724 if ~isempty(self.subplot{end, icol})
725 currentNeighbor = self.subplot{end, icol}.fout;
726 else
727 currentNeighbor = currentSubplot;
728 end
729 yticks(currentSubplot.axes, self.diagYTick{icol}.modified.values);
730 yticklabels(currentSubplot.axes, self.diagYTick{icol}.modified.labels);
731
732 %%%% Set Y-axis label.
733
734 retryEnabled = false;
735 if ~isfield(currentNeighbor, "xlabel") || isempty(currentNeighbor.xlabel.String)
736 retryEnabled = true;
737 else
738 try
739 ylabel(currentSubplot.axes, currentNeighbor.xlabel.String);
740 catch
741 retryEnabled = true;
742 end
743 end
744 if retryEnabled
745 retryEnabled = false;
746 if isempty(currentSubplot.xlabel.String)
747 retryEnabled = true;
748 else
749 try
750 ylabel(currentSubplot.axes, string(currentSubplot.xlabel.String));
751 catch
752 retryEnabled = true;
753 end
754 end
755 if retryEnabled
756 ylabel(currentSubplot.axes, string(self.subplot{icol, icol}.xcolumns));
757 end
758 end
759
760 end
761
762 end
763
764 end
765
766 end
767
768 end
769
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771
772 function position = getAxesPositionColorbar(self)
773 position = [ self.layout.colorbar.origin.x ...
774 , self.layout.colorbar.origin.y ...
775 , self.layout.colorbar.width ...
776 , self.layout.colorbar.height ...
777 ];
778 end
779
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781
782 function position = getAxesPositionSubplot(self, irow, icol)
783 position = [ (icol - 1) * (self.layout.subplot.interspacex + self.layout.subplot.width) + self.layout.axes.margin.left ...
784 , (irow - 1) * (self.layout.subplot.interspacey + self.layout.subplot.height) + self.layout.axes.margin.bottom ...
785 , self.layout.subplot.width ...
786 , self.layout.subplot.height ...
787 ];
788 end
789
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791
792 function position = getAxesPositionMain(self)
793 position = [ self.layout.axes.origin.x ...
794 , self.layout.axes.origin.y ...
795 , self.layout.axes.width ...
796 , self.layout.axes.height ...
797 ];
798 end
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801
802 %> \brief
803 %> Update the layout of the Triplex plot with the new changes.<br>
804 %>
805 %> \details
806 %> For example, change the left/bottom margin of the main
807 %> axis of the figure to provide room for lengthy variable names.<br>
808 %> Then call the setLayout() method of layout to reflect the changes.<br>
809 %>
810 %> \warning
811 %> This method causes side-effects by manipulating
812 %> the existing attributes of the object.<br>
813 %>
814 %> \interface{setLayout}
815 %> \code{.m}
816 %>
817 %> g = pm.vis.Triplex(subplot, varargin);
818 %> g.setLayout();
819 %>
820 %> \endcode
821 %>
822 %> \example{setLayout}
823 %>
824 %> \final{setLayout}
825 %>
826 %> \author
827 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
828 function setLayout(self)
829 self.axes.height = 1 - self.axes.margin.top;
830 self.axes.width = 1 - self.axes.margin.right;
831 self.axes.subplot.width = (1 - self.axes.margin.left - self.axes.margin.right) / size(self.subplot, 1) - self.axes.subplot.interspacex;
832 self.axes.subplot.height = (1 - self.axes.margin.top - self.axes.margin.bottom) / size(self.subplot, 2) - self.axes.subplot.interspacey;
833 self.colorbar.origin.x = 1 - self.axes.margin.right;
834 self.colorbar.origin.y = self.axes.margin.bottom;
835 self.colorbar.height = size(self.subplot, 1) * (self.axes.subplot.height + self.axes.subplot.interspacey) - self.axes.subplot.interspacex;
836 self.figure.width = self.figure.height * (1 ...
837 - self.axes.margin.bottom ...
838 + self.axes.margin.right ...
839 + self.axes.margin.left ...
840 - self.axes.margin.top ...
841 + self.colorbar.width ...
842 );
843 if isfield(self, "fout") && isfield(self.fout, "gca") && isgraphics(self.fout.axes)
844 set(self.fout.axes, "position", self.getAxesPositionMain());
845 end
846 if any(strcmp(fieldnames(self.fout), "colorbar")) && isgraphics(self.fout.colorbar)
847 set(self.fout.colorbar, "position", self.getColorbarAxisPosition());
848 end
849 for irow = 1 : size(self.subplot, 1)
850 for icol = 1 : size(self.subplot, 2)
851 jrow = size(self.subplot, 1) - irow + 1;
852 if isgraphics(self.subplot{irow, icol}.fout.axes)
853 set(self.subplot{irow,icol}.fout.axes, "position", self.getAxesPositionSubplot(jrow, icol));
854 end
855 end
856 end
857 end
858
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860
861 end
862
863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864
865end
function name(in vendor)
Return the MPI library name as used in naming the ParaMonte MATLAB shared libraries.
function list()
Return a list of MATLAB strings containing the names of OS platforms supported by the ParaMonte MATLA...
This is the abstract class for generating instances of objects that contain the specifications of var...
Definition: Figure.m:27
This is the abstract class for generating instances of axes with various types of plots from one or m...
Definition: Subplot.m:188
This is the base class for generating instances of figures containing a square symmetric tiling of su...
Definition: Triplex.m:27
function premake(in self, in varargin)
Preset the tiling settings before making it.
Property subplot
Definition: Triplex.m:51
function setLayout(in self)
Update the layout of the Triplex plot with the new changes.
function show(in self, in varargin)
Show the requested section(s) of the Triplex, and return nothing.
Property layout
Definition: Triplex.m:43
function hideShow(in self, in varargin)
function reset(in self, in varargin)
Reset the properties of the figure to the original default settings.
function adjustAxesTicks(in self)
function Triplex(in subplot, in varargin)
Construct and return an object of class pm.vis.Triplex.
function hideShowAxesLabels(in self)
Hide or show axis labels and ticks depending on the presence of the neighbor subplots.
function hide(in self, in varargin)
Hide the requested section(s) of the Triplex, and return nothing.
function make(in self, in varargin)
Configure the figure settings and specifications, make the figure and the subplots,...
function rotateAxesLabels(in self, in degx, in degy)
Rotate the axes labels of the subplots of the Triplex, and return nothing.
function getAxesPositionSubplot(in self, in irow, in icol)
function getAxesPositionMain(in self)
Property colorbared
Definition: Triplex.m:65
function getAxesPositionColorbar(in self)
function clean()
Remove all paths that contain the ParaMonte lib directory from the MATLAB path variable.
function istype(in varval, in vartype, in varsize)
Return true if and only if the input varval conforms with the specified input type vartype and the sp...
function show(in obj, in name, in hidden)
Display the components of an input MATLAB variable on MATLAB Console recursively.
function which(in vendor)
Return the a MATLAB string containing the path to the first mpiexec executable binary found in system...