]> Creatis software - CreaPhase.git/blobdiff - octave_packages/m/plot/private/__errplot__.m
update packages
[CreaPhase.git] / octave_packages / m / plot / private / __errplot__.m
diff --git a/octave_packages/m/plot/private/__errplot__.m b/octave_packages/m/plot/private/__errplot__.m
new file mode 100644 (file)
index 0000000..41bf71e
--- /dev/null
@@ -0,0 +1,336 @@
+## Copyright (C) 2000-2012 Teemu Ikonen
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
+## Undocumented internal function.
+## @end deftypefn
+
+## Created: 18.7.2000
+## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
+## Keywords: errorbar, plotting
+
+function h = __errplot__ (fstr, p, varargin)
+
+  if (nargin < 4 || nargin > 8) # at least two data arguments needed
+    print_usage ();
+  endif
+
+  [fmt, valid] = __pltopt__ ("__errplot__", fstr);
+
+  [len, nplots] = size (varargin{1});
+  h = [];
+
+  for i = 1:nplots
+    ## Set the plot type based on linestyle.
+
+    if (strcmp (fmt.errorstyle, "~"))
+      ifmt = "yerr";
+    elseif (strcmp (fmt.errorstyle, ">"))
+      ifmt = "xerr";
+    elseif (strcmp (fmt.errorstyle, "~>"))
+      ifmt = "xyerr";
+    elseif (strcmp (fmt.errorstyle, "#"))
+      ifmt = "box";
+    elseif (strcmp (fmt.errorstyle, "#~"))
+      ifmt = "boxy";
+    elseif (strcmp (fmt.errorstyle, "#~>"))
+      ifmt = "boxxy";
+    else
+      ifmt = "yerr";
+    endif
+
+    hg = hggroup ("parent", p);
+    h = [h; hg];
+    args = __add_datasource__ ("__errplot__", hg,
+                               {"x", "y", "l", "u", "xl", "xu"});
+
+    if (isempty (fmt.color))
+      fmt.color = __next_line_color__ ();
+    endif
+    if (isempty (fmt.marker) && isempty (fmt.linestyle))
+      [fmt.linestyle, fmt.marker] = __next_line_style__ ();
+    endif
+    hl = [(__line__ (hg, "linestyle", fmt.linestyle, "marker", fmt.marker,
+                   "color", fmt.color)),
+          (__line__ (hg, "linestyle", "-", "marker", "none",
+                   "color", fmt.color))];
+
+    switch (numel(varargin))
+      case 2
+        ydata = varargin{1}(:,i);
+        xdata = 1:numel (ydata);
+        if (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
+          xldata = varargin{2}(:,i);
+          xudata = ldata;
+          ldata = [];
+          udata = [];
+        elseif (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
+          ldata = varargin{2}(:,i);
+          udata = ldata;
+          xldata = [];
+          xudata = [];
+        else
+          error ("errorbar: 2 column errorplot is only valid for xerr or yerr");
+        endif
+      case 3
+        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
+          ydata = varargin{1}(:,i);
+          xdata = 1:numel (ydata);
+          xldata = varargin{2}(:,i);
+          xudata = xldata;
+          ldata = varargin{3}(:,i);
+          udata = ldata;
+        elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          xldata = varargin{3}(:,i);
+          xudata = xldata;
+          ldata = [];
+          udata = [];
+        else # yerr or boxy
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          ldata = varargin{3}(:,i);
+          udata = ldata;
+          xldata = [];
+          xudata = [];
+        endif
+      case 4
+        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          xldata = varargin{3}(:,i);
+          xudata = xldata;
+          ldata = varargin{4}(:,i);
+          udata = ldata;
+        elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          xldata = varargin{3}(:,i);
+          xudata = varargin{4}(:,i);
+          ldata = [];
+          udata = [];
+        else # yerr or boxy
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          ldata = varargin{3}(:,i);
+          udata = varargin{4}(:,i);
+          xldata = [];
+          xudata = [];
+        endif
+      case 6 # boxxy, xyerr
+        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
+          xdata = varargin{1}(:,i);
+          ydata = varargin{2}(:,i);
+          xldata = varargin{3}(:,i);
+          xudata = varargin{4}(:,i);
+          ldata = varargin{5}(:,i);
+          udata = varargin{6}(:,i);
+        else
+          error ("errorbar: error plot with 6 columns only valid for boxxy and xyerr");
+        endif
+      otherwise
+        error ("errorbar: error plot requires 2, 3, 4, or 6 arguments");
+    endswitch
+
+    addproperty ("xdata", hg, "data", xdata(:));
+    addproperty ("ydata", hg, "data", ydata(:));
+    addproperty ("ldata", hg, "data", ldata(:));
+    addproperty ("udata", hg, "data", udata(:));
+    addproperty ("xldata", hg, "data", xldata(:));
+    addproperty ("xudata", hg, "data", xudata(:));
+    addproperty ("format", hg, "string", ifmt);
+
+    addproperty ("color", hg, "linecolor", get (hl(1), "color"));
+    addproperty ("linewidth", hg, "linelinewidth", get (hl(1), "linewidth"));
+    addproperty ("linestyle", hg, "linelinestyle", get (hl(1), "linestyle"));
+    addproperty ("marker", hg, "linemarker", get (hl(1), "marker"));
+    addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
+                 get (hl(1), "markerfacecolor"));
+    addproperty ("markeredgecolor", hg, "linemarkerfacecolor",
+                 get (hl(1), "markeredgecolor"));
+    addproperty ("markersize", hg, "linemarkersize",
+                 get (hl(1), "markersize"));
+
+    fcn = {@update_props, hl};
+    addlistener (hg, "color", fcn);
+    addlistener (hg, "linewidth", fcn);
+    addlistener (hg, "linestyle", fcn);
+    addlistener (hg, "marker", fcn);
+    addlistener (hg, "markerfacecolor", fcn);
+    addlistener (hg, "markersize", fcn);
+
+    fcn = {@update_data, hl};
+    addlistener (hg, "xdata", fcn);
+    addlistener (hg, "ydata", fcn);
+    addlistener (hg, "ldata", fcn);
+    addlistener (hg, "udata", fcn);
+    addlistener (hg, "xldata", fcn);
+    addlistener (hg, "xudata", fcn);
+    addlistener (hg, "format", fcn);
+
+    hax = ancestor (hg, "axes");
+    addlistener (hax, "xscale", fcn);
+    addlistener (hax, "yscale", fcn);
+
+    update_data (hg, [], hl);
+
+  endfor
+
+  ## Process legend key
+  if (! isempty (fmt.key))    
+    hlegend = [];
+    fkids = get (gcf(), "children");
+    for i = 1 : numel (fkids)
+      if (ishandle (fkids(i)) && strcmp (get (fkids(i), "type"), "axes")
+          && (strcmp (get (fkids(i), "tag"), "legend")))
+        udata = get (fkids(i), "userdata");
+        if (! isempty (intersect (udata.handle, gca ())))
+          hlegend = fkids (i);
+          break;
+        endif
+      endif
+    endfor
+
+    if (isempty (hlegend))
+      hlgnd = [];
+      tlgnd = {};
+    else
+      [hlgnd, tlgnd] = __getlegenddata__ (hlegend);
+    endif
+    hlgnd(end+1) = hg;
+    tlgnd(end+1) = fmt.key;
+
+    legend (gca(), hlgnd, tlgnd);
+  end 
+
+endfunction
+
+function [xdata, ydata] = errorbar_data (xdata, ydata, ldata, udata,
+                                         xldata, xudata, ifmt,
+                                         xscale, yscale)
+  if (strcmp (xscale, "linear"))
+    dx = 0.01 * (max (xdata(:)) - min (xdata(:)));
+    xlo = xdata - dx;
+    xhi = xdata + dx;
+  else
+    n = xdata > 0;
+    rx = exp(0.01 * (max (log(xdata(n))) - min (log(xdata(n)))));
+    xlo = xdata/rx;
+    xhi = xdata*rx;
+  endif
+  if (strcmp (yscale, "linear"))
+    dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
+    ylo = ydata - dy;
+    yhi = ydata + dy;
+  else
+    n = ydata > 0;
+    ry = exp(0.01 * (max (log(ydata(n))) - min (log(ydata(n)))));
+    ylo = ydata/ry;
+    yhi = ydata*ry;
+  endif
+  nans = NaN + xdata(:);
+  if (strcmp (ifmt, "yerr"))
+    xdata = [xdata, xdata, nans, ...
+             xlo, xhi, nans, ...
+             xlo, xhi, nans];
+    ydata = [ydata-ldata, ydata+udata, nans, ...
+             ydata+udata, ydata+udata, nans, ...
+             ydata-ldata, ydata-ldata, nans];
+  elseif (strcmp (ifmt, "xerr"))
+    xdata = [xdata-xldata, xdata+xudata, nans, ...
+             xdata+xudata, xdata+xudata, nans, ...
+             xdata-xldata, xdata-xldata, nans];
+    ydata = [ydata, ydata, nans, ...
+             ylo, yhi, nans, ...
+             ylo, yhi, nans];
+  elseif (strcmp (ifmt, "boxy"))
+    dx = 0.01 * (max (xdata(:)) - min (xdata(:)));
+    xdata = [xlo, xhi, xhi, xlo, xlo, nans];
+    ydata = [ydata-ldata, ydata-ldata, ydata+udata, ydata+udata, ...
+             ydata-ldata, nans];
+  elseif (strcmp (ifmt, "box"))
+    dy = 0.01 * (max (ydata(:)) - min (ydata(:)));
+    xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
+             xdata-xldata, nans];
+    ydata = [ylo, ylo, yhi, yhi, ylo, nans];
+  elseif (strcmp (ifmt, "boxxy"))
+    xdata = [xdata-xldata, xdata+xudata, xdata+xudata, xdata-xldata, ...
+             xdata-xldata, nans];
+    ydata = [ydata-ldata, ydata-ldata, ydata+udata, ydata+udata, ...
+             ydata-ldata, nans];
+  elseif (strcmp (ifmt, "xyerr"))
+    [x1, y1] = errorbar_data (xdata, ydata, ldata, udata,
+                              xldata, xudata, "xerr", xscale, yscale);
+    [x2, y2] = errorbar_data (xdata, ydata, ldata, udata,
+                              xldata, xudata, "yerr", xscale, yscale);
+    xdata = [x1; x2];
+    ydata = [y1; y2];
+    return
+  else
+    error ("errorbar: valid error bar types are xerr, yerr, boxxy, and xyerr");
+  endif
+
+  xdata = xdata.'(:);
+  ydata = ydata.'(:);
+
+endfunction
+
+function update_props (hg, dummy, hl)
+  set (hl, "color", get (hg, "color"),
+           "linewidth", get (hg, "linewidth"));,
+  set (hl(1), "linestyle", get (hg, "linestyle"),
+              "marker", get (hg, "marker"),
+              "markersize", get (hg, "markersize"),
+              "markerfacecolor", get (hg, "markerfacecolor"),
+              "markeredgecolor", get (hg, "markeredgecolor"));
+endfunction
+
+function update_data (hg, dummy, hl)
+
+  if (strcmp (get (hg, "type"), "axes"))
+    hax = hg;
+    hg = ancestor (hl(1), "hggroup");
+  else
+    hax = ancestor (hg, "axes");
+  endif
+  xscale = get (hax, "xscale");
+  yscale = get (hax, "yscale");
+
+  xdata = get (hg, "xdata");
+  ydata = get (hg, "ydata");
+  ldata = get (hg, "ldata");
+  udata = get (hg, "udata");
+  xldata = get (hg, "xldata");
+  xudata = get (hg, "xudata");
+  ifmt = get (hg, "format");
+
+  set (hl(1), "xdata", xdata);
+  set (hl(1), "ydata", ydata);
+
+  [errorbar_xdata, errorbar_ydata] = ...
+          errorbar_data (xdata, ydata, ldata, udata, xldata, xudata, ...
+                         ifmt, xscale, yscale);
+
+  set (hl(2), "xdata", errorbar_xdata);
+  set (hl(2), "ydata", errorbar_ydata);
+
+endfunction
+