octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Rewritten version of bar.m


From: David Bateman
Subject: Rewritten version of bar.m
Date: Tue, 17 Apr 2007 00:21:09 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

Here is a rewritten version of bar.m for comment. Its not perfect, due
to a couple of issues, but it does treat groups and stacks when "y" is a
matrix, and is converted to use graphic handles. The matlab version uses
a new handle type called a barseries, whereas this version just uses the
line type to create the bars. It also returns a graphic handle (or
several if y is a matrix) and allows additional properties to be past to
the underlying plot command. Finally, though I haven't done it barh
might be trivially created from this file, by replacing

    varargout{1} = plot (xb, yb, newargs{:});

with

    varargout{1} = plot (yb, xb, newargs{:});

Unfortunately barh can't really be written as

function varargout = barh (varargin)
 [xb,yb] = bar(varargin{:});
 if (nargout > 1)
   varargout{1} = plot (yb,xb);
 else
   varargout{1} = xb;
   varargout{2} = yb;
 endif
endfunction

as this doesn't correctly treat all of the additional line properties
that might be passed to the plot command.

Regards
David
*** ./scripts/plot/bar.m.orig9  2007-04-05 18:14:09.000000000 +0200
--- ./scripts/plot/bar.m        2007-04-17 00:10:36.947765658 +0200
***************
*** 18,29 ****
  ## 02110-1301, USA.
  
  ## -*- texinfo -*-
! ## @deftypefn {Function File} {} bar (@var{x}, @var{y})
  ## 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 two output arguments are specified, the data are generated but
  ## not plotted.  For example,
  ##
--- 18,35 ----
  ## 02110-1301, USA.
  
  ## -*- texinfo -*-
! ## @deftypefn {Function File} address@hidden =} bar (@var{x}, @var{y}, 
@var{style})
! ## @deftypefnx {Function File} address@hidden, @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,
  ##
***************
*** 47,124 ****
  
  ## 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
  
  endfunction
--- 53,182 ----
  
  ## Author: jwe
  
! function varargout = bar (varargin)
  
!   width = 0.8;
!   group = true;
! 
!   if (nargin == 0)
!     print_usage()
!   endif
! 
!   if (nargin > 1 && 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 ("bar: x must be a vector");
!       endif
!       idx = 3;
      endif
    else
!     y = varargin{1};
!     if (isvector(y))
!       y = y(:);
!     endif
!     x = [1:size(y,1)]';
!     idx = 2;
    endif
+       
+   newargs = {};
+   while (idx <= nargin)
+     if (isstr(varargin{idx}) && strcmp(varargin{idx},"grouped"))
+       group = true;
+       idx++;
+     elseif (isstr(varargin{idx}) && strcmp(varargin{idx},"stacked"))
+       group = false;
+       idx++;
+     elseif (isscalar(varargin{idx}))
+       width = varargin{idx++};
+     elseif (idx == nargin)
+       newargs = [newargs,varargin(idx++)];
+     else
+       newargs = [newargs,varargin(idx:idx+1)];
+       idx += 2;
+     endif
+   endwhile
+ 
+   xlen = size (x, 1);
+   ylen = size (y, 1);
+   ycols = size (y, 2);
+   len = 5 * xlen;
+   xb = yb = zeros (len, ycols);
+   cutoff = (x(1:end-1) + x(2:end)) / 2;
+ 
+   if (group)
+     width = width / ycols;
+     offset = [-(ycols - 1) / 2 : (ycols - 1) / 2];
+   endif
+ 
+   for j = 1:ycols
+     delta_p = (cutoff(1) - x(1)) * width;
+     delta_m = delta_p;
+     k = 1;
+     for i = 1:5:len
+       if (group)
+       xb(i,j) = x(k) - delta_m + (delta_p + delta_m) * offset(j);
+       xb(i+1,j) = xb(i,j);
+       xb(i+2,j) = x(k) + delta_p + (delta_p + delta_m) * offset(j);
+       xb(i+3,j) = xb(i+2,j);
+       xb(i+4,j) = NaN;
+       else
+       xb(i,j) = x(k) - delta_m;
+       xb(i+1,j) = xb(i,j);
+       xb(i+2,j) = x(k) + delta_p;
+       xb(i+3,j) = xb(i+2,j);
+       xb(i+4,j) = NaN;
+       endif
+ 
+       if (group || j == 1)
+       yb(i,j) = 0.0;
+       yb(i+1,j) = y(k,j);
+       yb(i+2,j) = y(k,j);
+       yb(i+3,j) = 0.0;
+       yb(i+4,j) = NaN;
+       else
+       y0 = yb(i+1,j-1);
+       yb(i,j) = y0;
+       yb(i+1,j) = y0 + y(k,j);
+       yb(i+2,j) = y0 + y(k,j);
+       yb(i+3,j) = y0;
+       yb(i+4,j) = NaN;
+       endif
+ 
+       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)) * width;
+         k++;
+         if (k < xlen)
+           delta_p = (cutoff(k) - x(k)) * width;
+         else
+           delta_p = delta_m;
+         endif
+       endif
+     endfor
+   endfor
  
!   if (nargout < 2)
!     varargout{1} = plot (xb, yb, newargs{:});
    else
!     varargout{1} = xb;
!     varargout{2} = yb;
    endif
  
  endfunction
*** ./scripts/plot/hist.m.orig9 2006-10-17 15:39:12.000000000 +0200
--- ./scripts/plot/hist.m       2007-04-17 00:07:41.518764951 +0200
***************
*** 118,124 ****
      freq = freq / rows (y) * norm;
    endif
  
!   if (nargout > 0)
      if (arg_is_vector)
        nn = freq';
        xx = x';
--- 118,124 ----
      freq = freq / rows (y) * norm;
    endif
  
!   if (nargout > 1)
      if (arg_is_vector)
        nn = freq';
        xx = x';
***************
*** 127,133 ****
        xx = x;
      endif
    else
!     bar (x, freq);
    endif
  
  endfunction
--- 127,133 ----
        xx = x;
      endif
    else
!     nn = bar (x, freq, 1.0);
    endif
  
  endfunction

reply via email to

[Prev in Thread] Current Thread [Next in Thread]