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))