changeset 6540:9dcfc78da664

[project @ 2007-04-18 21:16:08 by dbateman]
author dbateman
date Wed, 18 Apr 2007 21:16:08 +0000
parents bfb71a842496
children 0796d8905848
files scripts/ChangeLog scripts/plot/Makefile.in scripts/plot/__bar__.m scripts/plot/bar.m scripts/plot/hbar.m
diffstat 5 files changed, 240 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Wed Apr 18 19:45:17 2007 +0000
+++ b/scripts/ChangeLog	Wed Apr 18 21:16:08 2007 +0000
@@ -1,3 +1,11 @@
+2007-04-18  David Bateman  <dbateman@free.fr>
+
+	* __bar__.m: New support function for bar/hbar to support graphic
+	handles, and additional arguments.
+	* bar.m: Convert to use __bar__.
+	* hbar.m: New function
+	* hist.m: Explicitly set the width of the bar plot.
+	
 2007-04-17  John W. Eaton  <jwe@octave.org>
 
 	* plot/stem.m (stem_line_spec): Pass false as third arg to __pltopt__.
--- a/scripts/plot/Makefile.in	Wed Apr 18 19:45:17 2007 +0000
+++ b/scripts/plot/Makefile.in	Wed Apr 18 21:16:08 2007 +0000
@@ -22,6 +22,7 @@
 
 SOURCES = \
   __axis_label__.m \
+  __bar__m \
   __default_colormap__.m \
   __default_plot_options__.m \
   __errcomm__.m \
@@ -61,6 +62,7 @@
   gca.m \
   gcf.m \
   grid.m \
+  hbar.m \
   hist.m \
   hold.m \
   isfigure.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/__bar__.m	Wed Apr 18 21:16:08 2007 +0000
