Mercurial > octave
changeset 29071:d2f7fb06bce3
Fixed stacked bar chart handling of negative values (bug #58216)
* NEWS: Added note about bar and barh matching Matlab output to Matlab
compatibility section.
* __bar__.m: Updated input parsing to separately handle negative stacked
values.
* bar.m, barh.m: Added demo and input error handling BISTS.
* * *
(bug #58216)
author | Nicholas R. Jankowski <jankowskin@asme.org> |
---|---|
date | Tue, 17 Nov 2020 15:52:03 -0500 |
parents | ab3e0676b8d6 |
children | a0be96cd13c5 |
files | NEWS scripts/plot/draw/bar.m scripts/plot/draw/barh.m scripts/plot/draw/private/__bar__.m |
diffstat | 4 files changed, 54 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Nov 18 19:45:04 2020 -0800 +++ b/NEWS Tue Nov 17 15:52:03 2020 -0500 @@ -155,6 +155,12 @@ Matlab code, but for which Octave does not yet implement the functionality. By default, this warning is enabled. +- The functions `bar` and `barh` now handle stacked negative bar values +in a Matlab-compatible manner. Negative values now stack below the zero +axis independently of a positive value bars in the same stack. +Previously the negative bars could overlap positive bars depending on +drawing order. + ### Alphabetical list of new functions added in Octave 7 * `getpixelposition`
--- a/scripts/plot/draw/bar.m Wed Nov 18 19:45:04 2020 -0800 +++ b/scripts/plot/draw/bar.m Tue Nov 17 15:52:03 2020 -0500 @@ -124,7 +124,6 @@ [varargout{:}] = __bar__ (true, "bar", varargin{:}); endfunction - %!demo %! clf; %! y = rand (11, 1); @@ -144,3 +143,17 @@ %! clf; %! h = bar (rand (5, 3), "stacked"); %! title ("bar() graph with stacked style"); + +%!demo +%! clf; +%! y = -rand (3) .* eye (3) + rand (3) .* (! eye (3)); +%! h = bar (y, "stacked"); +%! title ("stacked bar() graph including intermingled negative values"); + +%% Test input validation +%!error bar () +%!error <Y must be numeric> bar ("foo") +%!error <X must be a vector> bar ([1 2; 3 4], [1 2 3 4]) +%!error <X vector values must be unique> bar ([1 2 3 3], [1 2 3 4]) +%!error <length of X and Y must be equal> bar ([1 2 3], [1 2 3 4]) +%!error <length of X and Y must be equal> bar ([1 2 3 4], [1 2 3])
--- a/scripts/plot/draw/barh.m Wed Nov 18 19:45:04 2020 -0800 +++ b/scripts/plot/draw/barh.m Tue Nov 17 15:52:03 2020 -0500 @@ -95,3 +95,17 @@ %! set (h(2), "facecolor", "g"); %! set (h(3), "facecolor", "b"); %! title ("barh() graph w/multiple bars"); + +%!demo +%! clf; +%! x = -rand (3) .* eye (3) + rand (3) .* (! eye (3)); +%! h = barh (x, "stacked"); +%! title ("stacked barh() graph including intermingled negative values"); + +%% Test input validation +%!error barh () +%!error <Y must be numeric> barh ("foo") +%!error <X must be a vector> barh ([1 2; 3 4], [1 2 3 4]) +%!error <X vector values must be unique> barh ([1 2 3 3], [1 2 3 4]) +%!error <length of X and Y must be equal> barh ([1 2 3], [1 2 3 4]) +%!error <length of X and Y must be equal> barh ([1 2 3 4], [1 2 3])
--- a/scripts/plot/draw/private/__bar__.m Wed Nov 18 19:45:04 2020 -0800 +++ b/scripts/plot/draw/private/__bar__.m Tue Nov 17 15:52:03 2020 -0500 @@ -38,6 +38,7 @@ width = 0.8; group = true; + stacked = false; histc = NA; ## BaseValue if (strcmp (get (hax, "yscale"), "log")) @@ -84,6 +85,7 @@ group = true; idx += 1; elseif (ischar (varargin{idx}) && strcmpi (varargin{idx}, "stacked")) + stacked = true; group = false; idx += 1; elseif (ischar (varargin{idx}) && strcmpi (varargin{idx}, "histc")) @@ -185,8 +187,24 @@ y0 = zeros (size (y)) + bv; y1 = y; else - y1 = cumsum (y,2); - y0 = [zeros(ngrp,1)+bv, y1(:,1:end-1)]; + if (stacked && any (y(:) < 0)) + ypos = (y >= 0); + yneg = (y < 0); + ypos = y .* ypos; + yneg = y .* yneg; + + y1p = cumsum (y .* ypos, 2); + y1n = cumsum (y .* yneg, 2); + y1 = y1p .* ypos + y1n .* yneg; + + y0p = [zeros(ngrp,1)+bv, y1p(:,1:end-1)]; + y0n = [zeros(ngrp,1)+bv, y1n(:,1:end-1)]; + y0 = y0p .* ypos + y0n .* yneg; + + else + y1 = cumsum (y,2); + y0 = [zeros(ngrp,1)+bv, y1(:,1:end-1)]; + endif endif yb = zeros (4*ngrp, nbars);