octave-maintainers
[Top][All Lists]
Advanced

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

Re: AW: Re: Rewritten version of bar.m


From: David Bateman
Subject: Re: AW: Re: Rewritten version of bar.m
Date: Wed, 18 Apr 2007 22:14:32 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

address@hidden wrote:
>> ----Ursprüngliche Nachricht----
>> Von: address@hidden
>> Datum: 18.04.2007 05:56
>> An: <address@hidden>
>> Kopie: "octave maintainers mailing list"<address@hidden>
>> Betreff: Re: Rewritten version of bar.m
>>
>> On 4/18/07, David Bateman <address@hidden> wrote:
>>> Shai Ayal wrote:
>>>> I'm sorry I don't have time to help right now, but have you 
> looked at
>>>> the bar/barh functions from octplot? They use patch objects.
>>>>
>>>> http://svn.sourceforge.
> net/viewvc/octplot/trunk/octplot/high_level/__bar.m?
> revision=432&view=markup
>>>>
>>>> Shai
>>>>
>>> Shai,
>>>
>>> Does it really need to be that complex? In any case in the core 
> we don't
>>> have patches yet, so this is a stopgap till someone adds 
> patches
>>> (probably after 3.0).
> 
> This code isn't optimized yet. But the complexity will be not 
> (strong) reduced even if the
> code will be optimized. 

See the attached version, where I vectorized the code as much as
possible, though I'm not sure it makes much sense to have a large number
of bars on the plot, and so we probably won't profit from the vectorization.

> The bar/barh arguments can be (almost) in any order and it will 
> work!
> BTW, matlabs code is much more complex without to know why ...
> 

I believe X and Y have to be the first and second argument of bar/barh.
I see no reason to accept them in any other position.

Most of the arguments passed to bar/barh are plot properties and can be
passed to the underlying patch or plot command to treat. Only the width,
"grouped" or "stacked" argument needs to be treated locally. So
identifying these arguments and removing them before. One complexity is
that properties come in pair, but bar/barh can have a LineSpec that is a
single argument, so something like

bar(x,y,'g',0.7,'LineWidth','1.5')

won't be easy to parse, using pltopt should simplify it though. I'd
tried to treat all of these issues previously, but missed the pltopt
issue. The attached version fixes that as well. As plot/patch does most
of the work the code is fairly simple relative to the octplot version.

> I can't help currently a lot because my wife has born a second son 
> and so we have a lot to do :-)

Two kids, three times the work ...

D.
*** ./scripts/plot/bar.m.orig9  2007-04-05 18:14:09.000000000 +0200
--- ./scripts/plot/bar.m        2007-04-18 21:54:09.539341524 +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,
  ##
***************
*** 41,124 ****
  ##
  ## @noindent
  ## are equivalent.
! ## @seealso{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
! 
  endfunction
--- 47,59 ----
  ##
  ## @noindent
  ## are equivalent.
! ## @seealso{hbar, plot, semilogx, semilogy, loglog, polar, mesh, contour,
  ## stairs, xlabel, ylabel, title}
  ## @end deftypefn
  
  ## Author: jwe
  
! function varargout = bar (varargin)
!   varargout = cell (nargout, 1);
!   [varargout{:}] = __bar__ (true, "bar", varargin{:});
  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
*** ./scripts/plot/__bar__.m.orig9      2007-04-18 21:56:21.327580949 +0200
--- ./scripts/plot/__bar__.m    2007-04-18 21:44:51.185984367 +0200
***************
*** 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
*** ./scripts/plot/hbar.m.orig9 2007-04-18 21:56:25.529365403 +0200
--- ./scripts/plot/hbar.m       2007-04-18 21:55:14.021033692 +0200
***************
*** 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} address@hidden =} hbar (@var{x}, @var{y}, 
@var{style})
+ ## @deftypefnx {Function File} address@hidden, @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

reply via email to

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