@@ -0,0 +1,160 @@
+## Copyright (C) 1996, 1997 John W. Eaton
+##
+## 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 2, 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, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __bar__ (@dots{})
+## Support function for @ode{bar} and {hbar}. 
+## @seealso{bar, hbar}
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = __bar__ (vertical, func, varargin)
+  width = 0.8;
+  group = true;
+
+  if (nargin < 3)
+    print_usage();
+  endif
+
+  if (nargin > 3 && isnumeric(varargin{2}))
+    x = varargin{1};
+    if (isvector(x))
+      x = x(:);
+    endif
+    y = varargin{2};
+    if (isvector(y))
+      y = y(:);
+    endif
+    if (size(x,1) != size(y,1))
+      y = varargin{1};
+      if (isvector(y))
+	y = y(:);
+      endif
+      x = [1:size(y,1)]';
+      idx = 2;
+    else
+      if (! isvector(x))
+	error ("%s: x must be a vector", func);
+      endif
+      idx = 3;
+    endif
+  else
+    y = varargin{1};
+    if (isvector(y))
+      y = y(:);
+    endif
+    x = [1:size(y,1)]';
+    idx = 2;
+  endif
+      
+  newargs = {};
+  HaveLineSpec = false;
+  while (idx <= nargin -2)
+    if (isstr(varargin{idx}) && strcmp(varargin{idx},"grouped"))
+      group = true;
+      idx++;
+    elseif (isstr(varargin{idx}) && strcmp(varargin{idx},"stacked"))
+      group = false;
+      idx++;
+    else
+      if (!HaveLineSpec)
+	[dummy, valid] = __pltopt__ (func, varargin{idx}, false);
+	if (valid)
+	  HaveLineSpec = true;
+	  newargs = [newargs,varargin(idx++)];
+	  continue;
+	endif
+      endif
+      if (isscalar(varargin{idx}))
+	width = varargin{idx++};
+      elseif (idx == nargin - 2)
+	newargs = [newargs,varargin(idx++)];
+      else
+	newargs = [newargs,varargin(idx:idx+1)];
+	idx += 2;
+      endif
+    endif
+  endwhile
+
+  xlen = size (x, 1);
+  ylen = size (y, 1);
+
+  if (xlen != ylen)
+    error ("%s: length of x and y must be equal", func)
+  endif
+  if (any (x(2:end) < x(1:end-1)))
+    error ("%s: x vector values must be in ascending order", func);
+  endif
+
+  ycols = size (y, 2);
+  if (group)
+    width = width / ycols;
+  endif
+
+  cutoff = (x(1:end-1) + x(2:end)) / 2;
+  delta_p = [(cutoff - x(1:end-1)); (x(end) - cutoff(end))]  * width;
+  delta_m = [(cutoff(1) - x(1)); (x(2:end) - cutoff)] * width;
+  x1 = (x - delta_m)(:)';
+  x2 = (x + delta_p)(:)';
+  xb = repmat([x1; x1; x2; x2; NaN * ones(1,ylen)](:), 1, ycols);
+
+  if (group)
+    width = width / ycols;
+    offset = ((delta_p + delta_m) * [-(ycols - 1) / 2 : (ycols - 1) / 2]);
+    xb(1:5:5*ylen,:) += offset;
+    xb(2:5:5*ylen,:) += offset;
+    xb(3:5:5*ylen,:) += offset;
+    xb(4:5:5*ylen,:) += offset;
+    xb(5:5:5*ylen,:) += offset;
+    y0 = zeros (size (y));
+    y1 = y;
+  else
+    y1 = cumsum(y,2);
+    y0 = [zeros(ylen,1), y1(:,1:end-1)];
+  endif
+
+  yb = zeros (5*ylen, ycols);
+  yb(1:5:5*ylen,:) = y0;
+  yb(2:5:5*ylen,:) = y1;
+  yb(3:5:5*ylen,:) = y1;
+  yb(4:5:5*ylen,:) = y0;
+  yb(5:5:5*ylen,:) = NaN;
+
+  if (vertical)
+    if (nargout < 1)
+      plot (xb, yb, newargs{:});
+    elseif (nargout < 2)
+      varargout{1} = plot (xb, yb, newargs{:});
+    else
+      varargout{1} = xb;
+      varargout{2} = yb;
+    endif
+  else
+    if (nargout < 1)
+      plot (yb, xb, newargs{:});
+    elseif (nargout < 2)
+      varargout{1} = plot (yb, xb, newargs{:});
+    else
+      varargout{1} = yb;
+      varargout{2} = xb;
+    endif
+  endif    
+
+endfunction
--- a/scripts/plot/bar.m	Wed Apr 18 19:45:17 2007 +0000
+++ b/scripts/plot/bar.m	Wed Apr 18 21:16:08 2007 +0000
@@ -18,12 +18,18 @@
 ## 02110-1301, USA.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} bar (@var{x}, @var{y})
+## @deftypefn {Function File} {@var{h} =} bar (@var{x}, @var{y}, @var{style})
+## @deftypefnx {Function File} {[@var{xb}, @var{yb}] =} bar (@dots{})
 ## Given two vectors of x-y data, @code{bar} produces a bar graph.
 ##
 ## If only one argument is given, it is taken as a vector of y-values
 ## and the x coordinates are taken to be the indices of the elements.
 ##
+## If @var{y} is a matrix, then each column of @var{y} is taken to be a
+## separate bar graph plotted on the same graph. By default the columns
+## are plotted side-by-side. This behavior can be changed by the @var{style}
+## argument, which can take the values 'group' (the default), or 'stack'.
+##
 ## If two output arguments are specified, the data are generated but
 ## not plotted.  For example,
 ##
@@ -41,84 +47,13 @@
 ##
 ## @noindent
 ## are equivalent.
-## @seealso{plot, semilogx, semilogy, loglog, polar, mesh, contour,
+## @seealso{hbar, plot, semilogx, semilogy, loglog, polar, mesh, contour,
 ## stairs, xlabel, ylabel, title}
 ## @end deftypefn
 
 ## Author: jwe
 
