1########################################################################
2##
3## Copyright (C) 2005-2021 The Octave Project Developers
4##
5## See the file COPYRIGHT.md in the top-level directory of this
6## distribution or <https://octave.org/copyright/>.
7##
8## This file is part of Octave.
9##
10## Octave is free software: you can redistribute it and/or modify it
11## under the terms of the GNU General Public License as published by
12## the Free Software Foundation, either version 3 of the License, or
13## (at your option) any later version.
14##
15## Octave is distributed in the hope that it will be useful, but
16## WITHOUT ANY WARRANTY; without even the implied warranty of
17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18## GNU General Public License for more details.
19##
20## You should have received a copy of the GNU General Public License
21## along with Octave; see the file COPYING.  If not, see
22## <https://www.gnu.org/licenses/>.
23##
24########################################################################
25
26## -*- texinfo -*-
27## @deftypefn  {} {} hold
28## @deftypefnx {} {} hold on
29## @deftypefnx {} {} hold off
30## @deftypefnx {} {} hold (@var{hax}, @dots{})
31## Toggle or set the @qcode{"hold"} state of the plotting engine which
32## determines whether new graphic objects are added to the plot or replace
33## the existing objects.
34##
35## @table @code
36## @item hold on
37## Retain plot data and settings so that subsequent plot commands are displayed
38## on a single graph.  Line color and line style are advanced for each new plot
39## added.
40##
41## @item hold all (deprecated)
42## Equivalent to @code{hold on}.
43##
44## @item hold off
45## Restore default graphics settings which clear the graph and reset axes
46## properties before each new plot command.  (default).
47##
48## @item hold
49## Toggle the current hold state.
50## @end table
51##
52## When given the additional argument @var{hax}, the hold state is modified
53## for this axes rather than the current axes returned by @code{gca}.
54##
55## To query the current hold state use the @code{ishold} function.
56## @seealso{ishold, cla, clf, newplot}
57## @end deftypefn
58
59function hold (varargin)
60
61  if (nargin > 0 && isscalar (varargin{1}) && isaxes (varargin{1}))
62    hax = varargin{1};
63    varargin(1) = [];
64    nargs = numel (varargin);
65    hfig = ancestor (hax, "figure");
66  elseif (nargin > 0 && numel (varargin{1}) > 1 && ishghandle (varargin{1}))
67    print_usage ();
68  else
69    hax = gca ();
70    hfig = gcf ();
71    nargs = numel (varargin);
72  endif
73
74  hold_all = false;
75  if (nargs == 0)
76    turn_hold_off = ishold (hax);
77  elseif (nargs == 1)
78    state = tolower (varargin{1});
79    switch (state)
80      case "off"
81        turn_hold_off = true;
82      case "all"
83        turn_hold_off = false;
84        hold_all = true;
85      case "on"
86        turn_hold_off = false;
87      otherwise
88        error ("hold: invalid hold STATE");
89    endswitch
90  else
91    print_usage ();
92  endif
93
94  if (turn_hold_off)
95    set (hax, "nextplot", "replace");
96  else
97    set (hax, "nextplot", "add");
98    set (hfig, "nextplot", "add");
99  endif
100
101endfunction
102
103
104%!demo
105%! clf;
106%! t = linspace (0, 2*pi, 100);
107%! plot (t, sin (t));
108%! hold on;
109%! plot (t, cos (t));
110%! title ({"hold on", "2 plots shown on same graph"});
111%! hold off;
112
113%!demo
114%! clf;
115%! A = rand (100);
116%! [X, Y] = find (A > 0.95);
117%! imshow (A);
118%! hold on;
119%! plot (X, Y, "o");
120%! hold off;
121%! title ("hold with image and plot");
122
123%!demo
124%! clf;
125%! colormap ("default");
126%! hold on;
127%! imagesc (1 ./ hilb (4));
128%! plot (1:4, "-s");
129%! title ("hold with image and plot");
130%! hold off;
131
132%!demo
133%! clf;
134%! colormap ("default");
135%! hold on;
136%! imagesc (1 ./ hilb (2));
137%! imagesc (1 ./ hilb (4));
138%! title ({"hold with two images", "only second image is visible"});
139%! hold off;
140
141%!demo
142%! clf;
143%! colormap ("default");
144%! hold on;
145%! plot (1:4, "-s");
146%! imagesc (1 ./ hilb (4));
147%! title ({"hold with plot and image", "only image is visible"});
148%! hold off;
149
150%!demo
151%! clf;
152%! colormap ("default");
153%! t = linspace (-3, 3, 50);
154%! [x, y] = meshgrid (t, t);
155%! z = peaks (x, y);
156%! contourf (x, y, z, 10);
157%! hold on;
158%! plot (x(:), y(:), "^");
159%! patch ([-1.0 1.0 1.0 -1.0 -1.0], [-1.0 -1.0 1.0 1.0 -1.0], "red");
160%! xlim ([-2.0 2.0]);
161%! ylim ([-2.0 2.0]);
162%! colorbar ("SouthOutside");
163%! title ("hold with line, surface, and patch objects");
164
165## hold on test
166%!test
167%! hf = figure ("visible", "off");
168%! unwind_protect
169%!   p = plot ([0 1]);
170%!   assert (! ishold);
171%!   hold on;
172%!   assert (ishold);
173%!   p1 = fill ([0 1 1], [0 0 1], "black");
174%!   p2 = fill ([0 1 0], [0 1 1], "red");
175%!   assert (length (get (hf, "children")), 1);
176%!   assert (length (get (gca, "children")), 3);
177%! unwind_protect_cleanup
178%!   close (hf);
179%! end_unwind_protect
180
181## hold off test
182%!test
183%! hf = figure ("visible", "off");
184%! unwind_protect
185%!   p = plot ([0 1]);
186%!   assert (! ishold);
187%!   hold on;
188%!   assert (ishold);
189%!   p1 = fill ([0 1 1], [0 0 1], "black");
190%!   hold off;
191%!   p2 = fill ([0 1 0], [0 1 1], "red");
192%!   assert (length (get (hf, "children")), 1);
193%!   assert (length (get (gca, "children")), 1);
194%! unwind_protect_cleanup
195%!   close (hf);
196%! end_unwind_protect
197