# HG changeset patch # User Nicholas R. Jankowski # Date 1682543930 14400 # Node ID ada96a467a28664b089a3f68c9e808528ce835c4 # Parent 951801d8428f63a0236e677dffac8486d083e284 quiver: Improve plotting with non-float numeric inputs (bug #59695) * scripts/plot/draw/private/__quiver__.m: Change firstnonnumeric check to look for char instead of numeric to allow for logical inputs. Recast all inputs up to firstnonnumeric as doubles. Check if firstnonnumeric element is 'off' and if so set scale factor to 0 and increment firstnonnumeric. * scripts/plot/draw/quiver.m: Update docstring to include scaling factor option 'off'. Add BIST for int and logical input types. * scripts/plot/draw/quiver3.m: Update docstring to include scaling factor option 'off'. Add BISTs for too-few inputs. * etc/NEWS.9.md: Appended details of changes to quiver note under General Improvements and noted it also applies to quiver3. diff -r 951801d8428f -r ada96a467a28 etc/NEWS.9.md --- a/etc/NEWS.9.md Wed Apr 26 16:29:28 2023 -0700 +++ b/etc/NEWS.9.md Wed Apr 26 17:18:50 2023 -0400 @@ -19,8 +19,11 @@ the number of decimal places (the fourth input) retains old behavior for backward compatibility, except that non-integer inputs will no longer error. -- `quiver` now honors the scaling factor input when there is only a single -arrow, whereas the factor was previously ignored in that case. +- `quiver` and `quiver3` now properly plots non-float numeric inputs by +internally recasting them to 'double'. They honor the scaling factor input +when there is only a single arrow, whereas the factor was previously ignored +in that case. They also accept a scale factor of "off" which is equivalent to +setting it to 0. - The `inputParser` function has been re-architected for a 60% performance improvement. diff -r 951801d8428f -r ada96a467a28 scripts/plot/draw/private/__quiver__.m --- a/scripts/plot/draw/private/__quiver__.m Wed Apr 26 16:29:28 2023 -0700 +++ b/scripts/plot/draw/private/__quiver__.m Wed Apr 26 17:18:50 2023 -0400 @@ -40,12 +40,30 @@ ## in order to get equivalent visual results while keeping equivalent ## property values. arrowsize = 0.20; - - firstnonnumeric = find (! cellfun ("isnumeric", varargin(3:nargin)), 1); + firstnonnumeric = find (cellfun ("ischar", varargin(3:nargin)), 1); if (isempty (firstnonnumeric)) firstnonnumeric = Inf; + + ## Recast non-float inputs as doubles to avoid erroneous plots. + varargin(3:end) = cellfun ('double', varargin(3:end), ... + "UniformOutput", false); else firstnonnumeric += 2; + + ## Recast non-float inputs as doubles. + varargin(3:firstnonnumeric-1) = cellfun ('double', + varargin(3:firstnonnumeric-1), "UniformOutput", false); + + ## Check for scaling factor "off" and set it to 0. + if (strcmpi (varargin{firstnonnumeric}, "off")) + varargin(firstnonnumeric) = 0; + + if ((firstnonnumeric) == nargin) + firstnonnumeric = Inf; + else + firstnonnumeric++; + endif + endif endif ioff = 3; diff -r 951801d8428f -r ada96a467a28 scripts/plot/draw/quiver.m --- a/scripts/plot/draw/quiver.m Wed Apr 26 16:29:28 2023 -0700 +++ b/scripts/plot/draw/quiver.m Wed Apr 26 17:18:50 2023 -0400 @@ -46,7 +46,7 @@ ## The optional input @var{s} is a scalar defining a scaling factor to use for ## the arrows of the field relative to the mesh spacing. A value of 1.0 will ## result in the longest vector exactly filling one grid square. A value of 0 -## disables all scaling. The default value is 0.9. +## or "off" disables all scaling. The default value is 0.9. ## ## The style to use for the plot can be defined with a line style @var{style} ## of the same format as the @code{plot} command. If a marker is specified @@ -198,7 +198,52 @@ %! close (hf); %! end_unwind_protect +%!test <*59695> # Check for proper plotting with non-float inputs. +%! hf = figure ("visible", "off"); +%! hax = gca (); +%! unwind_protect +%! h = quiver (int32(1), int32(1), int32(1), int32(1), double(0.5)); +%! childxdata = get (get (h, "children"), "xdata"); +%! childydata = get (get (h, "children"), "ydata"); +%! assert (all (strcmp (cellfun (... +%! 'class', childxdata, 'UniformOutput', false), "double"))); +%! assert (all (strcmp (cellfun (... +%! 'class', childydata, 'UniformOutput', false), "double"))); +%! assert (childxdata{2}(2) , 1.5, eps); +%! assert (childxdata{3}(2) , 1.5, eps); +%! assert (childydata{2}(2) , 1.5, eps); +%! assert (childydata{3}(2) , 1.5, eps); +%! +%! h = quiver (0.5, 0.5, 0.5, 0.5, int32(1)); +%! childxdata = get (get (h, "children"), "xdata"); +%! childydata = get (get (h, "children"), "ydata"); +%! assert (all (strcmp (cellfun (... +%! 'class', childxdata, 'UniformOutput', false), "double"))); +%! assert (all (strcmp (cellfun (... +%! 'class', childydata, 'UniformOutput', false), "double"))); +%! assert (childxdata{2}(2) , 1, eps); +%! assert (childxdata{3}(2) , 1, eps); +%! assert (childydata{2}(2) , 1, eps); +%! assert (childydata{3}(2) , 1, eps); +%! +%! h = quiver (false, true, false, true, true); +%! childxdata = get (get (h, "children"), "xdata"); +%! childydata = get (get (h, "children"), "ydata"); +%! assert (all (strcmp (cellfun (... +%! 'class', childxdata, 'UniformOutput', false), "double"))); +%! assert (all (strcmp (cellfun (... +%! 'class', childydata, 'UniformOutput', false), "double"))); +%! assert (childxdata{2}(2) , 0, eps); +%! assert (childxdata{3}(2) , 0, eps); +%! assert (childydata{2}(2) , 2, eps); +%! assert (childydata{3}(2) , 2, eps); +%! +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + ## Test input validation %!error quiver() -%!error quiver(1) +%!error quiver(1.1) + diff -r 951801d8428f -r ada96a467a28 scripts/plot/draw/quiver3.m --- a/scripts/plot/draw/quiver3.m Wed Apr 26 16:29:28 2023 -0700 +++ b/scripts/plot/draw/quiver3.m Wed Apr 26 17:18:50 2023 -0400 @@ -46,7 +46,7 @@ ## The optional input @var{s} is a scalar defining a scaling factor to use for ## the arrows of the field relative to the mesh spacing. A value of 1.0 will ## result in the longest vector exactly filling one grid cube. A value of 0 -## disables all scaling. The default value is 0.9. +## or "off" disables all scaling. The default value is 0.9. ## ## The style to use for the plot can be defined with a line style @var{style} ## of the same format as the @code{plot} command. If a marker is specified @@ -80,7 +80,7 @@ [hax, varargin, nargin] = __plt_get_axis_arg__ ("quiver3", varargin{:}); - if (nargin < 2) + if (nargin < 4) print_usage (); endif @@ -134,3 +134,10 @@ %! shading interp; %! title ({"quiver3() of surface normals to peaks() function"; ... %! 'shading "interp"'}); + +##Test input validation +%!error quiver3 () +%!error quiver3 (1.1) +%!error quiver3 (1.1, 2) +%!error quiver3 (1.1, 2, 3) +