scripts/plot/__contour__.m
author David Bateman <dbateman@free.fr>
Mon Aug 24 10:02:47 2009 +0200 (2009-08-24)
changeset 9411 d208ae6e9d74
parent 8920 eb63fbe60fab
permissions -rw-r--r--
Fix test for setting of datasource properties. Add the edgecolor property to contours
jwe@8920
     1
## Copyright (C) 2007, 2008, 2009 David Bateman
jwe@7170
     2
##
jwe@7170
     3
## This file is part of Octave.
jwe@7170
     4
##
jwe@7170
     5
## Octave is free software; you can redistribute it and/or modify it
jwe@7170
     6
## under the terms of the GNU General Public License as published by
jwe@7170
     7
## the Free Software Foundation; either version 3 of the License, or (at
jwe@7170
     8
## your option) any later version.
jwe@7170
     9
##
jwe@7170
    10
## Octave is distributed in the hope that it will be useful, but
jwe@7170
    11
## WITHOUT ANY WARRANTY; without even the implied warranty of
jwe@7170
    12
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
jwe@7170
    13
## General Public License for more details.
jwe@7170
    14
##
jwe@7170
    15
## You should have received a copy of the GNU General Public License
jwe@7170
    16
## along with Octave; see the file COPYING.  If not, see
jwe@7170
    17
## <http://www.gnu.org/licenses/>.
jwe@7170
    18
jwe@8812
    19
## -*- texinfo -*-
jwe@8812
    20
## @deftypefn {Function File} {[@var{c}, @var{hg}] =} __contour__ (@dots{})
jwe@7170
    21
## Undocumented internal function.
jwe@8812
    22
## @end deftypefn
jwe@7170
    23
dbateman@8289
    24
function [c, hg] = __contour__ (varargin)
jwe@7208
    25
  ax = varargin{1};
dbateman@8289
    26
  zlevel = varargin{2};
dbateman@8289
    27
  filled = "off";
jwe@7170
    28
jwe@7317
    29
  linespec.linestyle = "-";
dbateman@8289
    30
  linespec.color = "auto";
dbateman@9411
    31
  edgecolor = "flat";
jwe@7317
    32
  for i = 3 : nargin
jwe@7317
    33
    arg = varargin {i};
jwe@7317
    34
    if ((ischar (arg) || iscell (arg)))
dbateman@8289
    35
      [linespec, valid] = __pltopt__ ("__contour__", arg, false);
jwe@7317
    36
      if (isempty (linespec.color))
dbateman@8289
    37
	linespec.color = "auto";
jwe@7317
    38
      endif
jwe@7317
    39
      if (valid)
jwe@7317
    40
	have_line_spec = true;
jwe@7317
    41
	varargin(i) = [];
jwe@7317
    42
	break;
jwe@7317
    43
      endif
jwe@7317
    44
    endif
jwe@7317
    45
  endfor
jwe@7317
    46
David@7462
    47
  opts = {};
David@7462
    48
  i = 3;
David@7462
    49
  while (i < length (varargin))
David@7462
    50
    if (ischar (varargin {i}))
dbateman@8289
    51
      if (strcmpi (varargin{i}, "fill"))
dbateman@8289
    52
	filled = varargin {i + 1};
dbateman@8289
    53
	varargin(i:i+1) = [];
dbateman@8289
    54
      elseif (strcmpi (varargin{i}, "linecolor"))
dbateman@8289
    55
	linespec.color = varargin {i + 1};
dbateman@9411
    56
	edgecolor = linespec.color;
dbateman@9411
    57
	if (ischar (edgecolor) && strcmpi (edgecolor, "auto"))
dbateman@9411
    58
	  edgecolor = "flat";
dbateman@9411
    59
	endif
dbateman@9411
    60
	varargin(i:i+1) = [];
dbateman@9411
    61
      elseif (strcmpi (varargin{i}, "edgecolor"))
dbateman@9411
    62
	linespec.color = varargin {i + 1};
dbateman@9411
    63
	edgecolor = linespec.color;
dbateman@9411
    64
	if (ischar (edgecolor) && strcmpi (edgecolor, "flat"))
