1 ## Copyright (C) 2000-2012 Teemu Ikonen
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
21 ## Undocumented internal function.
25 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
26 ## Keywords: errorbar, plotting
28 function h = __errplot__ (fstr, p, varargin)
30 if (nargin < 4 || nargin > 8) # at least two data arguments needed
34 [fmt, valid] = __pltopt__ ("__errplot__", fstr);
36 [len, nplots] = size (varargin{1});
40 ## Set the plot type based on linestyle.
42 if (strcmp (fmt.errorstyle, "~"))
44 elseif (strcmp (fmt.errorstyle, ">"))
46 elseif (strcmp (fmt.errorstyle, "~>"))
48 elseif (strcmp (fmt.errorstyle, "#"))
50 elseif (strcmp (fmt.errorstyle, "#~"))
52 elseif (strcmp (fmt.errorstyle, "#~>"))
58 hg = hggroup ("parent", p);
60 args = __add_datasource__ ("__errplot__", hg,
61 {"x", "y", "l", "u", "xl", "xu"});
63 if (isempty (fmt.color))
64 fmt.color = __next_line_color__ ();
66 if (isempty (fmt.marker) && isempty (fmt.linestyle))
67 [fmt.linestyle, fmt.marker] = __next_line_style__ ();
69 hl = [(__line__ (hg, "linestyle", fmt.linestyle, "marker", fmt.marker,
71 (__line__ (hg, "linestyle", "-", "marker", "none",
72 "color", fmt.color))];
74 switch (numel(varargin))
76 ydata = varargin{1}(:,i);
77 xdata = 1:numel (ydata);
78 if (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
79 xldata = varargin{2}(:,i);
83 elseif (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
84 ldata = varargin{2}(:,i);
89 error ("errorbar: 2 column errorplot is only valid for xerr or yerr");
92 if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
93 ydata = varargin{1}(:,i);
94 xdata = 1:numel (ydata);
95 xldata = varargin{2}(:,i);
97 ldata = varargin{3}(:,i);
99 elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
100 xdata = varargin{1}(:,i);
101 ydata = varargin{2}(:,i);
102 xldata = varargin{3}(:,i);
107 xdata = varargin{1}(:,i);
108 ydata = varargin{2}(:,i);
109 ldata = varargin{3}(:,i);
115 if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
116 xdata = varargin{1}(:,i);
117 ydata = varargin{2}(:,i);
118 xldata = varargin{3}(:,i);
120 ldata = varargin{4}(:,i);
122 elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
123 xdata = varargin{1}(:,i);
124 ydata = varargin{2}(:,i);
125 xldata = varargin{3}(:,i);
126 xudata = varargin{4}(:,i);
130 xdata = varargin{1}(:,i);
131 ydata = varargin{2}(:,i);
132 ldata = varargin{3}(:,i);
133 udata = varargin{4}(:,i);
137 case 6 # boxxy, xyerr
138 if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
139 xdata = varargin{1}(:,i);
140 ydata = varargin{2}(:,i);
141 xldata = varargin{3}(:,i);
142 xudata = varargin{4}(:,i);
143 ldata = varargin{5}(:,i);
144 udata = varargin{6}(:,i);
146 error ("errorbar: error plot with 6 columns only valid for boxxy and xyerr");
149 error ("errorbar: error plot requires 2, 3, 4, or 6 arguments");
152 addproperty ("xdata", hg, "data", xdata(:));
153 addproperty ("ydata", hg, "data", ydata(:));
154 addproperty ("ldata", hg, "data", ldata(:));
155 addproperty ("udata", hg, "data", udata(:));
156 addproperty ("xldata", hg, "data", xldata(:));
157 addproperty ("xudata", hg, "data", xudata(:));
158 addproperty ("format", hg, "string", ifmt);
160 addproperty ("color", hg, "linecolor", get (hl(1), "color"));
161 addproperty ("linewidth", hg, "linelinewidth", get (hl(1), "linewidth"));
162 addproperty ("linestyle", hg, "linelinestyle", get (hl(1), "linestyle"));
163 addproperty ("marker", hg, "linemarker", get (hl(1), "marker"));
164 addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
165 get (hl(1), "markerfacecolor"));
166 addproperty ("markeredgecolor", hg, "linemarkerfacecolor",
167 get (hl(1), "markeredgecolor"));
168 addproperty ("markersize", hg, "linemarkersize",
169 get (hl(1), "markersize"));
171 fcn = {@update_props, hl};
172 addlistener (hg, "color", fcn);
173 addlistener (hg, "linewidth", fcn);
174 addlistener (hg, "linestyle", fcn);
175 addlistener (hg, "marker", fcn);
176 addlistener (hg, "markerfacecolor", fcn);
177 addlistener (hg, "markersize", fcn);
179 fcn = {@update_data, hl};
180 addlistener (hg, "xdata", fcn);
181 addlistener (hg, "ydata", fcn);
182 addlistener (hg, "ldata", fcn);
183 addlistener (hg, "udata", fcn);
184 addlistener (hg, "xldata", fcn);
185 addlistener (hg, "xudata", fcn);
186 addlistener (hg, "format", fcn);
188 hax = ancestor (hg, "axes");
189 addlistener (hax, "xscale", fcn);
190 addlistener (hax, "yscale", fcn);
192 update_data (hg, [], hl);
196 ## Process legend key
197 if (! isempty (fmt.key))
199 fkids = get (gcf(), "children");
200 for i = 1 : numel (fkids)
201 if (ishandle (fkids(i)) && strcmp (get (fkids(i), "type"), "axes")
202 && (strcmp (get (fkids(i), "tag"), "legend")))
203 udata = get (fkids(i), "userdata");
204 if (! isempty (intersect (udata.handle, gca ())))
211 if (isempty (hlegend))
215 [hlgnd, tlgnd] = __getlegenddata__ (hlegend);
219 tlgnd(end+1) = fmt.key;
221 legend (gca(), hlgnd, tlgnd);
226 function [xdata, ydata] = errorbar_data (xdata, ydata, ldata, udata,
227 xldata, xudata, ifmt,
229 if (strcmp (xscale, "linear"))
230 dx = 0.01 * (max (xdata(:)) - min (xdata(:)));
235 rx = exp(0.01 * (max (log(xdata(n))) - min (log(xdata(n)))));
239 if (strcmp (yscale, "linear"))
240 dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
245 ry = exp(0.01 * (max (log(ydata(n))) - min (log(ydata(n)))));
249 nans = NaN + xdata(:);
250 if (strcmp (ifmt, "yerr"))
251 xdata = [xdata, xdata, nans, ...
254 ydata = [ydata-ldata, ydata+udata, nans, ...
255 ydata+udata, ydata+udata, nans, ...
256 ydata-ldata, ydata-ldata, nans];
257 elseif (strcmp (ifmt, "xerr"))
258 xdata = [xdata-xldata, xdata+xudata, nans, ...
259 xdata+xudata, xdata+xudata, nans, ...
260 xdata-xldata, xdata-xldata, nans];
261 ydata = [ydata, ydata, nans, ...
264 elseif (strcmp (ifmt, "boxy"))
265 dx = 0.01 * (max (xdata(:)) - min (xdata(:)));
266 xdata = [xlo, xhi, xhi, xlo, xlo, nans];
267 ydata = [ydata-ldata, ydata-ldata, ydata+udata, ydata+udata, ...
269 elseif (strcmp (ifmt, "box"))
270 dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
271 xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
273 ydata = [ylo, ylo, yhi, yhi, ylo, nans];
274 elseif (strcmp (ifmt, "boxxy"))
275 xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
277 ydata = [ydata-ldata, ydata-ldata, ydata+udata, ydata+udata, ...
279 elseif (strcmp (ifmt, "xyerr"))
280 [x1, y1] = errorbar_data (xdata, ydata, ldata, udata,
281 xldata, xudata, "xerr", xscale, yscale);
282 [x2, y2] = errorbar_data (xdata, ydata, ldata, udata,
283 xldata, xudata, "yerr", xscale, yscale);
288 error ("errorbar: valid error bar types are xerr, yerr, boxxy, and xyerr");
296 function update_props (hg, dummy, hl)
297 set (hl, "color", get (hg, "color"),
298 "linewidth", get (hg, "linewidth"));,
299 set (hl(1), "linestyle", get (hg, "linestyle"),
300 "marker", get (hg, "marker"),
301 "markersize", get (hg, "markersize"),
302 "markerfacecolor", get (hg, "markerfacecolor"),
303 "markeredgecolor", get (hg, "markeredgecolor"));
306 function update_data (hg, dummy, hl)
308 if (strcmp (get (hg, "type"), "axes"))
310 hg = ancestor (hl(1), "hggroup");
312 hax = ancestor (hg, "axes");
314 xscale = get (hax, "xscale");
315 yscale = get (hax, "yscale");
317 xdata = get (hg, "xdata");
318 ydata = get (hg, "ydata");
319 ldata = get (hg, "ldata");
320 udata = get (hg, "udata");
321 xldata = get (hg, "xldata");
322 xudata = get (hg, "xudata");
323 ifmt = get (hg, "format");
325 set (hl(1), "xdata", xdata);
326 set (hl(1), "ydata", ydata);
328 [errorbar_xdata, errorbar_ydata] = ...
329 errorbar_data (xdata, ydata, ldata, udata, xldata, xudata, ...
330 ifmt, xscale, yscale);
332 set (hl(2), "xdata", errorbar_xdata);
333 set (hl(2), "ydata", errorbar_ydata);