-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubplot_grid.m
4548 lines (3861 loc) · 165 KB
/
subplot_grid.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
classdef subplot_grid < handle
properties
version = '6.0'
hgVersion;
current_axes = [1,1]
titles = struct('template',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'title',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'subtitle',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'rowtitles_left',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'rowtitles_right',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'coltitles_top',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]),...
'coltitles_bottom',struct('valid',0,'hax',[],'htxt',[],'txtbox_sizes',0,'ratios',[]));
nof_rows
nof_columns
mergelist
hfig
hax
Iax
Rax
Cax
hlegend
subplotzoom_enabled
interaxes_selection_mods = struct('LineWidth',2,...
'LineStyle','-')
legend_data
legend_data_defaults = struct('valid',false,...
'location','nei',...
'tag',[],...
'buffer_px',2*ones(1,4),...
'print_legend_title',true);
loose_inset_px = 10*ones(1,4);
subplotzoom_data
hcolorbar;
zoomlinklist;
zoom_button_size_x = 10;
zoom_button_size_y = 10;
zoomed
hidden_axes
hidden_axes_manual
interaxes_data = struct([]);
interaxes_supported_types = {'line';
'image';
'surface';
};
viewer = struct('nof_minor_rows',0,...
'starting_index',0);
loose_inset_px_default = 5*ones(1,4)
in_panel = false;
panel_padding = 2; % pixels
hparent
pos_parent_in_figure = [0 0 1 1];
subplotzoom_init_state = 1;
colorbar_data
colorbar_data_defaults = struct('valid',false,...
'location','eeo',...
'tag',[],...
'cmap','auto',...
'shortdim_px',10,...
'buffer_px',2*ones(1,4),...
'scaled','auto',...
'datalim','auto');
end
methods
function this = subplot_grid(varargin)
%
% ****************************************************************
% *** THIS VERSION IS ONLY TESTED ON MATLAB R2014b
% *** CORRECT FUNCTIONING FOR EARLIER RELEASES IS NOT GUARANTEED
% *** (and not even expected)
% ****************************************************************
%
%
% SUBPLOT_GRID generates a figure containing the number of subplots
% wanted. Subplots can be merged through a variable input parameters.
%
% subplot_grid or subplot_grid('demo') will render a sequence
% showing some of the features of subplot_grid. Via a keypress the
% sequence moves one step.
%
% hsg = subplot_grid(nax) creates a figure with nax
% laid-out in a 2D matrix. hsg is the subplot_grid object
% which properties can be called and which methods (see
% below) can be invoked.
%
% hsg = subplot_grid(nrows,ncols) creates a figure with nrows
% rows and ncols columns of axes.
%
% hsg = subplot_grid('viewer',nax) creates a subplot_grid
% panel with a big 5-row spanning axes and nax small axes.
%
% hsg = subplot_grid('viewer',nax,nrows) places the little
% axes in nrows rows below the major graph.
%
% hsg = subplot_grid('viewer',nax,nrows,mode) places nrows of
% little axes either below or above the major axes. Mode can
% hold either 'top' or 'bottom'.
% Note that using the method 'set_gca' is modified:
% hsg.set_gca(1) will make the big axes the current axes,
% while hsg.set_gca('viewer',1) will make the first little
% axes current.
%
% Some properties have been defined which can be set via the
% property/value pairs after the mandatory nax or nrows and
% ncols parameters. These properties do not work in 'viewer'
% mode.
%
% hsg = subplot_grid(nax,'property',value,...) or hsg =
% subplot_grid(nrows,ncols,'property',value,...) sets these
% properties. No particular order is required. See the demo
% to check how it works.
%
% The valid properties are:
%
% 'mergelist'
% Cell array of vectors. Every vector contains subplot
% indices. The subplots to merge are the subplots in the
% rectangle spanning all subplots indices in the vector. A 2D
% vector is therefore sufficient to merge multiple
% subplots.
%
% 'zoomlinklist'
% Cell array of vectors. Every vector contains
% subplot indices for axes to link while zooming
% out. That is, when clicked on the + sign, all
% axes linked are enlarged together in a single column.
%
% 'parent'
% Gives the handle of the object (either a figure or a panel) in
% which subplot_grid creates its axes and works its stuff
%
% 'no_zoom'
% Does not need any value(s), but indicates that
% subplot_grid should not place zoom-buttons in the
% axes (generally used in case some print-out needs
% to be made and the buttons look ugly)
%
% The possibility of saving and reloading the figure exists. Saving
% the figure as a .fig file via the 'Save Figure' toolbar button
% will work fine when reloading via 'openfig'. However, some bug
% has been found - and not solved yet- in case hgload and hgsave
% are used. So please refrain from using these functions in
% combination with subplot_grid.
%
% Re-loading a saved subplot_grid object will show the figure panel
% and contents plus creates a handle to the subplot_grid object
% called 'o_subplot_grid'. This could be renamed to whatever is
% handy. Via the properties and methods of this object, anything
% should be enabled again.
%
% After the subplot_grid object has been create the contents may be
% modified via the following user methods.
%
% USER METHODS:
%
% NOTE: every user method help function can be inspected by typing
% 'subplot_grid.<method>'.
%
% *Listed alphabetically*
%
% colorbar adds a colorbar to the current axes.
% when resizing or zooming, this
% colorbar will remain correct. The contents
% of the colorbar can be, but are not
% required to be linked to the axes'
% contents.
% coltitles Adds column titles above/below every column
% disable_interaxes Disables the interaxes functionality
% disable_subplotzoom Disable the subplot zoom buttons
% enable_interaxes Enable the interaxes functionality in which the
% axes become clickable (implemented for
% 'line','surface' and 'image' graphical objects)
% enable_subplotzoom Enable the subplot zoom buttons
% extract_axes Creates a new figure from one of the
% axes.
% figplace Locate the figure somewhere on a grid
% covering the screen(s). calling
% FIGPLACE without parameters maximizes
% the figure window.
% figtitle Adds a figure title above the subplots
% hide_axes Hides an axes (by default all subplots are
% generated
% hide_empty_axes Hides all axes which do not contain any graphical
% content/objects.
% legend creates a legend without connection to content.
% overwrite_interaxes_selection_mods
% Overwrites the default selection modifications
% per axes.
% redraw Redraws the subplot_grid figure. This
% realigns and resets axes, legends and
% colorbars
% remove_legend Removes the legends from one or multiple
% subplots
% rowtitles Adds row titles to the left/right of every row.
% set_gca Set the actual axis as current axes for that
% figure
% set_padding resets the padding space around the
% axes in pixels (default = 5px)
% show_axes Shows an axes which has been hidden before.
% subfigtitle Adds a subtitle to the figure.
% sync_axes Will synchronize one or more axes
% (i.e., x, y and/or color axes).
% Zooming within an axes will keep the
% same axes.
% zoomlink_axes Link axes on zooming in via
% subplotzoom.
%
%
% SYNTAX:
% obj = subplot_grid(varargin)
%
%
% PROPERTIES:
%
% Can be asked via 'properties(hsg)' or via the generic structured
% object hierarchy: typing 'hsg' in the command-window will show all
% properties. (of course only when you've named your subplot_grid
% object 'hsg', otherwise use your subplot_grid variable/object
% name).
%
%
% OUTPUT PARAMETER:
% Object of type 'subplot_grid'
%
% VERSION:
% 6.0
%
% FUTURE WORK:
%
% KNOWN LIMITATIONS:
% 20120203 : (joris) The MATLAB function PLOTYY does not work
% correctly with subplot_grid, because of the
% fact that PLOTYY uses two overlaying
% axes; one with an y-axis on the left,
% and one with an y-axes on the right.
%
% ABOUT:
% Birthdate: december 6, 2010
% Authors: Joris Kampman/Benno Schl�nsen/Dan Kominsky
%% MODIFICATIONS:
% <pre release>
% 20101206 : (Joris) Fixed a bug in the ordering of row and column
% titles in the subfunction 'subplot_resize_fcn'.
% 20101208 : (Joris) Fixed a bug regarding the resizing of plots that
% have colorbars.
% 20101210 : (Benno) Modified the function to class, and
% added subplotzoom functionality.
% 20101213 : (Joris) Modified and cleaned up class code.
% 20101213 : (Joris) Fixed bug in resizing while zoomed-out.
% 20101214 : (Joris) Added 'extract_axes' function which creates a new
% figure in which the wanted axes contents are copied.
% 20101218 : (Joris) Added 'interaxes' function which enables the use of
% the mouse click and arrow buttons for navigation
% through the axis. To be set.
% 20101218 : (Joris) Fixed a bug regarding the placement after addition
% of row titles.
% 20101222 : (Joris) Some minor bugfixes and addition of the maintainance
% of the interaxes function after the
% 'extract_subplot' command.
% <<==== version 1.0 created ====>>
% 20110103 : (Joris) Bugfix: interaxes functionality did not correctly
% function after 'extract_axes' method.
% 20110103 : (Joris) Bugfix: method 'disable_interaxes' gave errors
% <<=== version 1.1 created ===>>
% 20110104 : (Joris) Bugfix: resizing with no row and/or column titles
% gave an error.
% <<=== version 1.2 created ==>>
% 20110106 : (Joris) Added the moving to the top of the plot object stack
% when zoomed via subplotzoom.
% 20110106 : (Joris) Bugfix: adding column titles when Nr != Nc crashed
% <<=== version 1.3 created ==>>
% 20110118 : (Joris) Naming update: changed property 'hax_subplots' to 'hax'.
% Naming update: changed method 'set_actual_subplot'
% to 'set_gca'
% <<=== version 1.4 created ===>>
% 20110201 : (Joris) Added methods 'show_axes' and 'hide_axes', which
% control the visibility of any of the subplot axes
% created by default at instantiation of this class.
% <<=== version 1.5 created ==>>
% 20110201 : (Joris) Bugfix: when using 'hide_axes' and zooming via the
% subplotzoom callback. On zooming back out to the
% orginal axes position, the hidden axes appears. This
% is fixed.
% <<=== version 1.6 created ==>>
% 20110203 : (Joris) Adding the method 'hide_empty_axes' which hide all
% axes that do not contain any graphical objects.
% 20110207 : (Joris) Added the possibility to use a subplot index instead
% of only the row and column indices. Numbering is
% equal to the matlab SUBPLOT function indexing.
% 20110207 : (Joris) Added the possibility for most methods to give a
% set of axes as parameters which will be looped.
% 20110207 : (Joris) Bugfix: disabling and enabling INTERAXES for a set
% of axes did not function properly.
% 20110207 : (Joris) Added the possibility to enable and disable
% SUBPLOTZOOM for a subset of all axes.
% subset of axes.
% 20110207 : (Joris) Added help data for all methods
% <<=== version 2.0 created ===>>
% 20110214 : (Joris) Modified subplot_grid to function correctly during
% saving and loading the figure. A function
% 'reset_handles' is added. When loading, and the
% resize function cannot find the handles specifies,
% it calls this reset_handles function
% 20110310 : (Joris) Added the 'viewer' mode. This is a major subplot and
% a row of minor subplots. Easy to use for one
% combined plot, and several individual plots.
% 20110310 : (Joris) Added the possibility for single-parameter usage.
% This calculates the number of rows and columns itself.
% <<=== version 3.0 created ===>>
% 20110526 : (Joris) Added the possibility to add a subtitle to the
% figure.
% 20110804 : (Joris) Added the methods ROWTITLES and COLTITLES for a more
% intuitive feel, since there are multiple rows and
% columns which are to be titled.
% 20111130 : (Joris) Added the possibility to add a fixed legend
% (predefined), not necessarily related to actual
% content. Use method LEGEND to create this. Re
% locating can be done with the method PLACE_LEGEND
% <<=== version 4.0 created ===>>
% 20111206 : (Joris) Added the possibility to place a legend 'outside'
% the axes and auto-scaling the axes. Resizing and
% zooming functions work also for legends placed
% outside the axes.
% 20111206 : (Joris) Added the methods RELOCATE_LEGEND and REMOVE_LEGEND
% in this class. See their respective help functions
% for more information on syntax.
% <<=== version 4.1 created ===>>
% 20111208 : (Joris) Set 'LooseInset' property of all axes to a fixed
% width. See property 'loose_inset_px' for the values.
% 20111213 : (Joris) Cleaned up code, and fixed some warnings. In the
% process fixed some small bugs (although there are
% without a doubt some left).
% 20111213 : (Joris) Extended the demo (call SUBPLOT_GRID) to incorporate
% some zooming, legend creation and interaxes
% functionality.
% <<=== version 4.2 created ===>>
% 20111219 : (Joris) Extended the LEGEND method to be able to handle
% all plot properties. See help of LEGEND method for
% more information.
% <<=== version 4.3 created ===>>
% 20120101 : (Joris) in the LEGEND method, changed the number of markers
% from 3 to a single marker in the centre of the line,
% to mimic the MATLAB-style legend
% 20120117 : (Benno) Added x_sync_axes to synchronise axes x.
% TODO: - Link Y, link both, unlink
% - Add consistency checks
% 20120302 : (Joris) Bugfix in the placement of the legend
% using SUBPLOTZOOM to enlarge and
% contract again.
% 20120302 : (Joris) Added functionality to correctly handle
% the deletion/closing of axes or clearing
% the figure. Also on resizing.
% 20120302 : (Joris) Bugfix in the zooming of an axes with legends on other
% axes. The axes with legends did not recover correctly
% 20120302 : (Joris) Added COLORBAR method to add a colorbar
% with the same inputs as the normal
% MATLAB colorbar function.
% 20120302 : (Joris) Added method SET_PADDING which allows
% control over the amount of whitespace
% between axes (Default: [5,5,5,5] pixels)
% <<=== version 4.4 created ===>>
% 20121118 : (Joris) Added a second VARARGIN parameter with which
% axes can be linked on zooming in.
% 20121118 : (Joris) Added the method ZOOMLINK_AXES with
% which axes can be linked on zooming in.
% <<=== version 4.5 created ===>>
% 20121120 : (Joris) Debugged the use of linked axes in
% combination with merged axes and a
% legend.
% <<=== version 4.6 beta created ===>>
% 20130423 : (Dan) Improved the 'set_zoom_button_position' to
% significantly improve speeds (by approx.
% 22 percent).
% 20130429 : (Joris/Dan)
% Because of the number of properties, all
% varargin parameters are changed to
% property-value pairs.
% 20130430 : (Joris) Rewritten the help function completely.
% 20130430 : (Joris) Implemented 'viewer' mode in demo
% 20130430 : (Joris) Added use of 'parent' property in demo
% 20130715 : (Joris) Added method REDRAW to reset or redraw
% legends, colorbars and titles.
% 20130716 : (Joris) Added method FIGPLACE with which the
% figure can be placed in a grid of
% figures.
% 20130713 : (Joris) Added method SYNC_AXES with which the
% axes of multiple axes can be
% synchronized based on the content.
% <<=== version 4.7 created ===>>
% 20130719 : (Joris) Modified the SYNC_AXES method to
% include padding percentages.
% 20131014 : (Joris) Modified ZOOMLINK_AXES method to keep the
% current relative vertical sizes of the
% linked axes
% 20140525 : (Joris) Added property SUBPLOTZOOM_INIT_STATE
% used to either force subplotzoom to be
% enabled or disabled at startup
% 20140627 : (Joris) Added input property 'no_zoom' to
% disable all subplotzoom buttons and
% actions. Makes for nicer prints.
% 20140627 : (Joris) Removed X_SYNC_AXES. Has been superseded
% by the more generic SYNC_AXES
% <<=== version 4.8 created ===>>
% 20140627 : (Joris) calling REDRAW after adding texts
% 201...... NO SCORE KEPT ANYMORE!
%
%% initialization
%%------------------------------------------------------------------------
if nargin == 0 || strcmpi(varargin{1},'demo'), % demo
this.demo
return
end
this.hfig = gcf;
set(this.hfig,'Toolbar','figure'); % set toolbar to figure
this.hparent = this.hfig;
if isequal('double',class(this.hfig)),
this.hgVersion = 1;
else
this.hgVersion = 2;
end
%% exception one: viewer mode!
if strcmpi(varargin{1},'viewer'), % if: viewer mode
nof_figures = varargin{2};
valid_modes = {'bottom','top','left','right'};
mode = 'bottom'; % options: top, left,bottom, right... indicates the position of the list of smaller plots
nof_minor_rows = 1;
if nargin > 2,
if ischar(varargin{3}),
% check if it contains a mode or another input parameter
imode = find(strcmpi(valid_modes,varargin{3}));
if any(imode),
mode = varargin{3};
% check if the number of minor rows is given
if nargin > 3,
if ~ischar(varargin{4}),
nof_minor_rows = varargin{4};
end
end
end
end
end
%% find input parameters
if any(strcmpi('mergelist',varargin)),
imergelist = 1 + find(strcmpi('mergelist',varargin));
if iscell(varargin{imergelist}),
this.mergelist = varargin{imergelist};
else
error('The provided ''mergelist'' is not a cell array');
end
else
this.mergelist = {};
end
if any(strcmpi('zoomlinklist',varargin)),
izoomlinklist = 1 + find(strcmpi('zoomlinklist',varargin));
if iscell(varargin{izoomlinklist}),
this.zoomlinklist = varargin{izoomlinklist};
else
error('The provided ''zoomlinklist'' is not a cell array');
end
else
this.zoomlinklist = {};
end
if any(strcmpi('parent',varargin)),
iparent = 1 + find(strcmpi('parent',varargin));
if ishandle(varargin{iparent}),
this.hparent = varargin{iparent};
this.in_panel = true;
else
error('The provided ''parent'' is not a handle!');
end
end
if any(strcmpi('no_zoom',varargin)),
this.subplotzoom_init_state = false;
end
this.viewer.nof_minor_rows = nof_minor_rows;
nof_major_rows = 5;
nr = nof_minor_rows + nof_major_rows;
nc = ceil(nof_figures/nof_minor_rows);
switch mode
case 'bottom',
this.mergelist = {[1,nof_major_rows*nc]};
this.viewer.starting_index = nof_major_rows*nc + 1;
case 'top',
this.mergelist = {[nof_minor_rows*nc+1,nr*nc]};
this.viewer.starting_index = 1;
otherwise
this.mergelist = {[1,nof_major_rows*nc]};
this.viewer.starting_index = nof_major_rows*nc + 1;
end % switch: mode
%% normal mode (not 'viewer')
else % not in viewer mode
%% handle inputs
if nargin == 1 || (ischar(varargin{2}) || iscell(varargin{2})), % 1 or 2 first are scalars, if string then property
nc = round(ceil(2*sqrt(varargin{1}))/2);
nr = round(floor(2*sqrt(varargin{1}))/2);
else
nr = varargin{1};
nc = varargin{2};
end
% option 1: mergelist
% Check for old calling syntax:
cellInputs = find(cellfun(@iscell,varargin));
for iCell = cellInputs
if ~ischar(varargin{iCell-1}) || ~(any(strcmpi(varargin{iCell-1},{'mergelist','parent','zoomlinklist','no_zoom'})))
error('subplot_grid:oldSyntax','Subplot_grid has been called with an obsolete syntax');
end
end
%% find input parameters
if any(strcmpi('mergelist',varargin)),
imergelist = 1 + find(strcmpi('mergelist',varargin));
if iscell(varargin{imergelist}),
this.mergelist = varargin{imergelist};
else
error('The provided ''mergelist'' is not a cell array');
end
else
this.mergelist = {};
end
if any(strcmpi('zoomlinklist',varargin)),
izoomlinklist = 1 + find(strcmpi('zoomlinklist',varargin));
if iscell(varargin{izoomlinklist}),
this.zoomlinklist = varargin{izoomlinklist};
else
error('The provided ''zoomlinklist'' is not a cell array');
end
else
this.zoomlinklist = {};
end
if any(strcmpi('parent',varargin)),
iparent = 1 + find(strcmpi('parent',varargin));
if ishandle(varargin{iparent}),
this.hparent = varargin{iparent};
this.in_panel = true;
else
error('The provided ''parent'' is not a handle!');
end
end
if any(strcmpi('no_zoom',varargin)),
this.subplotzoom_init_state = false;
end
end % ifelse: viewer mode or not??
%% create axes
this.nof_rows = nr;
this.nof_columns = nc;
this.hlegend = nan(nr,nc);
this.hcolorbar = nan(nr,nc);
this.hidden_axes = false(nr,nc);
this.hidden_axes_manual = false(nr,nc);
this.zoomed = false(nr,nc);
boxheight = 1/nr;
boxwidth = 1/nc;
this.hax = zeros(nr,nc);
this.Iax = this.hax;
legnames = fieldnames(this.legend_data_defaults);
cbnames = fieldnames(this.colorbar_data_defaults);
for ir = 1:nr, % all rows
for ic = 1:nc, % al columns
%% create axes
position = [((ic - 1)*boxwidth) ((nr - ir)*boxheight) boxwidth boxheight];
this.hax(ir,ic) = axes('Parent',this.hparent,...
'Units','normalized',...
'OuterPosition',position,...
'Tag',sprintf('hax_%d_%d',ir,ic));
set(this.hax(ir,ic),'Units','pixels','LooseInset',this.loose_inset_px); % set loose inset
%% save misc properties
this.Iax(ir,ic) = sub2ind(size(this.hax.'),ic,ir);
this.Rax(ir,ic) = ir;
this.Cax(ir,ic) = ic;
%% zoomed flag (set to false)
this.zoomed(ir,ic) = false; % init: not zoomed in of course
%% init interaxes grid
this.interaxes_data(ir,ic).valid = false;
this.interaxes_data(ir,ic).selected_object_handle = nan;
this.interaxes_data(ir,ic).selected_object_props = [];
this.interaxes_data(ir,ic).local_selection_mods = this.interaxes_selection_mods;
%% Create subplot zoom buttons and prepare subplot zoom data
this.subplotzoom_data(ir,ic).zm_btn = uicontrol(this.hparent,...
'style','push',...
'tag',sprintf('subplotzoom_%d_%d',ir,ic),...
'units','pixels',...
'string','+',...
'fontsize',6,...
'Interruptible','off',...
'callback',@(src, event)subplotzoom_cb(this,ir,ic));
this.subplotzoom_enabled(ir,ic) = this.subplotzoom_init_state; % 1 => with suplot zoom, 0 => without subplot zoom
this.set_zoom_button_position(ir,ic); % set positions in axes (upper right corner)
% init legend data to nan
for ilegn = 1:numel(legnames),
this.legend_data(ir,ic).(legnames{ilegn}) = this.legend_data_defaults.(legnames{ilegn});
end
% init colorbar data tot nan
for icbn = 1:numel(cbnames),
this.colorbar_data(ir,ic).(cbnames{icbn}) = this.colorbar_data_defaults.(cbnames{icbn});
end
% find axes it's linked to
index = sub2ind([nc,nr],ic,ir);
this.subplotzoom_data(ir,ic).zoomlinked_with = index;
for icell = 1:numel(this.zoomlinklist),
if ismember(index,this.zoomlinklist{icell}),
this.subplotzoom_data(ir,ic).zoomlinked_with = this.zoomlinklist{icell};
end
end % for: all in zoomlinklist
end % for: all columns
end % for: all rows
%% merge axes
%%------------------------------------------------------------------------
if ~isempty(this.mergelist),
if ~iscell(this.mergelist),
this.mergelist = {this.mergelist};
end
nof_combs = numel(this.mergelist);
for icomb = 1:nof_combs,
sp2merge = this.mergelist{icomb};
[ic,ir] = ind2sub([nc,nr],sp2merge);
leftpos = get(this.hax(min(ir),min(ic)),'OuterPosition');
rightpos = get(this.hax(max(ir),max(ic)),'OuterPosition');
mergepos = [leftpos(1),...
rightpos(2),...
rightpos(1) + rightpos(3) - leftpos(1),...
leftpos(2) + leftpos(4) - rightpos(2)];
% remove redundant subplots including reduncant subplot
% zoom buttons and data
for rrem = (min(ir)):1:max(ir),
for crem = (min(ic)):1:max(ic),
if rrem > min(ir) || crem > min(ic),
delete(this.hax(rrem,crem)); % delete axis
delete(this.subplotzoom_data(rrem,crem).zm_btn) % delete subplotzoom button
this.subplotzoom_data(rrem,crem) = this.subplotzoom_data(min(ir),min(ic)); % delete subplotzoom_data
clear this.subplotzoom_data(rrem,crem);
this.hax(rrem,crem) = this.hax(min(ir),min(ic));
this.Iax(rrem,crem) = this.Iax(min(ir),min(ic));
this.Rax(rrem,crem) = this.Rax(max(ir),max(ic));
this.Rax(ir,ic) = this.Rax(max(ir),max(ic));
this.Cax(rrem,crem) = this.Cax(min(ir),min(ic));
end
end
end
set(this.hax(min(ir),min(ic)),'OuterPosition',mergepos,'ActivePositionProperty','OuterPosition');
set(this.hax(min(ir),min(ic)),'Units','pixels','LooseInset',this.loose_inset_px);
set(this.hax(min(ir),min(ic)),'Units','normalized');
end % for: all combinations
end
if ~this.subplotzoom_enabled,
this.disable_subplotzoom;
end
%% Resizing function (if present)
%%------------------------------------------------------------------------
pause(0.1);
set(this.hfig,'ResizeFcn',@(src,evt)this.reposition_content);
% this.hfig.SizeChangeFcn = this.reposition_content
% set(this.hfig,'SizeChangeFcn',@this.reposition_content);
set(this.hax(:),'DeleteFcn',@this.delete_axes);
this.set_gca(1,1);
set(this.hfig,'Units','pixels');
set(this.hparent,'Units','pixels');
figpos = get(this.hfig,'Position');
parpos = get(this.hparent,'Position');
if this.in_panel,
this.pos_parent_in_figure = [parpos(1)/figpos(3),parpos(2)/figpos(4),parpos(3)/figpos(3),parpos(4)/figpos(4)];
else
this.pos_parent_in_figure = [0 0 1 1];
end
this.reposition_content;
this.set_gca(1,1);
end % fcn: constructor
function figtitle(this, titlestring,varargin)
%
% FIGTITLE adds a - multi-row - title for the entire figure. The
% extension of the title to multiple rows is done via the use of a
% cell array of strings. The text properties may be altered by the
% normal properties as VARARGIN parameters
%
% SYNTAX:
% <obj>.figtitle(titlestring,VARARGIN);
%
% INPUT PARAMETER:
% titlestring A string or a cell array of strings containing the
% text to use as the figure title.
%
% VARARGIN PARAMETERS:
% The varargin parameters can be used to set the text properties of
% the figure title. The VARARGIN parameters come in pairs:
% 'property_name' and 'property_value'. An extensive list can thus
% be created.
%
set(0,'CurrentFigure',this.hfig);
if isempty(titlestring),
if this.titles.title.valid,
delete(this.titles.title.hax);
this.titles.title = this.titles.template;
end
this.reposition_content;
return
end
if ~iscell(titlestring),
titlestring = {titlestring};
end
%% undo zooming (temporarily)
[irzoomed,iczoomed] = find(this.zoomed == 1);
if any(irzoomed),
this.subplotzoom_cb(irzoomed(1),iczoomed(1));
end
%% row and coltitle dimensions
%--------------------------------------------------------------
% delete existing figure title
if this.titles.title.valid,
delete(this.titles.title.hax);
end
%% create figure title axes and text box
%%----------------------------------------------------------------------
% AXES
hax_figtitle = axes('Parent',this.hparent,...
'Units','normalized',...
'Position',[0 0 1 1],...
'Tag','figtitle',...
'Visible','off',...
'XTick',[],...
'YTick',[],...
'Box','off');
% TEXTBOX
htext_figtitle = text(0.5,0.5,'',...
'Units','normalized',...
'HorizontalAlignment','center',...
'VerticalAlignment','middle',...
'LineStyle','none',...
'EdgeColor',[0 1 0],...
'Tag','figtitle',...
'FontWeight','bold',...
'FontSize',12);
% VARARGIN (text properties)
if nargin > 2,
for iarg = 2:2:nargin-1,
set(htext_figtitle,varargin{iarg-1},varargin{iarg});
end
end
% text in textbox
set(htext_figtitle,'String',titlestring,'Units','pixels');
pos = get(htext_figtitle,'Extent');
set(htext_figtitle,'Units','normalized');
this.titles.title = struct('valid',true,...
'hax',hax_figtitle,...
'htxt',htext_figtitle,...
'txtbox_sizes',pos(4),...
'ratios',[]);
%% reposition everything
this.reposition_content
end % fcn
function subfigtitle(this, titlestring, varargin)
%
% SUBFIGTITLE adds a - multi-row - SUBtitle for the entire figure. The
% extension of the title to multiple rows is done via the use of a
% cell array of strings. The text properties may be altered by the
% normal properties as VARARGIN parameters
%
% SYNTAX:
% <obj>.subfigtitle(titlestring,VARARGIN);
%
% INPUT PARAMETER:
% titlestring A string or a cell array of strings containing the
% text to use as the figure title.
%
% VARARGIN PARAMETERS:
% The varargin parameters can be used to set the text properties of
% the figure title. The VARARGIN parameters come in pairs:
% 'property_name' and 'property_value'. An extensive list can thus
% be created.
%
set(0,'CurrentFigure',this.hfig);
if isempty(titlestring),
if this.titles.subtitle.valid,
delete(this.titles.subtitle.hax);
this.titles.subtitle = this.titles.template;
end
this.reposition_content;
return
end
if ~iscell(titlestring),
titlestring = {titlestring};
end
%% undo zooming (temporarily)
[irzoomed,iczoomed] = find(this.zoomed == 1);
if any(irzoomed),
this.subplotzoom_cb(irzoomed(1),iczoomed(1));
end
if this.titles.subtitle.valid,
delete(this.titles.subtitle.hax);
end
%% (re)create figure title axes and text box
%%----------------------------------------------------------------------
% AXES
hax_subfigtitle = axes('Parent',this.hparent,...
'Units','normalized',...
'Position',[0 0 1 1],...
'Tag','subfigtitle',...
'Visible','off',...
'XTick',[],...
'YTick',[],...
'Box','off');
% TEXTBOX
htext_subfigtitle = text(0.5,0.5,'',...
'Units','normalized',...
'HorizontalAlignment','center',...
'VerticalAlignment','middle',...
'LineStyle','none',...
'EdgeColor',[0 1 0],...
'Tag','subfigtitle',...
'FontWeight','bold',...
'FontSize',10);
% VARARGIN
if nargin > 2,
for iarg = 2:2:nargin-1,
set(htext_subfigtitle,varargin{iarg-1},varargin{iarg});
end
end
% text in textbox
set(htext_subfigtitle,'String',titlestring,'Units','pixels');
pos = get(htext_subfigtitle,'Extent');
set(htext_subfigtitle,'Units','normalized');
this.titles.subtitle = struct('valid',true,...
'hax',hax_subfigtitle,...
'htxt',htext_subfigtitle,...
'txtbox_sizes',pos(4),...
'ratios',[]);
this.reposition_content;
end % fcn
function rowtitles(this,rowstring,varargin)
%
% ROWTITLES adds vertically aligned texts on the left or the right side of the window.
%
% obj.rowtitles(C) adds the texts in cell array C to the left (=default) side of the
% figure window, evenly spaced to span the entire available length. The number of
% elements in C does NOT have to be equal to the number of axes or such. These are not
% connected. The cell array C can hold multi-line texts in case an element of C is
% itself a cell array.
%
% obj.rowtitles(C,R) will use the vector R to determine the relative sizes of the
% titles. Default R = ones(number of elements,1).
%
% obj.rowtitles(C,loc,...) will place the row titles on the side given by 'loc' and
% can hold two options: 'left' or 'right'
%
% obj.rowtitles(C,...,VARARGIN) uses the standard text property name/value pairs to
% modify the text properties.
%
% obj.rowtitles([]) will remove all row titles on both sides and expands the axes again to
% fill the empty space.
%
% EXAMPLE:
%
% obj.rowtitles({'first',{'second.1','second.2'},'third'},'right',[1 2 1])
%
% this example will plot three row titles of which the second consists of two lines.
%
% the second parameter 'right' ensures the row titles to be on the right side of the
% window.
%
% The third parameter [1 2 1] ensures that the size of the texts has the ratio
% 1:2:1. That is, the second texts is twice the size of the other two texts.
%
% VARARGIN PARAMETERS:
%
% The varargin parameters can be used to set the text properties of the row
% titles.
%
set(0,'CurrentFigure',this.hfig);
location = 'left'; % default
%% gather titles dimensions
%%-------------------------------------------------------------------
%% process empty input
if isempty(rowstring),
if this.titles.rowtitles_left.valid,
delete(this.titles.rowtitles_left.hax);
this.titles.rowtitles_left = this.titles.template;
end
if this.titles.rowtitles_right.valid,
delete(this.titles.rowtitles_right.hax);
this.titles.rowtitles_right = this.titles.template;
end
this.reposition_content;
return
end
%% handle input parameters
if ~iscell(rowstring),
rowstring = {rowstring};
end
nof_rowtitles = numel(rowstring);
nvargin = numel(varargin);
argos = 0;
size_ratios = ones(1,nof_rowtitles);
valid_positions = {'left','right'};
if nargin > 2,
if any(find(strcmpi(varargin{1},valid_positions))),
location = varargin{1};
argos = 1;
if nargin > 3,
if ~ischar(varargin{2}),
argos = 2;
size_ratios = varargin{2};
end
end
elseif ~ischar(varargin{1}),
argos = 1;