dbateman@9411
    65
	  linespec.color = "auto";
dbateman@9411
    66
	endif
dbateman@8289
    67
	varargin(i:i+1) = [];
dbateman@8289
    68
      else
dbateman@8289
    69
	opts{end+1} = varargin{i};
dbateman@8289
    70
        varargin(i) = [];
dbateman@8289
    71
        opts{end+1} = varargin{i};
dbateman@8289
    72
        varargin(i) = [];
dbateman@8289
    73
      endif
David@7462
    74
    else
David@7462
    75
      i++;
David@7462
    76
    endif
David@7462
    77
  endwhile
David@7462
    78
dbateman@8289
    79
  if (length(varargin) < 5)
dbateman@8289
    80
    z1 = varargin{3};
dbateman@8289
    81
    x1 = 1 : rows(z1);
dbateman@8289
    82
    y1 = 1 : columns(z1);
dbateman@8289
    83
  else
dbateman@8289
    84
    x1 = varargin{3};
dbateman@8289
    85
    y1 = varargin{4};
dbateman@8289
    86
    z1 = varargin{5};
dbateman@8289
    87
  endif
dbateman@8289
    88
  if (length (varargin) == 4 || length (varargin) == 6)
dbateman@8289
    89
    vn = varargin {end};
dbateman@8289
    90
    vnauto = false;
dbateman@8289
    91
  else
dbateman@8289
    92
    vnauto = true;
dbateman@8289
    93
    vn = 10; 
dbateman@8289
    94
  endif
dbateman@8289
    95
dbateman@8299
    96
  if (isscalar (vn))
dbateman@8299
    97
    lvl = linspace (min (z1(!isinf(z1))), max (z1(!isinf(z1))), 
dbateman@8299
    98
		    vn + 2)(1:end-1);
dbateman@8299
    99
  else
dbateman@8299
   100
    lvl = vn;
dbateman@8299
   101
  endif
dbateman@8299
   102
dbateman@8289
   103
  if (strcmpi (filled, "on"))
dbateman@8289
   104
    if (isvector (x1) || isvector (y1))
dbateman@8289
   105
      [x1, y1] = meshgrid (x1, y1);
dbateman@8289
   106
    endif
dbateman@8289
   107
    [nr, nc] = size (z1);
dbateman@8289
   108
    x0 = prepad(x1, nc+1, 2 * x1(1, 1) - x1(1, 2), 2);
dbateman@8289
   109
    x0 = postpad(x0, nc+2, 2 * x1(1, nc) - x1(1, nc - 1), 2);
dbateman@8289
   110
    x0 = [x0(1, :); x0; x0(1, :)];
dbateman@8289
   111
    y0 = prepad(y1, nr+1, 2 * y1(1, 1) - y1(2, 1), 1);
dbateman@8289
   112
    y0 = postpad(y0, nr+2, 2 * y1(nr, 1) - y1(nr - 1, 1));
dbateman@8289
   113
    y0 = [y0(:, 1), y0, y0(:, 1)];
dbateman@8289
   114
    z0 = -Inf(nr+2, nc+2);
dbateman@8289
   115
    z0(2:nr+1, 2:nc+1) = z1;
dbateman@8299
   116
    [c, lev] = contourc (x0, y0, z0, lvl);
dbateman@8289
   117
  else
dbateman@8299
   118
    [c, lev] = contourc (x1, y1, z1, lvl);
dbateman@8289
   119
  endif
dbateman@8289
   120
dbateman@8289
   121
  hg = hggroup ();
dbateman@8289
   122
  opts = __add_datasource__ ("__countour__", hg, {"x", "y", "z"}, opts{:});
dbateman@8289
   123
dbateman@8289
   124
  addproperty ("xdata", hg, "data", x1);
dbateman@8289
   125
  addproperty ("ydata", hg, "data", y1);
dbateman@8289
   126
  addproperty ("zdata", hg, "data", z1);
dbateman@8289
   127
  addproperty ("contourmatrix", hg, "data", c);
dbateman@8289
   128
dbateman@8289
   129
  addlistener (hg, "xdata", @update_data);
