~gabriel1984sibiu/octave/octave

« back to all changes in this revision

Viewing changes to scripts/plot/util/newplot.m

  • Committer: Grevutiu Gabriel
  • Date: 2014-01-02 13:05:54 UTC
  • Revision ID: gabriel1984sibiu@gmail.com-20140102130554-3r7ivdjln1ni6kcg
New version (3.8.0) from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
## Copyright (C) 2005-2013 John W. Eaton
 
2
##
 
3
## This file is part of Octave.
 
4
##
 
5
## Octave is free software; you can redistribute it and/or modify it
 
6
## under the terms of the GNU General Public License as published by
 
7
## the Free Software Foundation; either version 3 of the License, or (at
 
8
## your option) any later version.
 
9
##
 
10
## Octave is distributed in the hope that it will be useful, but
 
11
## WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
## General Public License for more details.
 
14
##
 
15
## You should have received a copy of the GNU General Public License
 
16
## along with Octave; see the file COPYING.  If not, see
 
17
## <http://www.gnu.org/licenses/>.
 
18
 
 
19
## -*- texinfo -*-
 
20
## @deftypefn  {Function File} {} newplot ()
 
21
## @deftypefnx {Function File} {} newplot (@var{hfig})
 
22
## @deftypefnx {Function File} {} newplot (@var{hax})
 
23
## @deftypefnx {Function File} {@var{hax} =} newplot (@dots{})
 
24
## Prepare graphics engine to produce a new plot.
 
25
##
 
26
## This function is called at the beginning of all high-level plotting
 
27
## functions.  It is not normally required in user programs.  @code{newplot}
 
28
## queries the @qcode{"NextPlot"} field of the current figure and axis to
 
29
## determine what to do.
 
30
##
 
31
## @multitable @columnfractions .25 .75
 
32
## @headitem Figure NextPlot @tab Action
 
33
## @item @qcode{"new"} @tab Create a new figure and make it the current figure.
 
34
##
 
35
## @item @qcode{"add"} (default) @tab Add new graphic objects to the current figure.
 
36
##
 
37
## @item @qcode{"replacechildren"} @tab Delete child objects whose HandleVisibility is
 
38
## set to @qcode{"on"}.  Set NextPlot property to @qcode{"add"}.  This
 
39
## typically clears a figure, but leaves in place hidden objects such as
 
40
## menubars.  This is equivalent to @code{clf}.
 
41
##
 
42
## @item @qcode{"replace"} @tab Delete all child objects of the figure and
 
43
## reset all figure properties to their defaults.  However, the following
 
44
## four properties are not reset: Position, Units, PaperPosition, PaperUnits.
 
45
##  This is equivalent to @code{clf reset}.
 
46
## @end multitable
 
47
##
 
48
## @multitable @columnfractions .25 .75
 
49
## @headitem Axis NextPlot @tab Action
 
50
## @item @qcode{"add"} @tab Add new graphic objects to the current axes.  This is
 
51
## equivalent to @code{hold on}.
 
52
##
 
53
## @item @qcode{"replacechildren"} @tab Delete child objects whose HandleVisibility is
 
54
## set to @qcode{"on"}, but leave axis properties unmodified.  This typically
 
55
## clears a plot, but preserves special settings such as log scaling for
 
56
## axes.  This is equivalent to @code{cla}.
 
57
##
 
58
## @item @qcode{"replace"} (default) @tab Delete all child objects of the
 
59
## axis and reset all axis properties to their defaults.  However, the
 
60
## following properties are not reset: Position, Units.  This is equivalent
 
61
## to @code{cla reset}.
 
62
## @end multitable
 
63
##
 
64
## If the optional input @var{hfig} or @var{hax} is given then prepare the
 
65
## specified figure or axes rather than the current figure and axes.
 
66
##
 
67
## The optional return value @var{hax} is a graphics handle to the created
 
68
## axes object (not figure).
 
69
##
 
70
## @strong{Caution:} Calling @code{newplot} may change the current figure and
 
71
## current axis.
 
72
## @end deftypefn
 
73
 
 
74
## FIXME: The Matlab function takes an optional list of file handles, hsave,
 
75
##        which are not deleted when the figure and axes are prepared.
 
76
##        I'm sure there is a good reason for that, but coding such
 
77
##        compatibility is really tricky and doesn't serve much purpose since
 
78
##        newplot is nearly exclusively used by Octave's internal plotting
 
79
##        functions.  In Octave's case the argument is almost always null,
 
80
##        or occasionally the axis handle to plot into.
 
81
 
 
82
function hax = newplot (hsave = [])
 
83
 
 
84
  if (nargin > 1)
 
85
    print_usage ();
 
86
  endif
 
87
 
 
88
  cf = [];
 
89
  ca = [];
 
90
 
 
91
  if (! isempty (hsave))
 
92
    ## Find the first valid axes 
 
93
    ca = ancestor (hsave, "axes", "toplevel"); 
 
94
    if (iscell (ca))
 
95
      ca = [ca{:}];
 
96
    endif
 
97
    ca = ca(find (ca, 1));
 
98
    hsave(hsave == ca) = [];
 
99
    ## Next, find the figure associated with any axis found
 
100
    if (! isempty (ca))
 
101
      cf = ancestor (ca, "figure", "toplevel");
 
102
    else
 
103
      cf = ancestor (hsave, "figure", "toplevel"); 
 
104
      if (iscell (cf))
 
105
        cf = [cf{:}];
 
106
      endif
 
107
      cf = cf(find (cf, 1));
 
108
    endif
 
109
  endif
 
110
 
 
111
  if (isempty (cf))
 
112
    ## get current figure, or create a new one if necessary
 
