Mercurial > octave-nkf
comparison scripts/plot/private/__stem__.m @ 17432:77bec442a35a
Overhaul stem family of plot functions.
* scripts/plot/private/__stem__.m: Use low-level plotting fcn __line__
for performance. Add property/listener on 'basevalue' for baseline object.
Simplify and correct input option processing so that it actually does
the right thing.
* scripts/plot/stem.m: Add list of "stem series" properties to docstring.
Add titles to %!demos. Add %!error tests for input validation.
* scripts/plot/stem3.m: Cross-reference "stem series" to stem documentation.
Accept property/value pair inputs. Add %!error tests for input validation.
author | Rik <rik@octave.org> |
---|---|
date | Wed, 18 Sep 2013 10:32:27 -0700 |
parents | 366a51191fd7 |
children | 177147bf7b55 |
comparison
equal
deleted
inserted
replaced
17431:1dfc3abb0f0d | 17432:77bec442a35a |
---|---|
33 endif | 33 endif |
34 | 34 |
35 [hax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:}); | 35 [hax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:}); |
36 | 36 |
37 [x, y, z, dofill, llc, ls, mmc, ms, varargin] = ... | 37 [x, y, z, dofill, llc, ls, mmc, ms, varargin] = ... |
38 check_stem_arg (have_z, varargin{:}); | 38 check_stem_arg (have_z, varargin{:}); |
39 | 39 |
40 oldfig = []; | 40 oldfig = []; |
41 if (! isempty (hax)) | 41 if (! isempty (hax)) |
42 oldfig = get (0, "currentfigure"); | 42 oldfig = get (0, "currentfigure"); |
43 endif | 43 endif |
61 xt = [xt; xt; NaN(1, nx)](:); | 61 xt = [xt; xt; NaN(1, nx)](:); |
62 yt = y(:, i)'; | 62 yt = y(:, i)'; |
63 yt = [zeros(1, nx); yt; NaN(1, nx)](:); | 63 yt = [zeros(1, nx); yt; NaN(1, nx)](:); |
64 endif | 64 endif |
65 | 65 |
66 if (isempty (llc)) | |
67 lc = __next_line_color__ (); | |
68 else | |
69 lc = llc; | |
70 endif | |
71 | |
72 if (isempty (mmc)) | |
73 mc = lc; | |
74 else | |
75 mc = mmc; | |
76 endif | |
77 | |
78 if (dofill) | |
79 fc = mc; | |
80 else | |
81 fc = "none"; | |
82 endif | |
83 | |
84 ## Must occur after __next_line_color__ in order to work correctly. | |
66 hg = hggroup (); | 85 hg = hggroup (); |
67 h = [h; hg]; | 86 h = [h; hg]; |
68 args = __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:}); | 87 args = __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:}); |
69 | 88 |
70 if (isempty (llc)) | |
71 lc = __next_line_color__ (); | |
72 else | |
73 lc = llc; | |
74 endif | |
75 | |
76 if (isempty (mmc)) | |
77 mc = lc; | |
78 else | |
79 mc = mmc; | |
80 endif | |
81 | |
82 if (dofill) | |
83 fc = mc; | |
84 else | |
85 fc = "none"; | |
86 endif | |
87 | |
88 if (have_z) | 89 if (have_z) |
89 h_stems = plot3 (hax, xt, yt, zt, "color", lc, "linestyle", ls, | 90 __line__ (hax, xt, yt, zt, "color", lc, "linestyle", ls, "parent", hg); |
90 "parent", hg, x, y, z, "color", mc, | 91 __line__ (hax, x, y, z, "color", mc, "linestyle", "none", |
91 "marker", ms, "linestyle", "none", | 92 "marker", ms, "markerfacecolor", fc, "parent", hg); |
92 "markerfacecolor", fc, "parent", hg); | |
93 | |
94 h_baseline = []; | 93 h_baseline = []; |
95 else | 94 else |
96 h_stems = plot (hax, xt, yt, "color", lc, "linestyle", ls, | 95 __line__ (hax, xt, yt, "color", lc, "linestyle", ls, "parent", hg); |
97 "parent", hg, x(:,i), y(:, i), "color", mc, "marker", | 96 __line__ (hax, x(:,i), y(:, i), "color", mc, "linestyle", "none", |
98 ms, "linestyle", "none", "markerfacecolor", | 97 "marker", ms, "markerfacecolor", fc, "parent", hg); |
99 fc, "parent", hg); | |
100 | |
101 x_axis_range = get (hax, "xlim"); | 98 x_axis_range = get (hax, "xlim"); |
102 h_baseline = line (hax, x_axis_range, [0, 0], "color", [0, 0, 0]); | 99 h_baseline = line (hax, x_axis_range, [0, 0], "color", [0, 0, 0]); |
103 set (h_baseline, "handlevisibility", "off"); | 100 set (h_baseline, "handlevisibility", "off", "xliminclude", "off"); |
104 set (h_baseline, "xliminclude", "off"); | |
105 addlistener (hax, "xlim", @update_xlim); | 101 addlistener (hax, "xlim", @update_xlim); |
106 addlistener (h_baseline, "ydata", @update_baseline); | 102 addproperty ("basevalue", h_baseline, "data", 0); |
107 addlistener (h_baseline, "visible", @update_baseline); | 103 addlistener (h_baseline, "basevalue", {@update_baseline, 0}); |
104 addlistener (h_baseline, "ydata", {@update_baseline, 1}); | |
105 addlistener (h_baseline, "visible", {@update_baseline, 2}); | |
108 endif | 106 endif |
109 | 107 |
110 ## Setup the hggroup and listeners. | 108 ## Setup the hggroup and listeners. |
111 addproperty ("showbaseline", hg, "radio", "{on}|off"); | 109 addproperty ("showbaseline", hg, "radio", "{on}|off"); |
110 addproperty ("baseline", hg, "data", h_baseline); | |
112 addproperty ("basevalue", hg, "data", 0); | 111 addproperty ("basevalue", hg, "data", 0); |
113 addproperty ("baseline", hg, "data", h_baseline); | |
114 | 112 |
115 if (! have_z) | 113 if (! have_z) |
116 addlistener (hg, "showbaseline", @show_baseline); | 114 addlistener (hg, "showbaseline", @show_baseline); |
117 addlistener (hg, "basevalue", @move_baseline); | 115 addlistener (hg, "basevalue", @move_baseline); |
118 endif | 116 endif |
119 | 117 |
120 addproperty ("color", hg, "linecolor", lc); | 118 addproperty ("color", hg, "linecolor", lc); |
119 addproperty ("linestyle", hg, "linelinestyle", ls); | |
121 addproperty ("linewidth", hg, "linelinewidth", 0.5); | 120 addproperty ("linewidth", hg, "linelinewidth", 0.5); |
122 addproperty ("linestyle", hg, "linelinestyle", ls); | |
123 addproperty ("marker", hg, "linemarker", ms); | 121 addproperty ("marker", hg, "linemarker", ms); |
122 addproperty ("markeredgecolor", hg, "linemarkerfacecolor", mc); | |
124 addproperty ("markerfacecolor", hg, "linemarkerfacecolor", fc); | 123 addproperty ("markerfacecolor", hg, "linemarkerfacecolor", fc); |
125 addproperty ("markersize", hg, "linemarkersize", 6); | 124 addproperty ("markersize", hg, "linemarkersize", 6); |
126 | 125 |
127 addlistener (hg, "color", @update_props); | 126 addlistener (hg, "color", @update_props); |
127 addlistener (hg, "linestyle", @update_props); | |
128 addlistener (hg, "linewidth", @update_props); | 128 addlistener (hg, "linewidth", @update_props); |
129 addlistener (hg, "linestyle", @update_props); | |
130 addlistener (hg, "marker", @update_props); | 129 addlistener (hg, "marker", @update_props); |
130 addlistener (hg, "markeredgecolor", @update_props); | |
131 addlistener (hg, "markerfacecolor", @update_props); | 131 addlistener (hg, "markerfacecolor", @update_props); |
132 addlistener (hg, "markersize", @update_props); | 132 addlistener (hg, "markersize", @update_props); |
133 | 133 |
134 addproperty ("xdata", hg, "data", x(:, i)); | 134 addproperty ("xdata", hg, "data", x(:, i)); |
135 addproperty ("ydata", hg, "data", y(:, i)); | 135 addproperty ("ydata", hg, "data", y(:, i)); |
163 endif | 163 endif |
164 end_unwind_protect | 164 end_unwind_protect |
165 | 165 |
166 endfunction | 166 endfunction |
167 | 167 |
168 function [x, y, z, dofill, lc, ls, mc, ms, newargs] = check_stem_arg (have_z, varargin) | 168 function [x, y, z, dofill, lc, ls, mc, ms, args] = check_stem_arg (have_z, varargin) |
169 | |
170 ## FIXME: There seems to be a lot of duplicated code in this function. | |
171 ## It seems like it should be possible to simplify things by | |
172 ## combining some of the nearly identical code sections into | |
173 ## additional subfunctions. | |
174 ## FIXME: The code is so convoluted that certain options, such as "filled", | |
175 ## are not being processed correctly. | |
176 | 169 |
177 if (have_z) | 170 if (have_z) |
178 caller = "stem3"; | 171 caller = "stem3"; |
179 else | 172 else |
180 caller = "stem"; | 173 caller = "stem"; |
181 endif | 174 endif |
182 | 175 nargin = nargin - 1; # account for have_z argument |
183 ## Remove prop/val pairs from data to consider. | 176 |
184 i = 2; | 177 num_numeric = find (cellfun ("isclass", varargin, "char"), 1) - 1; |
185 newargs = {}; | 178 if (isempty (num_numeric)) |
186 while (i < length (varargin)) | 179 num_numeric = nargin; |
187 if (ischar (varargin{i}) && !(strcmpi ("fill", varargin{i}) | 180 endif |
188 || strcmpi ("filled", varargin{i}))) | 181 |
189 newargs{end + 1} = varargin{i}; | 182 if (num_numeric < 1 || num_numeric > 3) |
190 newargs{end + 1} = varargin{i + 1}; | 183 print_usage (caller); |
191 nargin = nargin - 2; | 184 endif |
192 varargin(i:i+1) = []; | 185 |
193 else | 186 x = y = z = []; |
194 i++; | 187 if (num_numeric == 1) |
195 endif | |
196 endwhile | |
197 | |
198 ## set specifiers to default values. | |
199 [lc, ls, mc, ms] = set_default_values (); | |
200 dofill = 0; | |
201 fill_2 = 0; | |
202 linespec_2 = 0; | |
203 z = []; | |
204 | |
205 ## Check input arguments. | |
206 if (nargin == 2) | |
207 if (have_z) | 188 if (have_z) |
208 z = varargin{1}; | 189 z = varargin{1}; |
209 x = 1:rows (z); | |
210 y = 1:columns (z); | |
211 else | 190 else |
212 y = varargin{1}; | 191 y = varargin{1}; |
192 endif | |
193 elseif (num_numeric == 2) | |
194 if (have_z) | |
195 error ("stem3: must define X, Y, and Z"); | |
196 else | |
197 x = varargin{1}; | |
198 y = varargin{2}; | |
199 endif | |
200 else # nun_numeric == 3 | |
201 if (have_z) | |
202 x = varargin{1}; | |
203 y = varargin{2}; | |
204 z = varargin{3}; | |
205 else | |
206 error ("stem: can not define Z for 2-D stem plot"); | |
207 endif | |
208 endif | |
209 | |
210 ## Validate numeric data | |
211 if (have_z) | |
212 if (isempty (x)) | |
213 [nr, nc] = size (z); | |
214 if (nr >= nc) | |
215 x = repmat ([1:nc], nr, 1); | |
216 y = repmat ([1:nr]', 1, nc); | |
217 else | |
218 x = repmat ([1:nc], nr, 1); | |
219 y = repmat ([1:nr]', 1, nc); | |
220 endif | |
221 endif | |
222 if (! (ismatrix (x) && ismatrix (y) && ismatrix (z))) | |
223 error ("stem3: X, Y, and Z must be numeric"); | |
224 endif | |
225 else | |
226 if (isempty (x)) | |
213 if (isvector (y)) | 227 if (isvector (y)) |
214 x = 1:length (y); | 228 x = 1:length (y); |
215 elseif (ismatrix (y)) | 229 elseif (ismatrix (y)) |
216 x = 1:rows (y); | 230 x = 1:rows (y); |
217 else | 231 endif |
218 error ("stem: Y must be a matrix"); | 232 endif |
219 endif # in each case, x & y will be defined | 233 if (! (ismatrix (x) && ismatrix (y))) |
220 endif | 234 error ("stem: X and Y must be numeric"); |
221 elseif (nargin == 3) | 235 endif |
222 ## Several possibilities | |
223 ## | |
224 ## 1. the real y data | |
225 ## 2. 'filled' | |
226 ## 3. line spec | |
227 if (ischar (varargin{2})) | |
228 ## Only 2. or 3. possible. | |
229 if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2})) | |
230 dofill = 1; | |
231 else | |
232 ## Parse the linespec. | |
233 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{2}); | |
234 endif | |
235 if (have_z) | |
236 z = varargin{1}; | |
237 x = 1:rows (z); | |
238 y = 1:columns (z); | |
239 else | |
240 y = varargin{1}; | |
241 if (isvector (y)) | |
242 x = 1:length (y); | |
243 elseif (ismatrix (y)) | |
244 x = 1:rows (y); | |
245 else | |
246 error ("stem: Y must be a matrix"); | |
247 endif # in each case, x & y will be defined | |
248 endif | |
249 else | |
250 if (have_z) | |
251 error ("stem3: must define X, Y and Z"); | |
252 else | |
253 ## Must be the real y data. | |
254 x = varargin{1}; | |
255 y = varargin{2}; | |
256 if (! (ismatrix (x) && ismatrix (y))) | |
257 error ("stem: X and Y must be matrices"); | |
258 endif | |
259 endif | |
260 endif | |
261 elseif (nargin == 4) | |
262 ## Again, several possibilities: | |
263 ## | |
264 ## arg2 1. real y | |
265 ## arg2 2. 'filled' or linespec | |
266 ## arg3 1. real z | |
267 ## arg3 2. 'filled' or linespec | |
268 if (ischar (varargin{2})) | |
269 ## Only arg2 2. / arg3 1. & arg3 3. are possible. | |
270 if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2})) | |
271 dofill = 1; | |
272 fill_2 = 1; # Be sure, no second "fill" is in the arguments. | |
273 else | |
274 ## Must be a linespec. | |
275 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{2}); | |
276 linespec_2 = 1; | |
277 endif | |
278 if (have_z) | |
279 z = varargin{1}; | |
280 x = 1:rows (z); | |
281 y = 1:columns (z); | |
282 else | |
283 y = varargin{1}; | |
284 if (isvector (y)) | |
285 x = 1:length (y); | |
286 elseif (ismatrix (y)) | |
287 x = 1:rows (y); | |
288 else | |
289 error ("stem: Y must be a matrix"); | |
290 endif # in each case, x & y will be defined | |
291 endif | |
292 else | |
293 if (have_z) | |
294 x = varargin{1}; | |
295 y = varargin{2}; | |
296 z = varargin{3}; | |
297 if (! (ismatrix (x) && ismatrix (y) && ismatrix (z))) | |
298 error ("stem3: X, Y and Z must be matrices"); | |
299 endif | |
300 else | |
301 ## must be the real y data. | |
302 x = varargin{1}; | |
303 y = varargin{2}; | |
304 if (! (ismatrix (x) && ismatrix (y))) | |
305 error ("stem: X and Y must be matrices"); | |
306 endif | |
307 endif | |
308 endif # if ischar (varargin{2}) | |
309 if (! have_z) | |
310 ## varargin{3} must be char. | |
311 ## Check for "fill. | |
312 if ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled")) | |
313 && fill_2) | |
314 error ("stem: duplicate fill argument"); | |
315 elseif (strcmpi ("fill", varargin{3}) && linespec_2) | |
316 ## Must be "fill". | |
317 dofill = 1; | |
318 fill_2 = 1; | |
319 elseif ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled")) | |
320 && !linespec_2) | |
321 ## Must be "fill". | |
322 dofill = 1; | |
323 fill_2 = 1; | |
324 elseif (! linespec_2) | |
325 ## Must be linespec. | |
326 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{3}); | |
327 linespec_2 = 1; | |
328 endif | |
329 endif | |
330 elseif (nargin == 5) | |
331 if (have_z) | |
332 x = varargin{1}; | |
333 y = varargin{2}; | |
334 z = varargin{3}; | |
335 if (! (ismatrix (x) && ismatrix (y) && ismatrix (z))) | |
336 error ("stem3: X, Y and Z must be matrices"); | |
337 endif | |
338 else | |
339 x = varargin{1}; | |
340 y = varargin{2}; | |
341 if (! (ismatrix (x) && ismatrix (y))) | |
342 error ("stem: X and Y must be matrices"); | |
343 endif | |
344 endif | |
345 | |
346 if (! have_z) | |
347 if (strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled")) | |
348 dofill = 1; | |
349 fill_2 = 1; # Be sure, no second "fill" is in the arguments. | |
350 else | |
351 ## Must be a linespec. | |
352 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{3}); | |
353 linespec_2 = 1; | |
354 endif | |
355 endif | |
356 | |
357 ## Check for "fill". | |
358 if ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled")) | |
359 && fill_2) | |
360 error ("%s: duplicate fill argument", caller); | |
361 elseif ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled")) | |
362 && linespec_2) | |
363 ## Must be "fill". | |
364 dofill = 1; | |
365 fill_2 = 1; | |
366 elseif (!strcmpi (varargin{4}, "fill") && !strcmpi (varargin{4}, "filled") | |
367 && !linespec_2) | |
368 ## Must be linespec. | |
369 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4}); | |
370 linespec_2 = 1; | |
371 endif | |
372 elseif (nargin == 6 && have_z) | |
373 x = varargin{1}; | |
374 y = varargin{2}; | |
375 z = varargin{3}; | |
376 if (! (ismatrix (x) && ismatrix (y) && ismatrix (z))) | |
377 error ("stem3: X, Y and Z must be matrices"); | |
378 endif | |
379 | |
380 if (strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled")) | |
381 dofill = 1; | |
382 fill_2 = 1; # be sure, no second "fill" is in the arguments | |
383 else | |
384 ## Must be a linespec. | |
385 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4}); | |
386 linespec_2 = 1; | |
387 endif | |
388 | |
389 ## check for "fill" .. | |
390 if ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled")) | |
391 && fill_2) | |
392 error ("stem3: duplicate fill argument"); | |
393 elseif ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled")) | |
394 && linespec_2) | |
395 ## Must be "fill". | |
396 dofill = 1; | |
397 fill_2 = 1; | |
398 elseif (!strcmpi (varargin{5}, "fill") && !strcmpi (varargin{5}, "filled") | |
399 && !linespec_2) | |
400 ## Must be linespec. | |
401 [lc, ls, mc, ms] = stem_line_spec (caller, varargin{5}); | |
402 linespec_2 = 1; | |
403 endif | |
404 else | |
405 error ("%s: incorrect number of arguments", caller); | |
406 endif | 236 endif |
407 | 237 |
408 ## Check sizes of x, y and z. | 238 ## Check sizes of x, y and z. |
409 if (have_z) | 239 if (have_z) |
410 if (!size_equal (x, y, z)) | 240 if (! size_equal (x, y, z)) |
411 error ("stem3: inconsistent size of x, y and z"); | 241 error ("stem3: inconsistent sizes for X, Y, and Z"); |
412 else | 242 endif |
413 x = x(:); | 243 x = x(:); |
414 y = y(:); | 244 y = y(:); |
415 z = z(:); | 245 z = z(:); |
416 endif | |
417 else | 246 else |
418 if (isvector (x)) | 247 if (isvector (x)) |
419 x = x(:); | 248 x = x(:); |
420 if (isvector (y)) | 249 if (isvector (y)) |
421 if (length (x) != length (y)) | 250 if (length (x) != length (y)) |
422 error ("stem: inconsistent size of x and y"); | 251 error ("stem: inconsistent sizes for X and Y"); |
423 else | |
424 y = y(:); | |
425 endif | 252 endif |
253 y = y(:); | |
426 else | 254 else |
427 if (length (x) == rows (y)) | 255 if (length (x) == rows (y)) |
428 x = repmat (x(:), 1, columns (y)); | 256 x = repmat (x(:), 1, columns (y)); |
429 else | 257 else |
430 error ("stem: inconsistent size of x and y"); | 258 error ("stem: inconsistent sizes for X and Y"); |
431 endif | 259 endif |
432 endif | 260 endif |
433 elseif (!size_equal (x, y)) | 261 elseif (! size_equal (x, y)) |
434 error ("stem: inconsistent size of x and y"); | 262 error ("stem: inconsistent sizes for X and Y"); |
435 endif | 263 endif |
436 endif | 264 endif |
437 | 265 |
438 endfunction | 266 dofill = false; |
439 | 267 have_line_spec = false; |
440 function [lc, ls, mc, ms] = stem_line_spec (caller, str) | 268 ## set specifiers to default values. |
441 if (! ischar (str)) | |
442 error ("%s: expecting argument to be \"fill\" or a string of specifiers", | |
443 caller); | |
444 endif | |
445 [lc, ls, mc, ms] = set_default_values (); | 269 [lc, ls, mc, ms] = set_default_values (); |
446 ## Parse the line specifier string. | 270 |
447 cur_props = __pltopt__ ("stem", str, false); | 271 args = {}; |
448 for i = 1:length (cur_props) | 272 ioff = num_numeric + 1; |
449 if (isfield (cur_props(i), "color") && ! isempty (cur_props(i).color)); # means line color | 273 while (ioff <= nargin) |
450 mc = lc = cur_props(i).color; | 274 arg = varargin{ioff++}; |
451 elseif (isfield (cur_props(i), "linestyle")) | 275 if (ischar (arg) && any (strcmpi (arg, {"fill", "filled"}))) |
452 ls = cur_props(i).linestyle; | 276 dofill = true; |
453 if (isempty (ls)) | 277 elseif ((ischar (arg) || iscell (arg)) && ! have_line_spec) |
454 ls = __next_line_style__ (); | 278 [linespec, valid] = __pltopt__ (caller, arg, false); |
455 endif | 279 if (valid) |
456 elseif (isfield (cur_props(i), "marker") && ! strcmpi (cur_props(i).marker, "none")) | 280 have_line_spec = true; |
457 ms = cur_props(i).marker; | 281 [lc, ls, mc, ms] = stem_line_spec (linespec); |
458 if (isempty (ms)) | 282 else |
459 [dummy, ms] = __next_line_style__ (); | 283 args{end+1} = arg; |
460 endif | 284 if (ioff <= nargin) |
461 endif | 285 args{end+1} = varargin{ioff++}; |
462 endfor | 286 else |
287 error ('%s: No value specified for property "%s"', caller, arg); | |
288 endif | |
289 endif | |
290 else | |
291 args{end+1} = arg; | |
292 if (ioff <= nargin) | |
293 args{end+1} = varargin{ioff++}; | |
294 else | |
295 error ('%s: No value specified for property "%s"', caller, arg); | |
296 endif | |
297 endif | |
298 endwhile | |
299 | |
300 endfunction | |
301 | |
302 function [lc, ls, mc, ms] = stem_line_spec (lspec) | |
303 | |
304 [lc, ls, mc, ms] = set_default_values (); | |
305 | |
306 if (! isempty (lspec.color)) | |
307 lc = mc = lspec.color; | |
308 endif | |
309 | |
310 if (! isempty (lspec.linestyle) && ! strcmp (lspec.linestyle, "none")) | |
311 ls = lspec.linestyle; | |
312 endif | |
313 | |
314 if (! isempty (lspec.marker) && ! strcmp (lspec.marker, "none")) | |
315 ms = lspec.marker; | |
316 endif | |
317 | |
463 endfunction | 318 endfunction |
464 | 319 |
465 function [lc, ls, mc, ms] = set_default_values () | 320 function [lc, ls, mc, ms] = set_default_values () |
466 ## set default values | |
467 mc = []; | 321 mc = []; |
468 lc = []; | 322 lc = []; |
469 ls = "-"; | 323 ls = "-"; |
470 ms = "o"; | 324 ms = "o"; |
471 endfunction | 325 endfunction |
472 | 326 |
473 function update_xlim (h, d) | 327 function update_xlim (h, ~) |
474 kids = get (h, "children"); | 328 kids = get (h, "children"); |
475 xlim = get (h, "xlim"); | 329 xlim = get (h, "xlim"); |
476 | 330 |
477 for i = 1 : length (kids) | 331 for i = 1 : length (kids) |
478 obj = get (kids (i)); | 332 obj = get (kids(i)); |
479 if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline")) | 333 if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline")) |
480 if (any (get (obj.baseline, "xdata") != xlim)) | 334 if (any (get (obj.baseline, "xdata") != xlim)) |
481 set (obj.baseline, "xdata", xlim); | 335 set (obj.baseline, "xdata", xlim); |
482 endif | 336 endif |
483 endif | 337 endif |
484 endfor | 338 endfor |
485 endfunction | 339 endfunction |
486 | 340 |
487 function update_baseline (h, d) | 341 function update_baseline (h, ~, src) |
488 visible = get (h, "visible"); | 342 visible = get (h, "visible"); |
489 ydata = get (h, "ydata")(1); | 343 if (src == 0) |
344 basevalue = get (h, "basevalue"); | |
345 else | |
346 basevalue = get (h, "ydata")(1); | |
347 endif | |
490 | 348 |
491 kids = get (get (h, "parent"), "children"); | 349 kids = get (get (h, "parent"), "children"); |
492 for i = 1 : length (kids) | 350 for i = 1 : length (kids) |
493 obj = get (kids (i)); | 351 obj = get (kids(i)); |
494 if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline") | 352 if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline") |
495 && obj.baseline == h) | 353 && obj.baseline == h) |
496 ## Only alter if changed to avoid recursion of the listener functions | 354 ## Avoid lots of unnecessary listener updates |
497 if (! strcmpi (get (kids(i), "showbaseline"), visible)) | 355 if (! strcmp (get (kids(i), "showbaseline"), visible)) |
498 set (kids (i), "showbaseline", visible); | 356 set (kids(i), "showbaseline", visible); |
499 endif | 357 endif |
500 if (! strcmpi (get (kids(i), "basevalue"), visible)) | 358 if (get (kids(i), "basevalue") != basevalue) |
501 set (kids (i), "basevalue", ydata); | 359 set (kids(i), "basevalue", basevalue); |
502 endif | 360 endif |
503 endif | 361 endif |
504 endfor | 362 endfor |
505 endfunction | 363 endfunction |
506 | 364 |
507 function show_baseline (h, d) | 365 function show_baseline (h, ~) |
508 set (get (h, "baseline"), "visible", get (h, "showbaseline")); | 366 set (get (h, "baseline"), "visible", get (h, "showbaseline")); |
509 endfunction | 367 endfunction |
510 | 368 |
511 function move_baseline (h, d) | 369 function move_baseline (h, ~) |
512 b0 = get (h, "basevalue"); | 370 b0 = get (h, "basevalue"); |
513 bl = get (h, "baseline"); | 371 bl = get (h, "baseline"); |
514 | 372 |
515 if (get (bl, "ydata") != [b0, b0]) | 373 set (bl, "ydata", [b0, b0]); |
516 set (bl, "ydata", [b0, b0]); | |
517 endif | |
518 | 374 |
519 kids = get (h, "children"); | 375 kids = get (h, "children"); |
520 yt = get (h, "ydata")(:)'; | 376 yt = get (h, "ydata")(:)'; |
521 ny = length (yt); | 377 ny = length (yt); |
522 yt = [b0 * ones(1, ny); yt; NaN(1, ny)](:); | 378 yt = [b0 * ones(1, ny); yt; NaN(1, ny)](:); |
523 set (kids(2), "ydata", yt); | 379 set (kids(2), "ydata", yt); |
524 endfunction | 380 endfunction |
525 | 381 |
526 function update_props (h, d) | 382 function update_props (h, ~) |
527 kids = get (h, "children"); | 383 kids = get (h, "children"); |
528 set (kids(2), "color", get (h, "color"), | 384 set (kids(2), "color", get (h, "color"), |
529 "linewidth", get (h, "linewidth"), | 385 "linestyle", get (h, "linestyle"), |
530 "linestyle", get (h, "linestyle")); | 386 "linewidth", get (h, "linewidth")); |
531 set (kids(1), "color", get (h, "color"), | 387 set (kids(1), "color", get (h, "markeredgecolor"), |
532 "marker", get (h, "marker"), | 388 "marker", get (h, "marker"), |
533 "markerfacecolor", get (h, "markerfacecolor"), | 389 "markerfacecolor", get (h, "markerfacecolor"), |
534 "markersize", get (h, "markersize")); | 390 "markersize", get (h, "markersize")); |
535 endfunction | 391 endfunction |
536 | 392 |
537 function update_data (h, d) | 393 function update_data (h, ~) |
538 x = get (h, "xdata"); | 394 x = get (h, "xdata"); |
539 y = get (h, "ydata"); | 395 y = get (h, "ydata"); |
540 z = get (h, "zdata"); | 396 z = get (h, "zdata"); |
541 | 397 |
542 if (!isempty (z) && size_equal (x, y, z)) | 398 if (!isempty (z) && size_equal (x, y, z)) |