Mercurial > octave
changeset 33611:f958b36069d3
maint: Merge stable to default.
author | Nicholas R. Jankowski <jankowski.nicholas@gmail.com> |
---|---|
date | Sun, 19 May 2024 23:01:32 -0400 |
parents | 338a70ccc1bb (current diff) f5b433492c16 (diff) |
children | 23bb1d9fcec8 7f7d6bc5702b |
files | |
diffstat | 2 files changed, 1447 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/plot/draw/bar.m Sat May 18 22:39:14 2024 -0400 +++ b/scripts/plot/draw/bar.m Sun May 19 23:01:32 2024 -0400 @@ -147,6 +147,712 @@ %! h = bar (y, "stacked"); %! title ("stacked bar() graph including intermingled negative values"); +## Tests bar geometry without plotting, using undocumented [x, y] output form. +%!test +%! [x, y] = bar (1:3); +%! assert (x, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (y, [0, 0, 0; 1, 2, 3; 1, 2, 3; 0, 0, 0]); + +%!test +%! [x, y] = bar (1:3, 2:4); +%! assert (x, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (y, [0, 0, 0; 2, 3, 4; 2, 3, 4; 0, 0, 0]); + +%!test +%! [x, y] = bar (1:3, 2); +%! assert (x, [0, 1, 2; 0, 1, 2; 2, 3, 4; 2, 3, 4]); +%! assert (y, [0, 0, 0; 1, 2, 3; 1, 2, 3; 0, 0, 0]); + +%!test +%! [x, y] = bar (-1:1:1); +%! assert (x, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (y, [0, 0, 0; -1, 0, 1; -1, 0, 1; 0, 0, 0]); + +%!test +%! [x, y] = bar ([1, 2; 3, 4]); +%! assert (x, cat (3, [0.68, 1.68; 0.68, 1.68; 0.96, 1.96; 0.96, 1.96], ... +%! [1.04, 2.04; 1.04, 2.04; 1.32, 2.32; 1.32, 2.32]), 2*eps); +%! assert (y, cat (3, [0, 0; 1, 3; 1, 3; 0, 0], [0, 0; 2, 4; 2, 4; 0, 0])); + +%!test +%! [x, y] = bar ([1:3; 4:6]); +%! assert (x, cat (3, [2, 5; 2, 5; ; 64/25, 139/25; 64/25, 139/25]/3, ... +%! [68 143; 68 143; 82, 157; 82, 157]/75, ... +%! [86/25, 161/25; 86/25, 161/25; 4, 7; 4, 7]/3), 2*eps); +%! assert (y, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + +## Test styles +%!test +%! [x, y] = bar ([1:3, 4:6]); +%! [x1, y1] = bar ([1:3, 4:6], "grouped"); +%! assert (x, x1); +%! assert (y, y1); + +%!test +%! [x, y] = bar ([1:3; 4:6], "stacked"); +%! assert (x, cat (3, [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4], ... +%! [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4], ... +%! [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]), eps); +%! assert (y, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [1, 4; 3, 9; 3, 9; 1, 4], ... +%! [3, 9; 6, 15; 6, 15; 3, 9])); + +%!test +%! [x, y] = bar ([1:6], "hist"); +%! assert (x, [0.5:1:5.5; 0.5:1:5.5; 1.5:1:6.5; 1.5:1:6.5], eps); +%! assert (y, [zeros(1, 6); 1:6; 1:6; zeros(1, 6)]); + +%!test +%! [x, y] = bar ([1:3; 4:6], "hist"); +%! assert (x, cat (3, [17, 42; 17, 42; 67/3, 142/3; 67/3, 142/3]/25, ... +%! [67, 142; 67, 142; 83, 158; 83, 158]/75, ... +%! [83/3, 158/3; 83/3, 158/3; 33, 58; 33, 58]/25), 2*eps); +%! assert (y, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + +%!test +%! [x, y] = bar ([1:6], "histc"); +%! assert (x, [1:6; 1:6; 2:7; 2:7], eps); +%! assert (y, [zeros(1, 6); 1:6; 1:6; zeros(1, 6)]); + +%!test +%! [x, y] = bar ([1:3; 4:6], "histc"); +%! assert (x, cat (3, [75, 150; 75, 150; 91, 166; 91, 166]/75, ... +%! [91, 166; 91, 166; 107, 182; 107, 182]/75, ... +%! [107/3, 182/3; 107/3, 182/3; 41, 66; 41, 66]/25), 2*eps); +%! assert (y, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + +## Test plotting +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! axesdata = get (hax); +%! +%! assert (isfield (bardata, "bargroup")); +%! assert (isfield (bardata, "barlayout")); +%! assert (isfield (bardata, "barwidth")); +%! assert (isfield (bardata, "baseline")); +%! assert (isfield (bardata, "basevalue")); +%! assert (isfield (bardata, "horizontal")); +%! assert (isfield (bardata, "showbaseline")); +%! assert (isfield (bardata, "xdata")); +%! assert (isfield (bardata, "ydata")); +%! +%! assert (bardata.parent, hax); +%! assert (bardata.bargroup, hb); +%! assert (bardata.type, "hggroup"); +%! assert (bardata.barlayout, "grouped"); +%! assert (bardata.barwidth, 0.8); +%! assert (bardata.basevalue, 0); +%! assert (bardata.horizontal, "off"); +%! assert (bardata.showbaseline, "on"); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (baselinedata.type, "line"); +%! assert (baselinedata.ydata, [0, 0]); +%! assert (diff (baselinedata.xdata) > 0); +%! assert (baselinedata.color, [0, 0, 0]); +%! assert (baselinedata.linestyle, "-"); +%! +%! assert (patchdata.type, "patch"); +%! assert (patchdata.xdata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.ydata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! assert (axesdata.xscale, "linear"); +%! assert (axesdata.xlim, [0.5, 3.5]); +%! assert (axesdata.xtick, 1:3); +%! assert (get(hax, 'xticklabel'), {"1"; "2"; "3"}); +%! assert (axesdata.yscale, "linear"); +%! assert (axesdata.ylim, [0, 4]); +%! assert (axesdata.ytick, 0:4); +%! assert (axesdata.yticklabel, {"0"; "1"; "2"; "3"; "4"}); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Style stacked (no difference for single group). +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4, "grouped"); +%! bardata1 = get (hb); +%! hl = bardata1.baseline; +%! baselinedata1 = get (hl); +%! hp = bardata1.children; +%! patchdata1 = get (hp); +%! +%! hb = bar (hax, 2:4, "stacked"); +%! bardata2 = get (hb); +%! hl = bardata2.baseline; +%! baselinedata2 = get (hl); +%! hp = bardata2.children; +%! patchdata2 = get (hp); +%! +%! assert (bardata1.barlayout, "grouped"); +%! assert (bardata2.barlayout, "stacked"); +%! bardata1.bargroup = []; +%! bardata1.barlayout = []; +%! bardata1.baseline = []; +%! bardata1.children = []; +%! +%! bardata2.bargroup = []; +%! bardata2.barlayout = []; +%! bardata2.baseline = []; +%! bardata2.children = []; +%! +%! patchdata1.parent = []; +%! patchdata2.parent = []; +%! +%! assert (isequaln (bardata1, bardata2)); +%! assert (isequaln (baselinedata1, baselinedata2)); +%! assert (isequaln (patchdata1, patchdata2)); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Style hist. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4, "hist"); +%! bardata = get (hb); +%! assert (isempty (bardata.children)); +%! assert (! isfield (bardata, "baseline")); +%! assert (! isfield (bardata, "barlayout")); +%! assert (! isfield (bardata, "barwidth")); +%! assert (bardata.type, "patch"); +%! assert (bardata.xdata, [0.5, 1.5, 2.5; ... +%! 0.5, 1.5, 2.5; ... +%! 1.5, 2.5, 3.5; ... +%! 1.5, 2.5, 3.5], eps); +%! assert (bardata.ydata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (bardata.faces), [3, 4]); +%! assert (size (bardata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Style histc. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4, "histc"); +%! bardata = get (hb); +%! assert (isempty (bardata.children)); +%! assert (! isfield (bardata, "baseline")); +%! assert (! isfield (bardata, "barlayout")); +%! assert (! isfield (bardata, "barwidth")); +%! assert (bardata.type, "patch"); +%! assert (bardata.xdata, [1:3; 1:3; 2:4; 2:4]); +%! assert (bardata.ydata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (bardata.faces), [3, 4]); +%! assert (size (bardata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Bar groups grouped. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, [1:3; 4:6]); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'grouped'))); +%! assert (all (strcmp ({bardata.horizontal}, 'off'))); +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (patchdata(1).xdata, [2, 5; ... +%! 2, 5; ... +%! 64/25, 139/25; ... +%! 64/25, 139/25]/3, eps); +%! assert (patchdata(1).ydata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Bar groups stacked. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, [1:3; 4:6], "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert (all (strcmp ({bardata.horizontal}, 'off'))); +%! +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (all (cellfun (@isequal, {patchdata.xdata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).ydata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (patchdata(2).ydata, [1, 4; 3, 9; 3, 9; 1, 4]); +%! assert (patchdata(3).ydata, [3, 9; 6, 15; 6, 15; 3, 9]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Stacked with negative values. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, [-2, 1, 3; 4, -5, 6], "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert (all (strcmp ({bardata.horizontal}, 'off'))); +%! +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [-2, 1, 3; 4, -5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (all (cellfun (@isequal, {patchdata.xdata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).ydata, [0, 0; -2, 4; -2, 4; 0, 0]); +%! assert (patchdata(2).ydata, [0, 0; 1, -5; 1, -5; 0, 0]); +%! assert (patchdata(3).ydata, [1, 4; 4, 10; 4, 10; 1, 4]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Test plot property settings/updates +## Note - Not testing plot and children visibile settings to avoid creating +## test suite artifacts. + +## Switch from grouped to stacked. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, [1:3; 4:6], "grouped"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! ## Verify base behavior. +%! assert (all (strcmp ({bardata.barlayout}, 'grouped'))); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! assert (patchdata(1).xdata, [2, 5; ... +%! 2, 5; ... +%! 64/25, 139/25; ... +%! 64/25, 139/25]/3, eps); +%! assert (patchdata(1).ydata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! +%! ## Verify changed behavior. +%! set (hb, "barlayout", "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! assert (all (cellfun (@isequal, {patchdata.xdata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).ydata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (patchdata(2).ydata, [1, 4; 3, 9; 3, 9; 1, 4]); +%! assert (patchdata(3).ydata, [3, 9; 6, 15; 6, 15; 3, 9]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Non-zero baseline +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4, "basevalue", 3); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.basevalue, 3); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (baselinedata.ydata, [3, 3]); +%! assert (diff (baselinedata.xdata) > 0); +%! +%! assert (patchdata.xdata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.ydata, [3, 3, 3; 2:4; 2:4; 3, 3, 3]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Color settings: +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4, "facecolor", "r", "edgecolor", "g"); +%! bardata = get (hb); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.facecolor, [1, 0, 0]); +%! assert (bardata.edgecolor, [0, 1, 0]); +%! assert (patchdata.facecolor, [1, 0, 0]); +%! assert (patchdata.edgecolor, [0, 1, 0]); +%! +%! set (hb, "facecolor", "b"); +%! assert (get (hb, "facecolor"), [0, 0, 1]); +%! assert (get (hp, "facecolor"), [0, 0, 1]); +%! set (hb, "edgecolor", "k"); +%! assert (get (hb, "edgecolor"), [0, 0, 0]); +%! assert (get (hp, "edgecolor"), [0, 0, 0]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, [1:3; 4:6], "facecolor", "r", "edgecolor", "g"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (all (vertcat (bardata.facecolor) == [1, 0, 0])); +%! assert (all (vertcat (bardata.edgecolor) == [0, 1, 0])); +%! assert (all (vertcat (patchdata.facecolor) == [1, 0, 0])); +%! assert (all (vertcat (patchdata.edgecolor) == [0, 1, 0])); +%! +%! set (hb, "facecolor", "b"); +%! set (hb, "edgecolor", "k"); +%! bardata = get (hb); +%! patchdata = get (hp); +%! assert (all (vertcat (bardata.facecolor) == [0, 0, 1])); +%! assert (all (vertcat (bardata.edgecolor) == [0, 0, 0])); +%! assert (all (vertcat (patchdata.facecolor) == [0, 0, 1])); +%! assert (all (vertcat (patchdata.edgecolor) == [0, 0, 0])); +%! +%! set (hb(2), "facecolor", "w"); +%! set (hb(2), "edgecolor", "r"); +%! bardata = get (hb); +%! patchdata = get (hp); +%! assert (all (vertcat (bardata([1,3]).facecolor) == [0, 0, 1])); +%! assert (all (vertcat (bardata([1,3]).edgecolor) == [0, 0, 0])); +%! assert (all (vertcat (patchdata([1,3]).facecolor) == [0, 0, 1])); +%! assert (all (vertcat (patchdata([1,3]).edgecolor) == [0, 0, 0])); +%! assert (bardata(2).facecolor, [1, 1, 1]); +%! assert (bardata(2).edgecolor, [1, 0, 0]); +%! assert (patchdata(2).facecolor, [1, 1, 1]); +%! assert (patchdata(2).edgecolor, [1, 0, 0]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Change to horizontal: + +%!test <65671> # Baseline should change to horizontal with bars. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! +%! set (hb, "horizontal", "on"); +%! +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.horizontal, "on"); +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (baselinedata.xdata, [0, 0]); +%! assert (diff (baselinedata.ydata) > 0); +%! +%! assert (patchdata.ydata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.xdata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test <65734> # Axis ticks after change to horizontal should match barh. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! +%! set (hb, "horizontal", "on"); +%! +%! bardata = get (hb); +%! axesdata = get (hax); +%! +%! assert (bardata.horizontal, "on"); +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (axesdata.yscale, "linear"); +%! assert (axesdata.ylim, [0.5, 3.5]); +%! assert (axesdata.ytick, 1:3); +%! assert (get(hax, 'yticklabel'), {"1"; "2"; "3"}); +%! assert (axesdata.xscale, "linear"); +%! assert (axesdata.xlim, [0, 4]); +%! assert (axesdata.xtick, 0:4); +%! assert (axesdata.xticklabel, {"0"; "1"; "2"; "3"; "4"}); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Check baseline updating subfunctions. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! assert (baselinedata.ydata, [0, 0]); +%! assert (baselinedata.xdata, [0.5, 3.5], eps); +%! assert (patchdata.xdata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.ydata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! +%! set (hax, "xlim", [0, 5]); # Change axes limits, verify baseline match. +%! assert (get (hl, "xdata"), [0, 5]); +%! +%! set (hb, "basevalue", 2); # Change line position through bar object. +%! axesdata = get (hax); +%! assert (get (hb, "basevalue"), 2); +%! assert (get (hl, "ydata"), [2, 2]); +%! assert (axesdata.ylim, [2, 4]); +%! assert (axesdata.ytick, [2:0.5:4], eps); +%! assert (axesdata.yticklabel, {"2"; "2.5"; "3"; "3.5"; "4"}); +%! assert (get (hp, "ydata"), [2, 2, 2; 2:4; 2:4; 2, 2, 2]); +%! +%! set (hl, "ydata", [-1 -1]); # Change line position directly. +%! axesdata = get (hax); +%! assert (get (hb, "basevalue"), -1); +%! assert (get (hl, "ydata"), [-1, -1]); +%! assert (axesdata.ylim, [-1, 4]); +%! assert (axesdata.ytick, [-1:4], eps); +%! assert (axesdata.yticklabel, {"-1"; "0"; "1"; "2"; "3"; "4"}); +%! assert (get (hp, "ydata"), [-1, -1, -1; 2:4; 2:4; -1, -1, -1]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Change linear/log scale and move baseline/patch values if needed. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! assert (baselinedata.ydata, [0, 0]); +%! assert (baselinedata.xdata, [0.5, 3.5], eps); +%! assert (get (hax, "yscale"), "linear"); +%! assert (get (hp, "ydata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! +%! warning ("off", "Octave:negative-data-log-axis", "local"); +%! set (hax, "yscale", "log"); +%! assert (get (hax, "yscale"), "log"); +%! assert (get (hb, "basevalue"), 1); +%! assert (get (hl, "ydata"), [1, 1]); +%! assert (get (hp, "ydata"), [1, 1, 1; 2:4; 2:4; 1, 1, 1]); +%! +%! set (hax, "yscale", "linear"); +%! assert (get (hax, "yscale"), "linear"); +%! assert (get (hb, "basevalue"), 0); +%! assert (get (hl, "ydata"), [0, 0]); +%! assert (get (hp, "ydata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating base plot xdata. +%!test <65734> # changing xdata should update xlim/ticks for new locations. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! xd = [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4]; +%! +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "xdata"), xd, eps); +%! assert (get (hax, "xlim"), [0.5, 3.5], eps); +%! assert (get (hax, "xtick"), 1:3); +%! assert (get (hax, "xticklabel"), {"1"; "2"; "3"}); +%! +%! ## Verify changed behavior. +%! set (hb, "xdata", [3:5]'); +%! assert (get (hb, "xdata"), [3:5]'); +%! assert (get (hp, "xdata"), xd + 2, eps); +%! assert (get (hax, "xlim"), [0.5, 3.5] + 2, eps); +%! assert (get (hax, "xtick"), 3:5); +%! assert (get (hax, "xticklabel"), {"3"; "4"; "5"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating base plot ydata. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "ydata"), [2:4]'); +%! assert (get (hp, "ydata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (get (hax, "ylim"), [0, 4]); +%! assert (get (hax, "ytick"), 0:4); +%! assert (get (hax, "yticklabel"), {"0"; "1"; "2"; "3"; "4"}); +%! +%! ## Verify changed behavior. +%! set (hb, "ydata", [-2, 1, 3]'); +%! assert (get (hb, "ydata"), [-2, 1, 3]'); +%! assert (get (hp, "ydata"), [0, 0, 0; -2, 1, 3; -2, 1, 3; 0, 0, 0]); +%! assert (get (hax, "ylim"), [-2, 3]); +%! assert (get (hax, "ytick"), -2:3); +%! assert (get (hax, "yticklabel"), {"-2"; "-1"; "0"; "1"; "2"; "3"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating barwidth. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = bar (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "barwidth"), 0.8, eps); +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "xdata"), [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! +%! ## Verify changed behavior. +%! set (hb, "barwidth", 0.5); +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "xdata"), [0.75, 1.75, 2.75; ... +%! 0.75, 1.75, 2.75; ... +%! 1.25, 2.25, 3.25; ... +%! 1.25, 2.25, 3.25], eps); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + + %% Test input validation %!error <Invalid call> bar () %!error <Y must be numeric> bar ("foo")
--- a/scripts/plot/draw/barh.m Sat May 18 22:39:14 2024 -0400 +++ b/scripts/plot/draw/barh.m Sun May 19 23:01:32 2024 -0400 @@ -77,6 +77,9 @@ ## @end deftypefn function varargout = barh (varargin) + if (nargin < 1) + print_usage; + endif varargout = cell (nargout, 1); [varargout{:}] = __bar__ ("barh", false, varargin{:}); endfunction @@ -102,8 +105,745 @@ %! h = barh (x, "stacked"); %! title ("stacked barh() graph including intermingled negative values"); +## Tests of bar geometry without plotting, using undocumented [x, y] output +%!test +%! [x, y] = barh (1:3); +%! assert (y, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (x, [0, 0, 0; 1, 2, 3; 1, 2, 3; 0, 0, 0]); + +%!test +%! [x, y] = barh (1:3, 2:4); +%! assert (y, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (x, [0, 0, 0; 2, 3, 4; 2, 3, 4; 0, 0, 0]); + +%!test +%! [x, y] = barh (1:3, 2); +%! assert (y, [0, 1, 2; 0, 1, 2; 2, 3, 4; 2, 3, 4]); +%! assert (x, [0, 0, 0; 1, 2, 3; 1, 2, 3; 0, 0, 0]); + +%!test +%! [x, y] = barh (-1:1:1); +%! assert (y, [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4], eps); +%! assert (x, [0, 0, 0; -1, 0, 1; -1, 0, 1; 0, 0, 0]); + +%!test +%! [x, y] = barh ([1, 2; 3, 4]); +%! assert (y, cat (3, [0.68, 1.68; 0.68, 1.68; 0.96, 1.96; 0.96, 1.96], ... +%! [1.04, 2.04; 1.04, 2.04; 1.32, 2.32; 1.32, 2.32]), 2*eps); +%! assert (x, cat (3, [0, 0; 1, 3; 1, 3; 0, 0], [0, 0; 2, 4; 2, 4; 0, 0])); + +%!test +%! [x, y] = barh ([1:3; 4:6]); +%! assert (y, cat (3, [2, 5; 2, 5; ; 64/25, 139/25; 64/25, 139/25]/3, ... +%! [68 143; 68 143; 82, 157; 82, 157]/75, ... +%! [86/25, 161/25; 86/25, 161/25; 4, 7; 4, 7]/3), 2*eps); +%! assert (x, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + +## Test styles grouped staced hist histc +%!test +%! [x, y] = barh ([1:3, 4:6]); +%! [x1, y1] = barh ([1:3, 4:6], "grouped"); +%! assert (x, x1); +%! assert (y, y1); + +%!test +%! [x, y] = barh ([1:3; 4:6], "stacked"); +%! assert (y, cat (3, [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4], ... +%! [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4], ... +%! [0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]), eps); +%! assert (x, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [1, 4; 3, 9; 3, 9; 1, 4], ... +%! [3, 9; 6, 15; 6, 15; 3, 9])); + +%!test +%! [x, y] = barh ([1:6], "hist"); +%! assert (y, [0.5:1:5.5; 0.5:1:5.5; 1.5:1:6.5; 1.5:1:6.5], eps); +%! assert (x, [zeros(1, 6); 1:6; 1:6; zeros(1, 6)]); + +%!test +%! [x, y] = barh ([1:3; 4:6], "hist"); +%! assert (y, cat (3, [17, 42; 17, 42; 67/3, 142/3; 67/3, 142/3]/25, ... +%! [67, 142; 67, 142; 83, 158; 83, 158]/75, ... +%! [83/3, 158/3; 83/3, 158/3; 33, 58; 33, 58]/25), 2*eps); +%! assert (x, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + +%!test +%! [x, y] = barh ([1:6], "histc"); +%! assert (y, [1:6; 1:6; 2:7; 2:7], eps); +%! assert (x, [zeros(1, 6); 1:6; 1:6; zeros(1, 6)]); + +%!test +%! [x, y] = barh ([1:3; 4:6], "histc"); +%! assert (y, cat (3, [75, 150; 75, 150; 91, 166; 91, 166]/75, ... +%! [91, 166; 91, 166; 107, 182; 107, 182]/75, ... +%! [107/3, 182/3; 107/3, 182/3; 41, 66; 41, 66]/25), 2*eps); +%! assert (x, cat (3, [0, 0; 1, 4; 1, 4; 0, 0], ... +%! [0, 0; 2, 5; 2, 5; 0, 0], ... +%! [0, 0; 3, 6; 3, 6; 0, 0])); + + +## Test plotting +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! axesdata = get (hax); +%! +%! assert (isfield (bardata, "bargroup")); +%! assert (isfield (bardata, "barlayout")); +%! assert (isfield (bardata, "barwidth")); +%! assert (isfield (bardata, "baseline")); +%! assert (isfield (bardata, "basevalue")); +%! assert (isfield (bardata, "horizontal")); +%! assert (isfield (bardata, "showbaseline")); +%! assert (isfield (bardata, "xdata")); +%! assert (isfield (bardata, "ydata")); +%! +%! assert (bardata.parent, hax); +%! assert (bardata.bargroup, hb); +%! assert (bardata.type, "hggroup"); +%! assert (bardata.barlayout, "grouped"); +%! assert (bardata.barwidth, 0.8); +%! assert (bardata.basevalue, 0); +%! assert (bardata.horizontal, "on"); +%! assert (bardata.showbaseline, "on"); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (patchdata.type, "patch"); +%! assert (patchdata.ydata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.xdata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Baseline must be vertical for barh. +%!test <65671> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! hl = get (hb, "baseline"); +%! baselinedata = get (hl); +%! +%! assert (baselinedata.type, "line"); +%! assert (baselinedata.xdata, [0, 0]); +%! assert (diff (baselinedata.ydata) > 0); +%! assert (baselinedata.color, [0, 0, 0]); +%! assert (baselinedata.linestyle, "-"); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## barh axes limits and labels should match inverse of bar. +%!test <65671> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! axesdata = get (hax); +%! assert (axesdata.ylim, [0.5, 3.5]); +%! assert (axesdata.ytick, 1:3); +%! assert (axesdata.yticklabel, {"1"; "2"; "3"}); +%! assert (axesdata.xscale, "linear"); +%! assert (axesdata.xlim, [0, 4]); +%! assert (axesdata.xtick, 0:4); +%! assert (axesdata.xticklabel, {"0"; "1"; "2"; "3"; "4"}); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Style stacked (no difference for single group). +%!test +%! hf1 = figure ("visible", "off"); +%! hf2 = figure ("visible", "off"); +%! unwind_protect +%! hax1 = axes ("parent", hf1); +%! hb1 = barh (hax1, 2:4, "grouped"); +%! bardata1 = get (hb1); +%! hl1 = bardata1.baseline; +%! baselinedata1 = get (hl1); +%! hp1 = bardata1.children; +%! patchdata1 = get (hp1); +%! +%! hax2 = axes ("parent", hf2); +%! hb2 = barh (hax2, 2:4, "stacked"); +%! bardata2 = get (hb2); +%! hl2 = bardata2.baseline; +%! baselinedata2 = get (hl2); +%! hp2 = bardata2.children; +%! patchdata2 = get (hp2); +%! +%! assert (bardata1.barlayout, "grouped"); +%! assert (bardata2.barlayout, "stacked"); +%! bardata1.bargroup = []; +%! bardata1.barlayout = []; +%! bardata1.baseline = []; +%! bardata1.children = []; +%! bardata1.parent = []; +%! +%! bardata2.bargroup = []; +%! bardata2.barlayout = []; +%! bardata2.baseline = []; +%! bardata2.children = []; +%! bardata2.parent = []; +%! +%! baselinedata1.parent = []; +%! baselinedata2.parent = []; +%! +%! patchdata1.parent = []; +%! patchdata2.parent = []; +%! +%! assert (isequaln (bardata1, bardata2)); +%! assert (isequaln (baselinedata1, baselinedata2)); +%! assert (isequaln (patchdata1, patchdata2)); +%! +%! unwind_protect_cleanup +%! close (hf1); +%! close (hf2); +%! end_unwind_protect + +## Style hist. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4, "hist"); +%! bardata = get (hb); +%! assert (isempty (bardata.children)); +%! assert (! isfield (bardata, "baseline")); +%! assert (! isfield (bardata, "barlayout")); +%! assert (! isfield (bardata, "barwidth")); +%! assert (bardata.type, "patch"); +%! assert (bardata.ydata, [0.5, 1.5, 2.5; ... +%! 0.5, 1.5, 2.5; ... +%! 1.5, 2.5, 3.5; ... +%! 1.5, 2.5, 3.5], eps); +%! assert (bardata.xdata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (bardata.faces), [3, 4]); +%! assert (size (bardata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Style histc. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4, "histc"); +%! bardata = get (hb); +%! assert (isempty (bardata.children)); +%! assert (! isfield (bardata, "baseline")); +%! assert (! isfield (bardata, "barlayout")); +%! assert (! isfield (bardata, "barwidth")); +%! assert (bardata.type, "patch"); +%! assert (bardata.ydata, [1:3; 1:3; 2:4; 2:4]); +%! assert (bardata.xdata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (bardata.faces), [3, 4]); +%! assert (size (bardata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Bar groups grouped. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, [1:3; 4:6]); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'grouped'))); +%! assert (all (strcmp ({bardata.horizontal}, 'on'))); +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (patchdata(1).ydata, [2, 5; ... +%! 2, 5; ... +%! 64/25, 139/25; ... +%! 64/25, 139/25]/3, eps); +%! assert (patchdata(1).xdata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Bar groups stacked. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, [1:3; 4:6], "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert (all (strcmp ({bardata.horizontal}, 'on'))); +%! +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (all (cellfun (@isequal, {patchdata.ydata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).xdata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (patchdata(2).xdata, [1, 4; 3, 9; 3, 9; 1, 4]); +%! assert (patchdata(3).xdata, [3, 9; 6, 15; 6, 15; 3, 9]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Stacked with negative values. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, [-2, 1, 3; 4, -5, 6], "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (numel (hb), 3); +%! assert (numel (hp), 3); +%! assert (all (strcmp ({bardata.type}, 'hggroup'))); +%! assert (bardata(1).baseline, bardata(2).baseline); # Common baseline +%! assert (bardata(1).baseline, bardata(3).baseline); # Common baseline +%! assert (bardata(1).bargroup, bardata(2).bargroup); # Common hggroup +%! assert (bardata(1).bargroup, bardata(3).bargroup); # Common hggroup +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert (all (strcmp ({bardata.horizontal}, 'on'))); +%! +%! assert ([bardata.basevalue], [0, 0, 0]); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [-2, 1, 3; 4, -5, 6]); +%! +%! assert (all (strcmp ({patchdata.type}, 'patch'))); +%! assert (all (cellfun (@isequal, {patchdata.ydata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).xdata, [0, 0; -2, 4; -2, 4; 0, 0]); +%! assert (patchdata(2).xdata, [0, 0; 1, -5; 1, -5; 0, 0]); +%! assert (patchdata(3).xdata, [1, 4; 4, 10; 4, 10; 1, 4]); +%! assert (size (patchdata(1).faces), [2, 4]); +%! assert (size (patchdata(1).vertices), [8, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Test plot property settings/updates +## Note - Not testing plot and children visibility settings to avoid creating +## test suite artifacts. + +## Switch from grouped to stacked. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, [1:3; 4:6], "grouped"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! ## Verify base behavior. +%! assert (all (strcmp ({bardata.barlayout}, 'grouped'))); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! assert (patchdata(1).ydata, [2, 5; ... +%! 2, 5; ... +%! 64/25, 139/25; ... +%! 64/25, 139/25]/3, eps); +%! assert (patchdata(1).xdata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! +%! ## Verify changed behavior. +%! set (hb, "barlayout", "stacked"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (all (strcmp ({bardata.barlayout}, 'stacked'))); +%! assert ([bardata.xdata], [1, 1, 1; 2, 2, 2]); +%! assert ([bardata.ydata], [1, 2, 3; 4, 5, 6]); +%! assert (all (cellfun (@isequal, {patchdata.ydata}, ... +%! {[0.6, 1.6; 0.6, 1.6; 1.4, 2.4; 1.4, 2.4]}))); +%! assert (patchdata(1).xdata, [0, 0; 1, 4; 1, 4; 0, 0]); +%! assert (patchdata(2).xdata, [1, 4; 3, 9; 3, 9; 1, 4]); +%! assert (patchdata(3).xdata, [3, 9; 6, 15; 6, 15; 3, 9]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Non-zero baseline +%!test <65671> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4, "basevalue", 3); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.basevalue, 3); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (baselinedata.xdata, [3, 3]); +%! assert (diff (baselinedata.ydata) > 0); +%! +%! assert (patchdata.ydata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.xdata, [3, 3, 3; 2:4; 2:4; 3, 3, 3]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Color setting and changing: +%!test # Single group +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4, "facecolor", "r", "edgecolor", "g"); +%! bardata = get (hb); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.facecolor, [1, 0, 0]); +%! assert (bardata.edgecolor, [0, 1, 0]); +%! assert (patchdata.facecolor, [1, 0, 0]); +%! assert (patchdata.edgecolor, [0, 1, 0]); +%! +%! set (hb, "facecolor", "b"); +%! assert (get (hb, "facecolor"), [0, 0, 1]); +%! assert (get (hp, "facecolor"), [0, 0, 1]); +%! set (hb, "edgecolor", "k"); +%! assert (get (hb, "edgecolor"), [0, 0, 0]); +%! assert (get (hp, "edgecolor"), [0, 0, 0]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test # Multiple groups +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, [1:3; 4:6], "facecolor", "r", "edgecolor", "g"); +%! bardata = get (hb); +%! hp = [bardata.children](:); +%! patchdata = get (hp); +%! +%! assert (all (vertcat (bardata.facecolor) == [1, 0, 0])); +%! assert (all (vertcat (bardata.edgecolor) == [0, 1, 0])); +%! assert (all (vertcat (patchdata.facecolor) == [1, 0, 0])); +%! assert (all (vertcat (patchdata.edgecolor) == [0, 1, 0])); +%! +%! set (hb, "facecolor", "b"); +%! set (hb, "edgecolor", "k"); +%! bardata = get (hb); +%! patchdata = get (hp); +%! assert (all (vertcat (bardata.facecolor) == [0, 0, 1])); +%! assert (all (vertcat (bardata.edgecolor) == [0, 0, 0])); +%! assert (all (vertcat (patchdata.facecolor) == [0, 0, 1])); +%! assert (all (vertcat (patchdata.edgecolor) == [0, 0, 0])); +%! +%! set (hb(2), "facecolor", "w"); +%! set (hb(2), "edgecolor", "r"); +%! bardata = get (hb); +%! patchdata = get (hp); +%! assert (all (vertcat (bardata([1,3]).facecolor) == [0, 0, 1])); +%! assert (all (vertcat (bardata([1,3]).edgecolor) == [0, 0, 0])); +%! assert (all (vertcat (patchdata([1,3]).facecolor) == [0, 0, 1])); +%! assert (all (vertcat (patchdata([1,3]).edgecolor) == [0, 0, 0])); +%! assert (bardata(2).facecolor, [1, 1, 1]); +%! assert (bardata(2).edgecolor, [1, 0, 0]); +%! assert (patchdata(2).facecolor, [1, 1, 1]); +%! assert (patchdata(2).edgecolor, [1, 0, 0]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Change from horizontal: +%!test <65671> # Baseline should change to/from horizontal with bars. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! +%! set (hb, "horizontal", "off"); +%! +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.horizontal, "off"); +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (baselinedata.ydata, [0, 0]); +%! assert (diff (baselinedata.xdata) > 0); +%! +%! assert (patchdata.xdata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! assert (patchdata.ydata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (size (patchdata.faces), [3, 4]); +%! assert (size (patchdata.vertices), [12, 2]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test <65734> # Axis ticks after change from horizontal should match bar. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! +%! set (hb, "horizontal", "off"); +%! +%! bardata = get (hb); +%! axesdata = get (hax); +%! +%! assert (bardata.horizontal, "off"); +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! +%! assert (axesdata.xscale, "linear"); +%! assert (axesdata.xlim, [0.5, 3.5]); +%! assert (axesdata.xtick, 1:3); +%! assert (axesdata.xticklabel, {"1"; "2"; "3"}); +%! assert (axesdata.yscale, "linear"); +%! assert (axesdata.ylim, [0, 4]); +%! assert (axesdata.ytick, 0:4); +%! assert (axesdata.yticklabel, {"0"; "1"; "2"; "3"; "4"}); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Change linear/log scale and move baseline/patch values if needed. +%!test <65671> +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! assert (baselinedata.xdata, [0, 0]); +%! assert (baselinedata.ydata, [0.5, 3.5], eps); +%! assert (get (hax, "xscale"), "linear"); +%! assert (get (hp, "xdata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! +%! warning ("off", "Octave:negative-data-log-axis", "local"); +%! set (hax, "xscale", "log"); +%! assert (get (hax, "xscale"), "log"); +%! assert (get (hb, "basevalue"), 1); +%! assert (get (hl, "xdata"), [1, 1]); +%! assert (get (hp, "xdata"), [1, 1, 1; 2:4; 2:4; 1, 1, 1]); +%! +%! set (hax, "xscale", "linear"); +%! assert (get (hax, "xscale"), "linear"); +%! assert (get (hb, "basevalue"), 0); +%! assert (get (hl, "xdata"), [0, 0]); +%! assert (get (hp, "xdata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Check baseline updating subfunctions +%!test <65671> # Baseline move or basevalue change: update line, bar, patch. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! bardata = get (hb); +%! hl = bardata.baseline; +%! baselinedata = get (hl); +%! hp = bardata.children; +%! patchdata = get (hp); +%! +%! assert (bardata.basevalue, 0); +%! assert (bardata.xdata, [1; 2; 3]); +%! assert (bardata.ydata, [2; 3; 4]); +%! assert (baselinedata.xdata, [0, 0]); +%! assert (baselinedata.ydata, [0.5, 3.5], eps); +%! assert (patchdata.xdata, [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (patchdata.ydata, [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! +%! set (hax, "ylim", [0, 5]); # Change axes limits, verify baseline match. +%! assert (get (hl, "ydata"), [0, 5]); +%! +%! set (hb, "basevalue", 2); # Change line position through bar object. +%! axesdata = get (hax); +%! assert (get (hb, "basevalue"), 2); +%! assert (get (hl, "xdata"), [2, 2]); +%! assert (axesdata.xlim, [2, 4]); +%! assert (axesdata.xtick, [2:0.5:4], eps); +%! assert (axesdata.xticklabel, {"2"; "2.5"; "3"; "3.5"; "4"}); +%! assert (get (hp, "xdata"), [2, 2, 2; 2:4; 2:4; 2, 2, 2]); +%! +%! set (hl, "xdata", [-1 -1]); # Change line position directly. +%! axesdata = get (hax); +%! assert (get (hb, "basevalue"), -1); +%! assert (get (hl, "xdata"), [-1, -1]); +%! assert (axesdata.xlim, [-1, 4]); +%! assert (axesdata.xtick, [-1:4]); +%! assert (axesdata.xticklabel, {"-1"; "0"; "1"; "2"; "3"; "4"}); +%! assert (get (hp, "xdata"), [-1, -1, -1; 2:4; 2:4; -1, -1, -1]); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating base plot ydata. +%!test <65734> # changing xdata should update xlim/ticks for new locations. +%! hf = figure ("visible", "off"); +%! unwind_protect +%! yd = [0.6, 1.6, 2.6; 0.6, 1.6, 2.6; 1.4, 2.4, 3.4; 1.4, 2.4, 3.4]; +%! +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "ydata"), yd, eps); +%! assert (get (hax, "ylim"), [0.5, 3.5], eps); +%! assert (get (hax, "ytick"), 1:3); +%! assert (get (hax, "yticklabel"), {"1"; "2"; "3"}); +%! +%! ## Verify changed behavior. +%! set (hb, "xdata", [3:5]'); +%! assert (get (hb, "xdata"), [3:5]'); +%! assert (get (hp, "ydata"), yd + 2, eps); +%! assert (get (hax, "ylim"), [0.5, 3.5] + 2, eps); +%! assert (get (hax, "ytick"), 3:5); +%! assert (get (hax, "yticklabel"), {"3"; "4"; "5"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating base plot xdata. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "ydata"), [2:4]'); +%! assert (get (hp, "xdata"), [0, 0, 0; 2:4; 2:4; 0, 0, 0]); +%! assert (get (hax, "xlim"), [0, 4]); +%! assert (get (hax, "xtick"), 0:4); +%! assert (get (hax, "xticklabel"), {"0"; "1"; "2"; "3"; "4"}); +%! +%! ## Verify changed behavior. +%! set (hb, "ydata", [-2, 1, 3]'); +%! assert (get (hb, "ydata"), [-2, 1, 3]'); +%! assert (get (hp, "xdata"), [0, 0, 0; -2, 1, 3; -2, 1, 3; 0, 0, 0]); +%! assert (get (hax, "xlim"), [-2, 3]); +%! assert (get (hax, "xtick"), -2:3); +%! assert (get (hax, "xticklabel"), {"-2"; "-1"; "0"; "1"; "2"; "3"}); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +## Updating barwidth. +%!test +%! hf = figure ("visible", "off"); +%! unwind_protect +%! hax = axes ("parent", hf); +%! hb = barh (hax, 2:4); +%! hp = get (hb, "children"); +%! +%! ## Verify base behavior. +%! assert (get (hb, "barwidth"), 0.8, eps); +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "ydata"), [0.6, 1.6, 2.6; ... +%! 0.6, 1.6, 2.6; ... +%! 1.4, 2.4, 3.4; ... +%! 1.4, 2.4, 3.4], eps); +%! +%! ## Verify changed behavior. +%! set (hb, "barwidth", 0.5); +%! assert (get (hb, "xdata"), [1:3]'); +%! assert (get (hp, "ydata"), [0.75, 1.75, 2.75; ... +%! 0.75, 1.75, 2.75; ... +%! 1.25, 2.25, 3.25; ... +%! 1.25, 2.25, 3.25], eps); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + + %% Test input validation -%!error barh () +%!error <Invalid call> bar () %!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])