dbateman@8289
   130
  addlistener (hg, "ydata", @update_data);
dbateman@8289
   131
  addlistener (hg, "zdata", @update_data);
dbateman@8289
   132
  addlistener (hg, "contourmatrix", @update_data);
dbateman@8289
   133
dbateman@8289
   134
  addproperty ("fill", hg, "radio", "on|{off}", filled);
dbateman@8289
   135
dbateman@8289
   136
  ## The properties zlevel and zlevelmode don't exist in matlab, but
dbateman@8289
   137
  ## allow the use of contourgroups with the contour3, meshc and surfc 
dbateman@8289
   138
  ## functions. 
dbateman@8289
   139
  if (isnumeric (zlevel))
dbateman@8289
   140
    addproperty ("zlevelmode", hg, "radio", "{none}|auto|manual", "manual")
dbateman@8289
   141
    addproperty ("zlevel", hg, "data", zlevel);
dbateman@8289
   142
  else
dbateman@8289
   143
    addproperty ("zlevelmode", hg, "radio", "{none}|auto|manual", zlevel)
dbateman@8289
   144
    if (ischar (zlevel) && strcmpi (zlevel, "manual"))
David@7462
   145
      z = varargin{3};
jwe@7191
   146
      z = 2 * (min (z(:)) - max (z(:)));
dbateman@8289
   147
      addproperty ("zlevel", hg, "data", z);
dbateman@8289
   148
    else
dbateman@8289
   149
      addproperty ("zlevel", hg, "data", 0.);
jwe@7175
   150
    endif
jwe@7175
   151
  endif
jwe@7175
   152
dbateman@8299
   153
  lvlstep = sum (abs (diff (lvl))) / (length (lvl) - 1);
jwe@7170
   154
dbateman@8289
   155
  addproperty ("levellist", hg, "data", lev);
dbateman@8289
   156
  addproperty ("levelstep", hg, "double", lvlstep);
dbateman@8289
   157
  if (vnauto)
dbateman@8289
   158
    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   159
    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   160
  elseif (isscalar (vn))
dbateman@8289
   161
    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   162
    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "manual");
dbateman@8289
   163
  else
dbateman@8289
   164
    addproperty ("levellistmode", hg, "radio", "{auto}|manual", "manual");
