]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/private/__errplot__.m
update packages
[CreaPhase.git] / octave_packages / m / plot / private / __errplot__.m
1 ## Copyright (C) 2000-2012 Teemu Ikonen
2 ##
3 ## This file is part of Octave.
4 ##
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.
9 ##
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.
14 ##
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/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
21 ## Undocumented internal function.
22 ## @end deftypefn
23
24 ## Created: 18.7.2000
25 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
26 ## Keywords: errorbar, plotting
27
28 function h = __errplot__ (fstr, p, varargin)
29
30   if (nargin < 4 || nargin > 8) # at least two data arguments needed
31     print_usage ();
32   endif
33
34   [fmt, valid] = __pltopt__ ("__errplot__", fstr);
35
36   [len, nplots] = size (varargin{1});
37   h = [];
38
39   for i = 1:nplots
40     ## Set the plot type based on linestyle.
41
42     if (strcmp (fmt.errorstyle, "~"))
43       ifmt = "yerr";
44     elseif (strcmp (fmt.errorstyle, ">"))
45       ifmt = "xerr";
46     elseif (strcmp (fmt.errorstyle, "~>"))
47       ifmt = "xyerr";
48     elseif (strcmp (fmt.errorstyle, "#"))
49       ifmt = "box";
50     elseif (strcmp (fmt.errorstyle, "#~"))
51       ifmt = "boxy";
52     elseif (strcmp (fmt.errorstyle, "#~>"))
53       ifmt = "boxxy";
54     else
55       ifmt = "yerr";
56     endif
57
58     hg = hggroup ("parent", p);
59     h = [h; hg];
60     args = __add_datasource__ ("__errplot__", hg,
61                                {"x", "y", "l", "u", "xl", "xu"});
62
63     if (isempty (fmt.color))
64       fmt.color = __next_line_color__ ();
65     endif
66     if (isempty (fmt.marker) && isempty (fmt.linestyle))
67       [fmt.linestyle, fmt.marker] = __next_line_style__ ();
68     endif
69     hl = [(__line__ (hg, "linestyle", fmt.linestyle, "marker", fmt.marker,
70                    "color", fmt.color)),
71           (__line__ (hg, "linestyle", "-", "marker", "none",
72                    "color", fmt.color))];
73
74     switch (numel(varargin))
75       case 2
76         ydata = varargin{1}(:,i);
77         xdata = 1:numel (ydata);
78         if (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
79           xldata = varargin{2}(:,i);
80           xudata = ldata;
81           ldata = [];
82           udata = [];
83         elseif (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
84           ldata = varargin{2}(:,i);
85           udata = ldata;
86           xldata = [];
87           xudata = [];
88         else
89           error ("errorbar: 2 column errorplot is only valid for xerr or yerr");
90         endif
91       case 3
92         if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
93           ydata = varargin{1}(:,i);
94           xdata = 1:numel (ydata);
95           xldata = varargin{2}(:,i);
96           xudata = xldata;
97           ldata = varargin{3}(:,i);
98           udata = ldata;
99         elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
100           xdata = varargin{1}(:,i);
101           ydata = varargin{2}(:,i);
102           xldata = varargin{3}(:,i);
103           xudata = xldata;
104           ldata = [];
105           udata = [];
106         else # yerr or boxy
107           xdata = varargin{1}(:,i);
108           ydata = varargin{2}(:,i);
109           ldata = varargin{3}(:,i);
110           udata = ldata;
111           xldata = [];
112           xudata = [];
113         endif
114       case 4
115         if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
116           xdata = varargin{1}(:,i);
117           ydata = varargin{2}(:,i);
118           xldata = varargin{3}(:,i);
119           xudata = xldata;
120           ldata = varargin{4}(:,i);
121           udata = ldata;
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);
127           ldata = [];
128           udata = [];
129         else # yerr or boxy
130           xdata = varargin{1}(:,i);
131           ydata = varargin{2}(:,i);
132           ldata = varargin{3}(:,i);
133           udata = varargin{4}(:,i);
134           xldata = [];
135           xudata = [];
136         endif
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);
145         else
146           error ("errorbar: error plot with 6 columns only valid for boxxy and xyerr");
147         endif
148       otherwise
149         error ("errorbar: error plot requires 2, 3, 4, or 6 arguments");
150     endswitch
151
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);
159
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"));
170
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);
178
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);
187
188     hax = ancestor (hg, "axes");
189     addlistener (hax, "xscale", fcn);
190     addlistener (hax, "yscale", fcn);
191
192     update_data (hg, [], hl);
193
194   endfor
195
196   ## Process legend key
197   if (! isempty (fmt.key))    
198     hlegend = [];
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 ())))
205           hlegend = fkids (i);
206           break;
207         endif
208       endif
209     endfor
210
211     if (isempty (hlegend))
212       hlgnd = [];
213       tlgnd = {};
214     else
215       [hlgnd, tlgnd] = __getlegenddata__ (hlegend);
216     endif
217  
218     hlgnd(end+1) = hg;
219     tlgnd(end+1) = fmt.key;
220
221     legend (gca(), hlgnd, tlgnd);
222   end 
223
224 endfunction
225
226 function [xdata, ydata] = errorbar_data (xdata, ydata, ldata, udata,
227                                          xldata, xudata, ifmt,
228                                          xscale, yscale)
229   if (strcmp (xscale, "linear"))
230     dx = 0.01 * (max (xdata(:)) - min (xdata(:)));
231     xlo = xdata - dx;
232     xhi = xdata + dx;
233   else
234     n = xdata > 0;
235     rx = exp(0.01 * (max (log(xdata(n))) - min (log(xdata(n)))));
236     xlo = xdata/rx;
237     xhi = xdata*rx;
238   endif
239   if (strcmp (yscale, "linear"))
240     dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
241     ylo = ydata - dy;
242     yhi = ydata + dy;
243   else
244     n = ydata > 0;
245     ry = exp(0.01 * (max (log(ydata(n))) - min (log(ydata(n)))));
246     ylo = ydata/ry;
247     yhi = ydata*ry;
248   endif
249   nans = NaN + xdata(:);
250   if (strcmp (ifmt, "yerr"))
251     xdata = [xdata, xdata, nans, ...
252              xlo, xhi, nans, ...
253              xlo, xhi, 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, ...
262              ylo, yhi, nans, ...
263              ylo, yhi, 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, ...
268              ydata-ldata, nans];
269   elseif (strcmp (ifmt, "box"))
270     dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
271     xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
272              xdata-xldata, nans];
273     ydata = [ylo, ylo, yhi, yhi, ylo, nans];
274   elseif (strcmp (ifmt, "boxxy"))
275     xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
276              xdata-xldata, nans];
277     ydata = [ydata-ldata, ydata-ldata, ydata+udata, ydata+udata, ...
278              ydata-ldata, nans];
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);
284     xdata = [x1; x2];
285     ydata = [y1; y2];
286     return
287   else
288     error ("errorbar: valid error bar types are xerr, yerr, boxxy, and xyerr");
289   endif
290
291   xdata = xdata.'(:);
292   ydata = ydata.'(:);
293
294 endfunction
295
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"));
304 endfunction
305
306 function update_data (hg, dummy, hl)
307
308   if (strcmp (get (hg, "type"), "axes"))
309     hax = hg;
310     hg = ancestor (hl(1), "hggroup");
311   else
312     hax = ancestor (hg, "axes");
313   endif
314   xscale = get (hax, "xscale");
315   yscale = get (hax, "yscale");
316
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");
324
325   set (hl(1), "xdata", xdata);
326   set (hl(1), "ydata", ydata);
327
328   [errorbar_xdata, errorbar_ydata] = ...
329           errorbar_data (xdata, ydata, ldata, udata, xldata, xudata, ...
330                          ifmt, xscale, yscale);
331
332   set (hl(2), "xdata", errorbar_xdata);
333   set (hl(2), "ydata", errorbar_ydata);
334
335 endfunction
336