113
    cf = gcf ();
 
114
  else
 
115
    ## switch to figure provided without causing other updates
 
116
    set (0, "currentfigure", cf);
 
117
  endif
 
118
 
 
119
  fnp = get (cf, "nextplot");
 
120
  switch (fnp)
 
121
    case "add"
 
122
      ## Default case.  Doesn't require action.
 
123
    case "new"
 
124
      ## Ordinarily, create a new figure to hold plot.
 
125
      ## But, if user has requested preparing a specific axis, then
 
126
      ## use the existing figure to hold the requested axis.
 
127
      if (isempty (ca))
 
128
        cf = figure ();
 
129
      endif
 
130
    case "replacechildren"
 
131
      kids = get (cf, "children");
 
132
      if (! isempty (ca))
 
133
        kids(kids == ca) = [];
 
134
      endif
 
135
      delete (kids);
 
136
    case "replace"
 
137
      kids = allchild (cf);
 
138
      if (! isempty (ca))
 
139
        kids(kids == ca) = [];
 
140
      endif
 
141
      delete (kids);
 
142
      reset (cf);
 
143
  endswitch
 
144
  set (cf, "nextplot", "add");  # Matlab compatibility
 
145
 
 
146
  if (isempty (ca))
 
147
    ca = gca ();
 
148
    deleteall = true;
 
149
  else
 
150
    set (cf, "currentaxes", ca);
 
151
    deleteall = false;
 
152
  endif
 
153
 
 
154
  ## FIXME: Is this necessary anymore?
 
155
  ##        It seems like a kluge that belongs somewhere else.
 
156
  if (strcmp (get (ca, "__hold_all__"), "off"))
 
157
    __next_line_color__ (true);
 
158
    __next_line_style__ (true);
 
159
  else
 
160
    __next_line_color__ (false);
 
161
    __next_line_style__ (false);
 
162
  endif
 
163
 
 
164
  anp = get (ca, "nextplot");
 
165
  switch (anp)
 
166
    case "add"
 
167
      ## Default case.  Doesn't require action.
 
168
    case "replacechildren"
 
169
      if (! deleteall && ca != hsave)
 
170
        ## preserve hsave and its parents, uncles, ...
 
171
        kids = allchild (ca);
 
172
        hkid = hsave;
 
173
        while (! any (hkid == kids))
 
174
          hkid = get (hkid, "parent");
 
175
        endwhile
 
176
        kids(kids == hkid) = [];
 
177
        delete (kids);
 
178
      else
 
179
        delete (get (ca, "children"));
 
180
      endif
 
181
    case "replace"
 
182
      if (! deleteall && ca != hsave)
 
183
        ## preserve hsave and its parents, uncles, ...
 
184
        kids = allchild (ca);
 
185
        hkid = hsave;
 
186
        while (! any (hkid == kids))
 
187
          hkid = get (hkid, "parent");
 
188
        endwhile
 
189
        kids(kids == hkid) = [];
 
190
        delete (kids);
 
191
      else
 
192
        __go_axes_init__ (ca, "replace");
 
193
        __request_drawnow__ ();
 
194
      endif
 
195
      ## FIXME: The code above should perform the following:
 
196
      ###########################
 
197
      ## delete (allchild (ca));
 
198
      ## reset (ca);
 
199
      ###########################
 
200
      ## Actually, __go_axes_init__ does both less and more.
 
201
      ## It doesn't really remove all children since it re-instantiates
 
202
      ## xlabel, ylabel, zlabel, and title text objects.
 
203
      ## Also it preserves font properties like fontsize.
 
204
      ## For the time being, in order to have axis labels and title work,
 
205
      ## the above code is is required.
 
206
  endswitch
 
207
 
 
208
  if (nargout > 0)
 
209
    hax = ca;
 
210
  endif
 
211
 
 
212
endfunction
 
213
 
 
214
 
 
215
%!test
 
216
%! hf = figure ("visible", "off");
 
217
%! unwind_protect
 
218
%!   p = plot ([0, 1]);
 
219
%!   hax = newplot ();
 
220
%!   assert (hax, gca);
 
221
%!   assert (isempty (get (gca, "children")));
 
222
%! unwind_protect_cleanup
 
223
%!   close (hf);
 
224
%! end_unwind_protect
 
225
 
 
226
%!test
 
227
%! hf = figure ("visible", "off");
 
228
%! unwind_protect
 
229
%!   hax = axes ();
 
230
%!   hold on;
 
231
%!   hg1 = hggroup ();
 
232
%!   hg2 = hggroup ("parent", hg1);
 
233
%!   li0 = line (1:10, 1:10);
 
234
%!   li1 = line (1:10, -1:-1:-10, "parent", hg1);
 
235
%!   li2 = line (1:10, sin (1:10), "parent", hg2);
 
236
%!   hold off;
 
237
%!   newplot (hg2);
 
238
%!   assert (ishandle (li0), false);
 
239
%!   assert (get (hax, "children"), hg1);
 
240
%! 
 
241
%!   ## kids are preserved for hggroups
 
242
%!   kids = get (hg1, "children");
 
243
%!   newplot (hg1); 
 
244
%!   assert (get (hg1, "children"), kids);
 
245
%! 
 
246
%!   ## preserve objects
 
247
%!   newplot (li1);
 
248
%!   assert (ishandle (li1));
 
249
%! 
 
250
%!   ## kids are deleted for axes
 
251
%!   newplot (hax);  
 
252
%!   assert (isempty (get (hax, "children")));
 
253
%! unwind_protect_cleanup
 
254
%!   close (hf);
 
255
%! end_unwind_protect
 
256