1
+ function plotHandleList = gui_slow_plot(axesHandleArray , mode , offsetPercent , pauseTime , XCell , YCell )
2
+ % GUI_SLOW_PLOT Plot slowly.
3
+ %
4
+ % Plot vector XCell against vector YCell slowly.
5
+ % Plot vectors XCell{i} against vectors YCell{i} slowly.
6
+ %
7
+ %
8
+ % Arguments:
9
+ % axesHandleArray: A scalar or vector of handles to axes objects.
10
+ %
11
+ % mode: One of the following:
12
+ % 'one axis': Everything will be plotted on one axis.
13
+ % 'multiple axes': Each data line will be plotted on
14
+ % a different axis. In this mode, the number of elements
15
+ % in axesHandleArray, XCell and YCell must be equal.
16
+ %
17
+ % pauseTime: Time in seconds to pause between updates in plot.
18
+ % This, along with number of elements in the data lines,
19
+ % determine the time it takes for the function to execute.
20
+ %
21
+ % offsetPercent: Float specifying percentage of empty space between
22
+ % highest/lowest value and the boundary of axes.
23
+ % To not resize axes, set offsetPercent to -1.
24
+ %
25
+ % XCell: A Cell array of vectors that act as the horizontal data
26
+ % on the plot. Can also be a single vector.
27
+ %
28
+ % YCell: A Cell array of vectors that act as the horizontal data
29
+ % on the plot. Can also be a single vector.
30
+ %
31
+ % XCell and YCell must have the same length.
32
+ % Also, for each i, XCell{i} and YCell{i} must be of the same length.
33
+ %
34
+ % Note: This function uses the "gui_resize_axis.m" function by
35
+ % Mohammadreza Khoshbin which can be downloaded from:
36
+ % https://github.com/k4vosh/gui_tools
37
+ %
38
+ % See also: PLOT, EZPLOT, PLOT3, TITLE, XLABEL, YLABEL, HOLD, LEGEND.
39
+ %
40
+ % plotHandleList = GUI_SLOW_PLOT(axesHandleArray, mode, pauseTime, XCell, YCell)
41
+ %
42
+ % Copyright (c) 2016 Mohammadreza Khoshbin
43
+
44
+ % #ok<*FORPF>
45
+
46
+ %% Validate input.
47
+ % Validate variable: axesHandleArray
48
+ validateattributes(axesHandleArray , {' numeric' }, {' vector' })
49
+ if ~all( ishandle(axesHandleArray ))
50
+ error(' Some of graphic handles are invalid.' )
51
+ end
52
+
53
+ % Validate variable: mode
54
+ if ~(strcmpi(mode , ' one axis' )||strcmpi(mode , ' multiple axes' ))
55
+ error(' Unexpected value for mode. Valid values are "one axis" and "multiple axes".' )
56
+ end
57
+
58
+ % Validate variable: offsetPercent
59
+ validateattributes(offsetPercent , {' numeric' }, {' scalar' , ' <=' , 20 , ' >=' , - 1 })
60
+ if ~any( exist(' gui_resize_axis' ) == [2 6 ]) % #ok<EXIST>
61
+ offsetPercent = - 1 ;
62
+ elseif offsetPercent == 0
63
+ offsetPercent = - 1 ;
64
+ end
65
+
66
+ % Validate variable: pauseTime
67
+ validateattributes(pauseTime , {' numeric' }, {' scalar' })
68
+
69
+ % Validate variable: XCell
70
+ validateattributes(XCell , {' cell' , ' numeric' }, {' vector' })
71
+ if isnumeric(XCell ) % There is only one vector.
72
+ XCell = {XCell };
73
+ end
74
+ if ~all(cellfun(@isvector , XCell ))
75
+ error(' At least one member of XCell is not a vector.' )
76
+ end
77
+
78
+ % Validate variable: YCell
79
+ validateattributes(YCell , {' cell' , ' numeric' }, {' vector' })
80
+ if isnumeric(YCell ) % There is only one vector.
81
+ YCell = {YCell };
82
+ end
83
+ if ~all(cellfun(@isvector , YCell ))
84
+ error(' At least one member of YCell is not a vector.' )
85
+ end
86
+
87
+ % Co-Validating variables: XCell, YCell
88
+ XCellLength = cellfun(@length , XCell );
89
+ YCellLength = cellfun(@length , YCell );
90
+ if ~all(XCellLength == YCellLength )
91
+ error(' At least two (Xn, Yn) vectors have different lengths.' )
92
+ end
93
+ if numel(XCell ) ~= numel(YCell )
94
+ error(' XCell and YCell have different lengths.' )
95
+ end
96
+ dataLinesLength = XCellLength ;
97
+ clear XCellLength YCellLength
98
+
99
+ % Co-Validating variables: mode, axesHandleArray
100
+ if strcmpi(mode , ' one axis' ) && numel(axesHandleArray ) ~= 1
101
+ error(' gui_slow_plot is set to operate in "one axis" mode but axesHandleArray contains more than one element.' )
102
+ elseif strcmpi(mode , ' multiple axes' ) && numel(axesHandleArray ) ~= numel(XCell )
103
+ error(' gui_slow_plot is set to operate in "multiple axes" mode but axesHandleArray, XCell and YCell have different lengths.' )
104
+ end
105
+ if strcmpi(mode , ' one axis' ) && numel(axesHandleArray ) ~= 1
106
+ % Everything will be plotted on a single axis.
107
+ axesHandleArray = repmat(axesHandleArray , [numel(XCell ),1 ]);
108
+ end
109
+
110
+ %% hold and resize all axes.
111
+ holdStatus = zeros(size(axesHandleArray ));
112
+ for i= 1 : numel(axesHandleArray )
113
+ % Record hold status and hold all axes.
114
+ holdStatus(i ) = ishold(axesHandleArray );
115
+ hold(axesHandleArray(i ), ' on' );
116
+ if offsetPercent ~= - 1 % Resize all axes so their data fits.
117
+ gui_resize_axis(axesHandleArray(i ), offsetPercent , XCell{i }, YCell{i } )
118
+ end
119
+ end
120
+
121
+ %% plot each dataLine in steps.
122
+ handleList{1 , numel(XCell )} = [];
123
+ for i = 1 : max(dataLinesLength )
124
+ for cellId= 1 : numel(XCell )
125
+ try
126
+ handleList{cellId }(i ) = plot(axesHandleArray(cellId ), XCell{cellId }(i ),YCell{cellId }(i ));
127
+ catch ME
128
+ % Ignore badsubscript errors. They only mean that this is not
129
+ % the biggest dataLine.
130
+ if ~strcmp(ME .identifier , ' MATLAB:badsubscript' )
131
+ rethrow(ME )
132
+ end
133
+ end
134
+ end
135
+ pause(pauseTime );
136
+ end
137
+
138
+ %% delete old dataLines and plot them completely.
139
+ plotHandleList = - 1 * ones(numel(XCell ));
140
+ for cellId= 1 : numel(XCell )
141
+ plotHandleList(cellId ) = plot(axesHandleArray(cellId ), XCell{cellId }, YCell{cellId });
142
+ delete(handleList{cellId });
143
+ end
144
+ assert( all(plotHandleList ~= - 1 ) )
145
+
146
+ %% reset hold status of axes.
147
+ for i= 1 : numel(axesHandleArray ) % All axes are held now,
148
+ if ~holdStatus(i ) % but some were not held before the function.
149
+ try
150
+ set(axesHandleArray(i ),' NextPlot' ,' replace' )
151
+ catch
152
+ if ~strcmp(ME .identifier , ' MATLAB:class:InvalidProperty' )
153
+ rethrow(ME )
154
+ else
155
+ hold(axesHandleArray(i ), ' off' );
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162
+ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163
+ % The MIT License (MIT)
164
+ %
165
+ % Copyright (c) 2016 Mohammadreza Khoshbin
166
+ %
167
+ % Permission is hereby granted, free of charge, to any person obtaining a copy
168
+ % of this software and associated documentation files (the "Software"), to deal
169
+ % in the Software without restriction, including without limitation the rights
170
+ % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
171
+ % copies of the Software, and to permit persons to whom the Software is
172
+ % furnished to do so, subject to the following conditions:
173
+ %
174
+ % The above copyright notice and this permission notice shall be included in all
175
+ % copies or substantial portions of the Software.
176
+ %
177
+ % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178
+ % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
179
+ % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
180
+ % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
181
+ % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
182
+ % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
183
+ % SOFTWARE.
184
+ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185
+ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0 commit comments