-function [xb, yb] = bar (x, y)
-
-  if (nargin == 1)
-    if (isvector (x))
-      len = 3 * length (x) + 1;
-      tmp_xb = tmp_yb = zeros (len, 1);
-      tmp_xb(1) = 0.5;
-      tmp_yb(1) = 0;
-      k = 1;
-      for i = 2:3:len
-        tmp_xb(i) = k-0.5;
-        tmp_xb(i+1) = k+0.5;
-        tmp_xb(i+2) = k+0.5;
-        tmp_yb(i) = x(k);
-        tmp_yb(i+1) = x(k);
-        tmp_yb(i+2) = 0.0;
-        k++;
-      endfor
-    else
-      error ("bar: argument must be a vector");
-    endif
-  elseif (nargin == 2)
-    if (isvector (x) && isvector (y))
-      xlen = length (x);
-      ylen = length (y);
-      if (xlen == ylen)
-        len = 3 * xlen + 1;
-        tmp_xb = tmp_yb = zeros (len, 1);
-        cutoff = zeros (1, xlen);
-        for i = 1:xlen-1
-          cutoff(i) = (x(i) + x(i+1)) / 2.0;
-        endfor
-        delta_p = cutoff(1) - x(1);
-        delta_m = delta_p;
-        tmp_xb(1) = x(1) - delta_m;
-        tmp_yb(1) = 0.0;
-        k = 1;
-        for i = 2:3:len
-          tmp_xb(i) = tmp_xb(i-1);
-          tmp_xb(i+1) = x(k) + delta_p;
-          tmp_xb(i+2) = tmp_xb(i+1);
-          tmp_yb(i) = y(k);
-          tmp_yb(i+1) = y(k);
-          tmp_yb(i+2) = 0.0;
-          if (k < xlen)
-            if (x(k+1) < x(k))
-              error ("bar: x vector values must be in ascending order");
-            endif
-            delta_m = x(k+1) - cutoff(k);
-            k++;
-            if (k < xlen)
-              delta_p = cutoff(k) - x(k);
-            else
-              delta_p = delta_m;
-            endif
-          endif
-        endfor
-      else
-        error ("bar: arguments must be the same length");
-      endif
-    else
-      error ("bar: arguments must be vectors");
-    endif
-  else
-    print_usage ();
-  endif
-
-  if (nargout == 0)
-    plot (tmp_xb, tmp_yb);
-  else
-    xb = tmp_xb;
-    yb = tmp_yb;
-  endif
-
+function varargout = bar (varargin)
+  varargout = cell (nargout, 1);
+  [varargout{:}] = __bar__ (true, "bar", varargin{:});
 endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/hbar.m	Wed Apr 18 21:16:08 2007 +0000
@@ -0,0 +1,59 @@
+## Copyright (C) 1996, 1997 John W. Eaton
+##
+## 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 2, 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, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} hbar (@var{x}, @var{y}, @var{style})
+## @deftypefnx {Function File} {[@var{xb}, @var{yb}] =} hbar (@dots{})
+## Given two vectors of x-y data, @code{bar} produces a horizontal bar graph.
+##
+## If only one argument is given, it is taken as a vector of y-values
+## and the x coordinates are taken to be the indices of the elements.
+##
+## If @var{y} is a matrix, then each column of @var{y} is taken to be a
+## separate bar graph plotted on the same graph. By default the columns
+## are plotted side-by-side. This behavior can be changed by the @var{style}
+## argument, which can take the values 'group' (the default), or 'stack'.
+##
+## If two output arguments are specified, the data are generated but
+## not plotted.  For example,
+##
+## @example
+## hbar (x, y);
+## @end example
+##
+## @noindent
+## and
+##
+## @example
+## [xb, yb] = hbar (x, y);
+## plot (xb, yb);
+## @end example
+##
+## @noindent
+## are equivalent.
+## @seealso{bar, plot, semilogx, semilogy, loglog, polar, mesh, contour,
+## stairs, xlabel, ylabel, title}
+## @end deftypefn
+
+## Author: jwe
+
+function varargout = hbar (varargin)
+  varargout = cell (nargout, 1);
+  [varargout{:}] = __bar__ (false, "hbar", varargin{:});
+endfunction