2%> This is the base
class for generating instances of
3%> figures containing a square symmetric tiling of subplots.<br>
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>
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>
16%> See the
list of
class attributes below,
17%> also those of the superclass [pm.vis.figure.Figure](@ref
Figure).<br>
20%> See also the documentation of the constructor of the
class [pm.vis.Triplex::Triplex](@ref
Triplex::Triplex).<br>
25%> \AmirShahmoradi, August 31 2024, 6:40 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30 properties(Access =
public)
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>
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>
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 properties(Access =
public, Hidden)
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>
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 methods(Access =
public)
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 %> Construct and
return an
object of
class [pm.vis.Triplex](@ref
Triplex).<br>
73 %> This is the constructor of the
class [pm.vis.Triplex](@ref
Triplex).<br>
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>
83 %> ``self`` : The output scalar
object of
class [pm.vis.Triplex](@ref
Triplex).<br>
89 %> g = pm.vis.Triplex(subplot, varargin);
94 %> See the
list of
class attributes below,
95 %> also those of the superclass [pm.vis.figure.Figure](@ref
Figure).<br>
100 %> \AmirShahmoradi, August 31 2024, 6:40 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
101 function self =
Triplex(subplot, varargin)
103 subplot = cell(0, 0);
105 failed = ~iscell(subplot);
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");
120 varargin = {
"subplot", subplot, varargin{:}};
122 help(
"pm.vis.Triplex");
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 ...
130 self = self@pm.vis.figure.Figure(varargin{:});
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 %> Reset the properties of the figure to the original
default settings.<br>
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>
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>
151 %> g = pm.vis.Triplex(subplot, varargin) % reset all
object properties to the
default settings.
152 %> g.reset(varargin);
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)
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;
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;
179 reset@pm.vis.figure.Figure(self, varargin{:}); %
this will automatically call the ``premake()`` method of the
object.
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 %%%% RULE 0: Any non-MATLAB-
default setting must be preferably set in the make() method to override user null values.
183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 %self.premake(varargin{:}); % This is the subclass method!
189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 %> Preset the tiling settings before making it.<br>
195 %> This method causes side-effects by manipulating
196 %> the existing attributes of the
object.<br>
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>
204 %> \interface{premake}
207 %> g = pm.vis.Triplex(subplot, varargin);
208 %> g.premake(varargin);
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
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234 %> Configure the figure settings and specifications,
235 %> make the figure and the subplots, and
return nothing.<br>
238 %> The subplots are made by calling their ``make()`` methods.<br>
241 %> This method has side-effects by manipulating
242 %> the existing attributes of the parent
object.<br>
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>
253 %> g = pm.vis.Triplex(subplot, varargin);
261 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
262 function make(self, varargin)
264 make@pm.vis.figure.Figure(self, varargin{:});
266 %%%% Resize the figure to allow good
default visualization.
268 if isempty(self.figure.outerPosition) && 0 < numel(self.subplot)
269 fullSize = get(0, 'ScreenSize');
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]);
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 %%%% RULE 0: No component of ``self`` is allowed to appear to the left of assignment operator, except ``fout``.
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 %for prop = [ "axes" ...
288 % if isprop(self, prop)
289 % kws.(prop) = self.comp2hash(prop);
294 %%%% Setup the main axes.
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" ...
307 axis(self.fout.axes,
"off");
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)
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();
323 disp(
"done in " + sprintf(
"%.6f",
string(timer.toc())) +
" seconds.");
328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331 %> Hide the requested section(s) of the
Triplex, and
return nothing.<br>
334 %> This method has side-effects by manipulating
335 %> the existing attributes of the parent
object.<br>
337 %> \param[in] varargin : A comma-separated sequence of strings to
char-vectors each of
which can be one of the following:
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.
344 %> If no input argument is provided, the action is performed
for all plot sections listed in the above.<br>
349 %> g = pm.vis.
Triplex(subplot, varargin);
358 %> g = pm.vis.Triplex(subplot, 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.
369 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
370 function hide(self, varargin)
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377 %> Show the requested section(s) of the
Triplex, and
return nothing.<br>
380 %> This method has side-effects by manipulating
381 %> the existing attributes of the parent
object.<br>
383 %> \param[in] varargin : A comma-separated sequence of strings to
char-vectors each of
which can be one of the following:
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.
390 %> If no input argument is provided, the action is performed
for all plot sections listed in the above.<br>
395 %> g = pm.vis.Triplex(subplot, varargin);
404 %> g = pm.vis.Triplex(subplot, varargin);
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.
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{:})
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 %> Rotate the axes labels of the subplots of the
Triplex, and
return nothing.<br>
426 %> This method has side-effects by manipulating
427 %> the existing attributes of the parent
object.<br>
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.)
438 %> \interface{rotateAxesLabels}
441 %> g = pm.vis.
Triplex(subplot, 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.
450 %> \final{rotateAxesLabels}
453 %> \AmirShahmoradi, July 7 2024, 12:53 AM, NASA Goddard Space Flight Center (GSFC), Washington, D.C.<br>
454 function rotateAxesLabels(self, degx, degy)
459 help(
"pm.vis.Triplex.rotateAxesLabels");
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 ...
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");
476 end % rotateAxesLabels
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
484 methods(Access =
public, Hidden)
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 function hideShow(self, varargin)
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");
502 %%%% act on all parts of the figure.
504 diagRequested =
true;
505 lowerRequested =
true;
506 upperRequested =
true;
507 colorbarRequested =
true;
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;
521 + "Unrecognized input argument pass to the " + action + "() method: " + newline ...
523 + join(part, " ") + 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 ...
533 + "Internal error occurred. Not enough input arguments to hideShow()." ...
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);
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);
563 if getVecLen(self.ccolumn)
564 [self.ccolnames, self.ccolindex] = getColNamesIndex(self.dfref.Properties.VariableNames,self.ccolumn);
565 ccolumnValues = self.dfref.(self.ccolnames);
567 ccolumnValues = self.rows;
568 self.ccolnames = "Count";
570 + "the component ""ccolumn"" of the GridPlot
object appears to be empty. " ...
571 + "Using the data counts instead for colormapping..." ...
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{:});
581 colorbarLabel = self.ccolnames;
582 ylabel(self.currentFig.colorbar,colorbarLabel,
"fontSize",self.colorbar.kws.fontSize);
584 set ( self.currentFig.colorbar ...
586 , self.getColorbarAxisPosition() ...
587 ,
"fontSize", self.colorbar.kws.fontSize ...
593 set(self.currentFig.colorbar,
'visible',
'off');
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);
608 if lowerRequested || upperRequested || diagRequested
609 self.hideShowAxesLabels();
612 end % function hideShow
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 %> Hide or
show axis labels and ticks depending on the presence of the neighbor subplots.<br>
620 %> This method causes side-effects by manipulating
621 %> the existing attributes of the
object.<br>
623 %> \interface{hideShowAxesLabels}
626 %> g = pm.vis.Triplex(subplot, varargin);
627 %> g.hideShowAxesLabels();
631 %> \example{hideShowAxesLabels}
633 %> \final{hideShowAxesLabels}
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)
641 for icol = 1 : size(self.subplot, 2)
644 %%%% Set the axes labels.
647 for irow = 1 : size(self.subplot, 1)
649 subplotExists = ~isempty(self.subplot{irow, icol});
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 =
"";
657 set(self.subplot{irow, icol}.fout.axes,
"XTickLabelMode",
"auto");
658 self.subplot{irow, icol}.fout.axes.XLabel.String = self.colnames(icol);
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);
673 if icol ~= 1 && subplotExists
674 axisLabelY = get(self.subplot{irow, icol}.fout.axes,
"YLabel");
675 set(axisLabelY,
"rotation", 45,
"VerticalAlignment",
"middle",
"HorizontalAlignment",
"right");
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");
686 self.adjustAxesTicks();
690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 function adjustAxesTicks(self)
695 %%%% reset the ytick labels of the diagonal subplots to x-axis ticks when there are subplots to their right.
698 for icol = 1 : size(self.subplot, 2)
700 if ~isempty(self.subplot{icol, icol}) && strcmp(self.subplot{icol, icol}.fout.axes.Visible,
"on")
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) ...
707 ( isempty(self.subplot{icol, icol + 1}) || strcmp(self.subplot{icol, icol + 1}.fout.axes.Visible,
"off")) ...
709 ( isempty(self.subplot{icol, icol - 1}) || strcmp(self.subplot{icol, icol - 1}.fout.axes.Visible,
"off")) ...
712 %%%% Let the histograms have their own y-ranges.
714 set(self.subplot{icol, icol}.fout.axes,
"YTickMode",
"auto",
"YTickLabelMode",
"auto");
716 elseif icol < size(self.subplot, 2)
718 currentSubplot = self.subplot{icol, icol}.fout;
720 %%%% Set the y-range and ticklabels according to the needs of the neighbor plots.
722 if icol == 1 || isempty(self.subplot{icol, icol - 1}) || strcmp(self.subplot{icol, icol - 1}.fout.axes.Visible,
"off")
724 if ~isempty(self.subplot{end, icol})
725 currentNeighbor = self.subplot{end, icol}.fout;
727 currentNeighbor = currentSubplot;
729 yticks(currentSubplot.axes, self.diagYTick{icol}.modified.values);
730 yticklabels(currentSubplot.axes, self.diagYTick{icol}.modified.labels);
732 %%%% Set Y-axis label.
734 retryEnabled =
false;
735 if ~isfield(currentNeighbor,
"xlabel") || isempty(currentNeighbor.xlabel.String)
739 ylabel(currentSubplot.axes, currentNeighbor.xlabel.String);
745 retryEnabled = false;
746 if isempty(currentSubplot.xlabel.String)
750 ylabel(currentSubplot.axes,
string(currentSubplot.xlabel.String));
756 ylabel(currentSubplot.axes,
string(self.subplot{icol, icol}.xcolumns));
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 ...
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 ...
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 ...
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 %> Update the layout of the
Triplex plot with the
new changes.<br>
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>
811 %> This method causes side-effects by manipulating
812 %> the existing attributes of the
object.<br>
814 %> \interface{setLayout}
817 %> g = pm.vis.
Triplex(subplot, varargin);
822 %> \example{setLayout}
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 ...
843 if isfield(self,
"fout") && isfield(self.fout,
"gca") && isgraphics(self.fout.axes)
844 set(self.fout.axes, "position", self.getAxesPositionMain());
846 if any(strcmp(fieldnames(self.fout), "colorbar")) && isgraphics(self.fout.colorbar)
847 set(self.fout.colorbar, "position", self.getColorbarAxisPosition());
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));
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 axes with various types of plots from one or m...
This is the base class for generating instances of figures containing a square symmetric tiling of su...
function premake(in self, in varargin)
Preset the tiling settings before making it.
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.
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)
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...