dbateman@8289
   165
    addproperty ("levelstepmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   166
  endif
jwe@7170
   167
dbateman@8289
   168
  addproperty ("labelspacing", hg, "double", 144);
dbateman@8289
   169
  addproperty ("textlist", hg, "data", lev);
dbateman@8289
   170
  addproperty ("textlistmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   171
  addproperty ("textstep", hg, "double", lvlstep);
dbateman@8289
   172
  addproperty ("textstepmode", hg, "radio", "{auto}|manual", "auto");
dbateman@8289
   173
  addproperty ("showtext", hg, "radio", "on|{off}", "off");
dbateman@8289
   174
dbateman@8289
   175
  addproperty ("linecolor", hg, "color", linespec.color, "{auto}|none");
dbateman@8289
   176
  addproperty ("linestyle", hg, "linelinestyle", linespec.linestyle);
dbateman@8289
   177
  addproperty ("linewidth", hg, "linelinewidth", 0.5);
dbateman@8289
   178
dbateman@9411
   179
  ## FIXME It would be good to hide this property which is just an undocumented
dbateman@9411
   180
  ## alias for linecolor
dbateman@9411
   181
  addproperty ("edgecolor", hg, "color", edgecolor, "{flat}|none");
dbateman@9411
   182
dbateman@8289
   183
  addlistener (hg, "fill", @update_data);
dbateman@8289
   184
dbateman@8289
   185
  addlistener (hg, "zlevelmode", @update_zlevel);
dbateman@8289
   186
  addlistener (hg, "zlevel", @update_zlevel);
dbateman@8289
   187
dbateman@8289
   188
  addlistener (hg, "levellist", @update_data);
dbateman@8289
   189
  addlistener (hg, "levelstep", @update_data);
dbateman@8289
   190
  addlistener (hg, "levellistmode", @update_data);
dbateman@8289
   191
  addlistener (hg, "levelstepmode", @update_data);
dbateman@8289
   192
dbateman@8289
   193
  addlistener (hg, "labelspacing", @update_text);
dbateman@8289
   194
  addlistener (hg, "textlist", @update_text);
dbateman@8289
   195
  addlistener (hg, "textlistmode", @update_text);
dbateman@8289
   196
  addlistener (hg, "textstep", @update_text);
dbateman@8289
   197
  addlistener (hg, "textstepmode", @update_text);
dbateman@8289
   198
  addlistener (hg, "showtext", @update_text);
dbateman@8289
   199
dbateman@8289
   200
  addlistener (hg, "linecolor", @update_line);
dbateman@8289
   201
  addlistener (hg, "linestyle", @update_line);
dbateman@8289
   202
  addlistener (hg, "linewidth", @update_line);
dbateman@8289
   203
dbateman@9411
   204
  addlistener (hg, "edgecolor", @update_edgecolor);
dbateman@9411
   205
dbateman@8289
   206
  add_patch_children (hg);
dbateman@8289
   207
dbateman@8289
   208
  if (!isempty (opts))
dbateman@8289
   209
    set (hg, opts{:});
dbateman@8289
   210
  endif
dbateman@8289
   211
endfunction
dbateman@8289
   212
dbateman@8289
   213
function add_patch_children (hg)
dbateman@8289
   214
  c = get (hg, "contourmatrix");
dbateman@8289
   215
  lev = get (hg, "levellist");
dbateman@8289
   216
  fill = get (hg, "fill");
dbateman@8289
   217
  z = get (hg, "zlevel");
dbateman@8289
   218
  zmode = get (hg, "zlevelmode");
dbateman@8289
   219
  lc = get (hg, "linecolor");
dbateman@8289
   220
  lw = get (hg, "linewidth");
dbateman@8289
   221
  ls = get (hg, "linestyle");
dbateman@8289
   222
  filled = get (hg, "fill");
dbateman@8289
   223
dbateman@8289
   224
  if (strcmpi (lc, "auto"))
dbateman@8289
   225
    lc = "flat";
dbateman@8289
   226
  endif
dbateman@8289
   227
dbateman@8289
   228
  if (strcmpi (filled, "on"))
dbateman@8289
   229
    if (diff (lev) < 10*eps) 
dbateman@8289
   230
      lvl_eps = 1e-6;
jwe@7175
   231
    else
dbateman@8289
   232
      lvl_eps = min (diff (lev)) / 1000.0;
jwe@7175
   233
    endif
jwe@7175
   234
dbateman@8289
   235
    ## Decode contourc output format.
dbateman@8289
   236
    i1 = 1;
dbateman@8289
   237
    ncont = 0;
dbateman@8289
   238
    while (i1 < columns (c))
dbateman@8289
   239
      ncont++;
dbateman@8289
   240
      cont_lev(ncont) = c(1, i1);
dbateman@8289
   241
      cont_len(ncont) = c(2, i1);
dbateman@8289
   242
      cont_idx(ncont) = i1+1;
dbateman@8289
   243
dbateman@8289
   244
      ii = i1+1:i1+cont_len(ncont);
dbateman@8289
   245
      cur_cont = c(:, ii);
dbateman@8289
   246
      startidx = ii(1);
dbateman@8289
   247
      stopidx = ii(end);
dbateman@8289
   248
      cont_area(ncont) = polyarea (c(1, ii), c(2, ii));
dbateman@8289
   249
      i1 += c(2, i1) + 1;
dbateman@8289
   250
    endwhile
dbateman@8289
   251
dbateman@8289
   252
    ## Handle for each level the case where we have (a) hole(s) in a patch.
dbateman@8289
   253
    ## Those are to be filled with the color of level below or with the
dbateman@8289
   254
    ## background colour.
dbateman@8289
   255
    for k = 1:numel (lev)
dbateman@8289
   256
      lvl_idx = find (abs (cont_lev - lev(k)) < lvl_eps);
dbateman@8289
   257
      len = numel (lvl_idx);
dbateman@8289
   258
      if (len > 1)
dbateman@8289
   259
	## mark = logical(zeros(size(lvl_idx)));
dbateman@8289
   260
	mark = false (size (lvl_idx));
dbateman@8289
   261
	a = 1;
dbateman@8289
   262
	while (a < len)
dbateman@8289
   263
	  ## take 1st patch
dbateman@8289
   264
          b = a + 1;
dbateman@8289
   265
          pa_idx = lvl_idx(a);
dbateman@8289
   266
          ## get pointer to contour start, and contour length
dbateman@8289
   267
          curr_ct_idx = cont_idx(pa_idx);
dbateman@8289
   268
          curr_ct_len = cont_len(pa_idx);
dbateman@8289
   269
	  ## get contour
dbateman@8289
   270
          curr_ct = c(:, curr_ct_idx:curr_ct_idx+curr_ct_len-1);
dbateman@8289
   271
          b_vec = (a+1):len;
dbateman@8289
   272
          next_ct_pt_vec = c(:, cont_idx(lvl_idx(b_vec)));
dbateman@8289
   273
          in = inpolygon (next_ct_pt_vec(1,:), next_ct_pt_vec(2,:),
dbateman@8289
   274
			  curr_ct(1, :), curr_ct(2, :));
dbateman@8289
   275
          mark(b_vec(in)) = !mark(b_vec(in));
dbateman@8289
   276
          a++;
dbateman@8289
   277
	endwhile
dbateman@8289
   278
	if (numel (mark) > 0)
dbateman@8289
   279
	  ## All marked contours describe a hole in a larger contour of
dbateman@8289
   280
	  ## the same level and must be filled with colour of level below.
dbateman@8289
   281
          ma_idx = lvl_idx(mark);
dbateman@8289
   282
          if (k > 1)
dbateman@8289
   283
	    ## Find color of level below.
dbateman@8289
   284
            tmp = find(abs(cont_lev - lev(k - 1)) < lvl_eps);
dbateman@8289
   285
            lvl_bel_idx = tmp(1);
dbateman@8289
   286
	    ## Set color of patches found.
dbateman@8289
   287
	    cont_lev(ma_idx) = cont_lev(lvl_bel_idx);
dbateman@8289
   288
          else
dbateman@8289
   289
	    ## Set lowest level contour to NaN.
dbateman@8289
   290
	    cont_lev(ma_idx) = NaN;
dbateman@8289
   291
          endif
dbateman@8289
   292
	endif
dbateman@8289
   293
      endif
dbateman@8289
   294
    endfor
dbateman@8289
   295
dbateman@8289
   296
    ## The algorithm can create patches with the size of the plotting
dbateman@8289
   297
    ## area, we would like to draw only the patch with the highest level.
dbateman@8289
   298
    del_idx = [];
dbateman@8289
   299
    max_idx = find (cont_area == max (cont_area));
dbateman@8289
   300
    if (numel (max_idx) > 1)
dbateman@8289
   301
      ## delete double entries
dbateman@8289
   302
      del_idx = max_idx(1:end-1);
dbateman@8289
   303
      cont_area(del_idx) = cont_lev(del_idx) = [];
dbateman@8289
   304
      cont_len(del_idx) = cont_idx(del_idx) = [];
dbateman@8289
   305
    endif
dbateman@8289
   306
dbateman@8289
   307
    ## Now we have everything together and can start plotting the patches
dbateman@8289
   308
    ## beginning with largest area.
dbateman@8289
   309
    [tmp, svec] = sort (cont_area);
dbateman@8289
   310
    len = ncont - numel (del_idx);
dbateman@8289
   311
    h = [];
bpabbott@8441
   312
    for n = len:(-1):1
dbateman@8289
   313
      idx = svec(n);
dbateman@8289
   314
      ctmp = c(:, cont_idx(idx):cont_idx(idx) + cont_len(idx) - 1);
dbateman@8289
   315
      if (all (ctmp(:,1) == ctmp(:,end)))
dbateman@8289
   316
        ctmp(:, end) = [];
dbateman@8289
   317
      else
dbateman@8289
   318
	## Special case unclosed contours
dbateman@8289
   319
      endif
dbateman@8289
   320
      h = [h; patch(ctmp(1, :), ctmp(2, :), cont_lev(idx), "edgecolor", lc, 
dbateman@8289
   321
		    "linestyle", ls, "linewidth", lw, "parent", hg)];
dbateman@8289
   322
    endfor
dbateman@8289
   323
dbateman@8289
   324
    if (min (lev) == max (lev))
dbateman@8289
   325
      set (gca (), "clim", [min(lev)-1, max(lev)+1]);
jwe@7170
   326
    else
dbateman@8289
   327
      set (gca(), "clim", [min(lev), max(lev)]);
jwe@7170
   328
    endif
dbateman@8289
   329
dbateman@8289
   330
    set (gca (), "layer", "top");
dbateman@8289
   331
  else
dbateman@8289
   332
    ## Decode contourc output format.
dbateman@8289
   333
    i1 = 1;
dbateman@8289
   334
    h = [];
dbateman@8289
   335
    while (i1 < length (c))
dbateman@8289
   336
      clev = c(1,i1);
dbateman@8289
   337
      clen = c(2,i1);
dbateman@8289
   338
dbateman@8289
   339
      if (all (c(:,i1+1) == c(:,i1+clen)))
dbateman@8289
   340
	p = c(:, i1+1:i1+clen-1);
dbateman@8289
   341
      else
dbateman@8289
   342
	p = [c(:, i1+1:i1+clen), NaN(2, 1)];
dbateman@8289
   343
      endif
dbateman@8289
   344
dbateman@8289
   345
      switch (zmode)
dbateman@8289
   346
	case "none"
dbateman@8289
   347
	  h = [h; patch(p(1,:), p(2,:), "facecolor", "none", 
dbateman@8289
   348
			"edgecolor", lc, "linestyle", ls, "linewidth", lw,
dbateman@8289
   349
			"cdata", clev, "parent", hg)]; 
dbateman@8289
   350
	case "auto"
dbateman@8289
   351
	  h = [h; patch(p(1,:), p(2,:), clev * ones (1, columns (p)),
dbateman@8289
   352
			"facecolor", "none", "edgecolor", lc, 
dbateman@8289
   353
			"linestyle", ls, "linewidth", lw, "cdata", clev, 
dbateman@8289
   354
			"parent", hg)];
dbateman@8289
   355
	otherwise
dbateman@8289
   356
	  h = [h; patch(p(1,:), p(2,:), z * ones (1, columns (p)),
dbateman@8289
   357
			"facecolor", "none", "edgecolor", lc,
dbateman@8289
   358
			"linestyle", ls, "linewidth", lw, "cdata", clev,
dbateman@8289
   359
			"parent", hg)];
dbateman@8289
   360
      endswitch
dbateman@8289
   361
      i1 += clen+1;
dbateman@8289
   362
    endwhile
dbateman@8289
   363
  endif
dbateman@8289
   364
jwe@7170
   365
endfunction
dbateman@8289
   366
dbateman@8289
   367
function update_zlevel (h, d)
dbateman@8289
   368
  z = get (h, "zlevel");
dbateman@8289
   369
  zmode = get (h, "zlevelmode");
dbateman@8289
   370
  kids = get (h, "children");
dbateman@8289
   371
dbateman@8289
   372
  switch (zmode)
dbateman@8289
   373
    case "none"
dbateman@8289
   374
      set (kids, "zdata", []);
dbateman@8289
   375
    case "auto"
dbateman@8289
   376
      for i = 1 : length (kids)
dbateman@8289
   377
	set (kids(i), "zdata", get (kids (i), "cdata") .* 
dbateman@8289
   378
	     ones (size (get (kids (i), "xdata"))));
dbateman@8289
   379
      endfor
dbateman@8289
   380
    otherwise
dbateman@8289
   381
      for i = 1 : length (kids)
dbateman@8289
   382
	set (kids(i), "zdata", z .* ones (size (get (kids (i), "xdata"))));
dbateman@8289
   383
      endfor
dbateman@8289
   384
  endswitch
dbateman@8289
   385
endfunction
dbateman@8289
   386
dbateman@9411
   387
function update_edgecolor (h, d)
dbateman@9411
   388
  ec = get (h, "edgecolor");
dbateman@9411
   389
  lc = get (h, "linecolor");
dbateman@9411
   390
  if (ischar (ec) && strcmpi (ec, "flat"))
dbateman@9411
   391
    if (! strcmpi (lc, "auto"))
dbateman@9411
   392
      set (h, "linecolor", "auto");
dbateman@9411
   393
    endif
dbateman@9411
   394
  elseif (! isequal (ec, lc))
dbateman@9411
   395
    set (h, "linecolor", ec);
dbateman@9411
   396
  endif
dbateman@9411
   397
endfunction
dbateman@9411
   398
dbateman@8289
   399
function update_line (h, d)
dbateman@8289
   400
  lc = get (h, "linecolor");
dbateman@9411
   401
  ec = get (h, "edgecolor");
dbateman@8289
   402
  if (strcmpi (lc, "auto"))
dbateman@8289
   403
    lc = "flat";
dbateman@8289
   404
  endif
dbateman@9411
   405
  if (! isequal (ec, lc))
dbateman@9411
   406
    set (h, "edgecolor", lc);
dbateman@9411
   407
  endif
dbateman@8289
   408
  set (findobj (h, "type", "patch"), "edgecolor", lc,
dbateman@8289
   409
       "linewidth", get (h, "linewidth"), "linestyle", get (h, "linestyle"));
dbateman@8289
   410
endfunction
dbateman@8289
   411
dbateman@8289
   412
function update_data (h, d)
dbateman@8289
   413
  persistent recursive = false;
dbateman@8289
   414
dbateman@8289
   415
  if (!recursive)
dbateman@8289
   416
    recursive = true;
dbateman@8289
   417
dbateman@8289
   418
    delete (get (h, "children"));
dbateman@8289
   419
dbateman@8289
   420
    if (strcmpi (get (h, "levellistmode"), "manual"))
dbateman@8289
   421
      lvl = get (h, "levellist");
dbateman@8289
   422
    elseif (strcmpi (get (h, "levelstepmode"), "manual"))
dbateman@8289
   423
      z = get (h, "zdata");
dbateman@8289
   424
      lvl = ceil ((max(z(:)) - min (z(:)) ./ get (h, "levelstep")));
dbateman@8289
   425
    else
dbateman@8289
   426
      lvl = 10;
dbateman@8289
   427
    endif
dbateman@8289
   428
dbateman@8289
   429
    if (strcmpi (get (h, "fill"), "on"))
dbateman@8289
   430
      X = get (h, "xdata");
dbateman@8289
   431
      Y = get (h, "ydata");
dbateman@8289
   432
      Z = get (h, "zdata");
dbateman@8289
   433
      if (isvector (X) || isvector (Y))
dbateman@8289
   434
	[X, Y] = meshgrid (X, Y);
dbateman@8289
   435
      endif
dbateman@8289
   436
      [nr, nc] = size (Z);
dbateman@8289
   437
      X0 = prepad(X, nc+1, 2 * X(1, 1) - X(1, 2), 2);
dbateman@8289
   438
      X0 = postpad(X0, nc+2, 2 * X(1, nc) - X(1, nc - 1), 2);
dbateman@8289
   439
      X0 = [X0(1, :); X0; X0(1, :)];
dbateman@8289
   440
      Y0 = prepad(Y, nr+1, 2 * Y(1, 1) - Y(2, 1), 1);
dbateman@8289
   441
      Y0 = postpad(Y0, nr+2, 2 * Y(nr, 1) - Y(nr - 1, 1));
dbateman@8289
   442
      Y0 = [Y0(:, 1), Y0, Y0(:, 1)];
dbateman@8289
   443
      Z0 = -Inf(nr+2, nc+2);
dbateman@8289
   444
      Z0(2:nr+1, 2:nc+1) = Z;
dbateman@8289
   445
      [c, lev] = contourc (X0, Y0, Z0, lvl);
dbateman@8289
   446
    else
dbateman@8289
   447
      [c, lev] = contourc (get (h, "xdata"), get (h, "ydata"), 
dbateman@8289
   448
			   get (h, "zdata"), lvl); 
dbateman@8289
   449
    endif
dbateman@8289
   450
    set (h, "contourmatrix", c);
dbateman@8289
   451
dbateman@8289
   452
    if (strcmpi (get (h, "levellistmode"), "manual"))
dbateman@8289
   453
      ## Do nothing
dbateman@8289
   454
    elseif (strcmpi (get (h, "levelstepmode"), "manual"))
dbateman@8289
   455
      set (h, "levellist", lev);
dbateman@8289
   456
    else
dbateman@8289
   457
      set (h, "levellist", lev);
dbateman@8289
   458
      z = get (h, "zdata");
dbateman@8289
   459
      lvlstep = (max(z(:)) - min(z(:))) / 10;
dbateman@8289
   460
      set (h, "levelstep", lvlstep);
dbateman@8289
   461
    endif
dbateman@8289
   462
dbateman@8289
   463
    add_patch_children (h);
dbateman@8289
   464
    update_text (h, d);
dbateman@8289
   465
  endif
dbateman@8289
   466
dbateman@8289
   467
  recursive = false;
dbateman@8289
   468
endfunction
dbateman@8289
   469
dbateman@8289
   470
function update_text (h, d)
dbateman@8289
   471
  persistent recursive = false;
dbateman@8289
   472
dbateman@8289
   473
  if (!recursive)
dbateman@8289
   474
    recursive = true;
dbateman@8289
   475
dbateman@8289
   476
    delete (findobj (h, "type", "text"));
dbateman@8289
   477
dbateman@8289
   478
    if (strcmpi (get (h, "textlistmode"), "manual"))
dbateman@8289
   479
      lvl = get (h, "textlist");
dbateman@8289
   480
    elseif (strcmpi (get (h, "textstepmode"), "manual"))
dbateman@8289
   481
      lev = get (h, "levellist");
dbateman@8289
   482
dbateman@8289
   483
      if (diff (lev) < 10*eps) 
dbateman@8289
   484
	lvl_eps = 1e-6;
dbateman@8289
   485
      else
dbateman@8289
   486
	lvl_eps = min (abs (diff (lev))) / 1000.0;
dbateman@8289
   487
      endif
dbateman@8289
   488
dbateman@8289
   489
      stp = get (h, "textstep");
dbateman@8289
   490
      t = [0, floor(cumsum(diff (lev)) / (abs(stp) - lvl_eps))];
dbateman@8289
   491
      lvl = lev([true, t(1:end-1) != t(2:end)]);
dbateman@8289
   492
      set (h, "textlist", lvl);
dbateman@8289
   493
    else
dbateman@8289
   494
      lvl = get (h, "levellist");
dbateman@8289
   495
      set (h, "textlist", lvl, "textstep", get (h, "levelstep"));
dbateman@8289
   496
    endif
dbateman@8289
   497
dbateman@8289
   498
    if (strcmpi (get (h, "showtext"), "on"))
dbateman@8289
   499
      switch (get (h, "zlevelmode"))
dbateman@8289
   500
	case "manual"
dbateman@8289
   501
	  __clabel__ (get (h, "contourmatrix"), lvl, h, 
dbateman@8289
   502
		      get (h, "labelspacing"), get (h, "zlevel"));
dbateman@8289
   503
	case "auto"
dbateman@8289
   504
	  __clabel__ (get (h, "contourmatrix"), lvl, h,
dbateman@8289
   505
		      get (h, "labelspacing"), "auto");
dbateman@8289
   506
	otherwise
dbateman@8289
   507
	  __clabel__ (get (h, "contourmatrix"), lvl, h,
dbateman@8289
   508
		      get (h, "labelspacing"), []);
dbateman@8289
   509
      endswitch
dbateman@8289
   510
    endif
dbateman@8289
   511
  endif
dbateman@8289
   512
dbateman@8289
   513
  recursive = false;
dbateman@8289
   514
endfunction