changeset 10995:e81914f3921f

Update legend code to support fltk (fixes #29348 and partially fixes #30461)
author David Bateman <dbateman@free.fr>
date Sat, 18 Sep 2010 22:30:41 +0200
parents 9e1270a84a10
children 72640afb02b9
files scripts/ChangeLog scripts/plot/__go_draw_axes__.m scripts/plot/__go_draw_figure__.m scripts/plot/__plt_get_axis_arg__.m scripts/plot/legend.m scripts/plot/plot3.m scripts/plot/private/__plt__.m src/ChangeLog src/graphics.cc src/graphics.h.in
diffstat 10 files changed, 776 insertions(+), 165 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,16 @@
+2010-09-18  David Bateman  <dbateman@free.fr>
+
+	* plot/__go_draw_axes__.m: Modify legend code to use data from legend
+	axes.
+	* plot/__go_draw_figure__.m: Draw draw figure axes, but pass their
+	data to the axis they are associated with.
+	* plot/__get_plt_axes_arg__.m: Ignores axes tagged with "legend".
+	* plot/legend.m: Rewrite to use line and text primitives in a seperate
+	axis.
+	* plot/plot3.m: Support old legend format (eg "-;title'") with new
+	legend code.
+	* plot/private/__plt__.m: Ditto.
+
 2010-09-16  Ben Abbott <bpabbott@mac.com>
 
 	* plot/__go_draw_axes__.m: Ensure text objects have units of "data".
--- a/scripts/plot/__go_draw_axes__.m
+++ b/scripts/plot/__go_draw_axes__.m
@@ -23,7 +23,7 @@
 
 ## Author: jwe
 
-function __go_draw_axes__ (h, plot_stream, enhanced, mono, bg_is_set)
+function __go_draw_axes__ (h, plot_stream, enhanced, mono, bg_is_set, hlegend)
 
   if (nargin >= 4 && nargin <= 6)
 
@@ -31,6 +31,11 @@
     unwind_protect
       set (0, "showhiddenhandles", "on");
       axis_obj = __get__ (h);
+      if (isempty (hlegend))
+        hlgnd = [];
+      else
+        hlgnd = __get__ (hlegend);
+      endif
     unwind_protect_cleanup
       set (0, "showhiddenhandles", showhiddenhandles);
     end_unwind_protect
@@ -486,11 +491,10 @@
           parametric(data_idx) = true;
           have_cdata(data_idx) = false;
           have_3d_patch(data_idx) = false;
-
-          if (isempty (obj.keylabel))
+          if (isempty (obj.displayname))
             titlespec{data_idx} = "title \"\"";
           else
-            tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+            tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
             titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
           endif
           usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
@@ -606,10 +610,10 @@
                  have_3d_patch(data_idx) = false;
                endif
 
-               if (i > 1 || isempty (obj.keylabel))
+               if (i > 1 || isempty (obj.displayname))
                  titlespec{local_idx} = "title \"\"";
                else
-                 tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+                 tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
                  titlespec{local_idx} = cstrcat ("title \"", tmp, "\"");
                endif
                if (isfield (obj, "facecolor"))
@@ -1028,10 +1032,11 @@
             style = do_linestyle_command (obj, obj.edgecolor,
                                           data_idx, mono, 
                                           plot_stream);
-            if (isempty (obj.keylabel))
+
+            if (isempty (obj.displayname))
               titlespec{data_idx} = "title \"\"";
             else
-              tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "keylabel"));
+              tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
               titlespec{data_idx} = cstrcat ("title \"", tmp, "\"");
             endif
             withclause{data_idx} = sprintf ("with pm3d linestyle %d",
@@ -1351,7 +1356,7 @@
     else
       if (nd == 3)
         fputs (plot_stream, "set border 895;\n");
-      else
+      elseif (! isempty (axis_obj.ytick))
         if (strcmpi (axis_obj.yaxislocation, "right"))
           fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
                    axis_obj.tickdir);
@@ -1386,19 +1391,30 @@
       fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth);
     endif
 
-    if (strcmpi (axis_obj.key, "on"))
-      if (strcmpi (axis_obj.keybox, "on"))
+    if (! isempty (hlgnd) 
+        && any (strcmpi (get (get (hlegend, "children"), "visible"), "on")))
+      hlgnd.box
+      hlgnd.orientation
+      hlgnd.textposition
+      hlgnd.location
+
+      if (strcmpi (hlgnd.box, "on"))
         box = "box";
       else
         box = "nobox";
       endif
-      if (strcmpi (axis_obj.keyreverse, "on"))
+      if (strcmpi (hlgnd.orientation, "vertical"))
+        horzvert = "vertical";
+      else
+        horzvert = "horizontal";
+      endif
+      if (strcmpi (hlgnd.textposition, "right"))
         reverse = "reverse";
       else
         reverse = "noreverse";
       endif
       inout = "inside";
-      keypos = axis_obj.keypos;
+      keypos = hlgnd.location;
       if (ischar (keypos))
         keypos = lower (keypos);
         keyout = findstr (keypos, "outside");
@@ -1408,17 +1424,6 @@
         endif
       endif
       switch (keypos)
-        case -1
-          pos = "right top";
-          inout = "outside";
-        case 1
-          pos = "right top";
-        case 2
-          pos = "left top";
-        case 3
-          pos = "left bottom";
-        case {4, 0}
-          pos = "right bottom";
         case "north"
           pos = "center top";
         case "south"
@@ -1444,16 +1449,15 @@
           pos = "";
       endswitch
       if (__gnuplot_has_feature__ ("key_has_font_properties"))
-        fontspec = create_fontspec (axis_obj.fontname, axis_obj.fontsize, gnuplot_term);
+        fontspec = create_fontspec (hlgnd.fontname, hlgnd.fontsize, gnuplot_term);
       else
         fontspec = "";
       endif
-      fprintf (plot_stream, "set key %s %s %s %s %s;\n", inout, pos, box,
-               reverse, fontspec);
+      fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s;\n", 
+               inout, pos, box, reverse, horzvert, fontspec);
     else
       fputs (plot_stream, "unset key;\n");
     endif
-
     fputs (plot_stream, "set style data lines;\n");
 
     if (! use_gnuplot_for_images)
--- a/scripts/plot/__go_draw_figure__.m
+++ b/scripts/plot/__go_draw_figure__.m
@@ -48,7 +48,12 @@
           type = get (kids(i), "type");
           switch (type)
             case "axes"
-              ## Rely upon listener to convert axes position to "normalized" units.
+              if (strcmpi (get (kids (i), "tag"), "legend"))
+                continue;
+              endif
+
+              ## Rely upon listener to convert axes position 
+              ## to "normalized" units.
               orig_axes_units = get (kids(i), "units");
               orig_axes_position = get (kids(i), "position");
               unwind_protect
@@ -63,9 +68,26 @@
                 if (bg_is_set)
                   fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg));
                 endif
-                ## Return axes "units" and "position" back to their original values.
-                __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, bg_is_set);
+                ## Find if this axes has an associated legend axes and pass it
+                ## to __go_draw_axes__
+                hlegend = [];
+                fkids = get (h, "children");
+                for j = 1 : numel(fkids)
+                  if (ishandle (fkids (j)) 
+                      && strcmp (get (fkids (j), "type"), "axes") 
+                      && (strcmp (get (fkids (j), "tag"), "legend")))
+                    udata = get (fkids (j), "userdata");
+                    if (! isempty (intersect (udata.handle, kids (i))))
+                      hlegend = fkids (j);
+                      break;
+                    endif
+                  endif
+                endfor
+                __go_draw_axes__ (kids(i), plot_stream, enhanced, mono,
+                                  bg_is_set, hlegend);
               unwind_protect_cleanup
+                ## Return axes "units" and "position" back to
+                ## their original values.
                 set (kids(i), "units", orig_axes_units);
                 set (kids(i), "position", orig_axes_position);
                 bg_is_set = false;
--- a/scripts/plot/__plt_get_axis_arg__.m
+++ b/scripts/plot/__plt_get_axis_arg__.m
@@ -40,7 +40,8 @@
       && varargin{1}(1) != 0 && ! isfigure (varargin{1}(1)))
     tmp = varargin{1};
     obj = get (tmp);
-    if (strcmp (obj.type, "axes") || strcmp (obj.type, "hggroup"))
+    if ((strcmp (obj.type, "axes") && ! strcmp (obj.tag, "legend")) 
+        || strcmp (obj.type, "hggroup"))
       h = ancestor (tmp, "axes");
       varargin(1) = [];
       if (isempty (varargin))
--- a/scripts/plot/legend.m
+++ b/scripts/plot/legend.m
@@ -1,5 +1,4 @@
-## Copyright (C) 2001, 2006, 2007, 2008, 2009 Laurent Mazet
-## Copyright (C) 2006 John W. Eaton
+## Copyright (C) 2010 David Bateman
 ##
 ## This file is part of Octave.
 ##
@@ -22,6 +21,7 @@
 ## @deftypefnx {Function File} {} legend (@var{matstr})
 ## @deftypefnx {Function File} {} legend (@var{cell})
 ## @deftypefnx {Function File} {} legend (@dots{}, "location", @var{pos})
+## @deftypefnx {Function File} {} legend (@dots{}, "orientation", @var{orient})
 ## @deftypefnx {Function File} {} legend (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {} legend (@var{hobjs}, @dots{})
 ## @deftypefnx {Function File} {} legend (@var{hax}, @var{hobjs}, @dots{})
@@ -70,6 +70,10 @@
 ##   can be appended to any location string
 ## @end multitable
 ##
+## The optional parameter @var{orient} determines if the key elements
+## are placed vertically or horizontally. The allowed values are "vertical"
+## or "horizontal" with the default being "vertical".
+##
 ## The following customizations are available using @var{option}:
 ##
 ## @table @asis
@@ -94,25 +98,44 @@
 ## @end table
 ## @end deftypefn
 
-function legend (varargin)
+function [hlegend2, hobjects2, hplot2, text_strings2] = legend (varargin)
 
-  [ca, varargin, nargin] = __plt_get_axis_arg__ ("legend", varargin{:});
-  nargs = nargin;
+  if (! ishandle (varargin {1}) || (strcmp (get (varargin {1}, "type"), "axes")
+      && !strcmp (get (varargin {1}, "tag"), "legend")))
+    [ca, varargin, nargs] = __plt_get_axis_arg__ ("legend", varargin{:});
+    fig = get (ca, "parent");
+  else
+    fig = get (0, "currentfigure");
+    ca = get (fig, "currentaxes");
+  endif
 
   if (all (ishandle (varargin{1})))
     kids = flipud (varargin{1}(:));
     varargin(1) = [];
     nargs = numel (varargin);
   else
-    kids = get (ca, "children");
+    kids = ca;
+    kids (strcmp (get (ca, "tag"), "legend")) = [];
+    if (isscalar (kids))
+      kids = get(kids, "children")(:);
+    else
+      kids = [get(kids, "children"){:}](:);
+    endif
   endif
   nkids = numel (kids);
 
+  orientation = "default";
+  position = "default";
+  show = "create";
+  textpos = "default";
+  box = "default";
+
   if (nargs > 0)
     pos = varargin{nargs};
     if (isnumeric (pos) && isscalar (pos) && round (pos) == pos)
       if (pos >= -1 && pos <= 4)
-        set (ca, "keypos", pos);
+        position = {"northeastoutside", "best", "northeast",
+                    "northwest", "southwest", "southeast"} (pos + 2);
         nargs--;
       else
         error ("legend: invalid position specified");
@@ -120,17 +143,59 @@
     endif
   endif
   
-  if (nargs > 1)
+  while (nargs > 1)
     pos = varargin{nargs-1};
     str = varargin{nargs};
     if (strcmpi (pos, "location")  && ischar (str))
-      set (ca, "keypos", str);
+      position = lower (str);
+      nargs -= 2;
+    elseif (strcmpi (pos, "orientation")  && ischar (str))
+      orientation = lower (str);
       nargs -= 2;
+    else
+      break;
     endif
+  endwhile
+
+  ## Validate the orientation 
+  switch (orientation)
+    case {"vertical", "horizontal","default"}
+    otherwise
+      error ("legend: unrecognized legend orientation");
+  endswitch
+
+  ## Validate the position type is valid
+  outside = false;
+  inout = findstr (position, "outside");
+  if (! isempty (inout))
+    outside = true;
+    position = position(1:inout-1);
+  else
+    outside = false;
   endif
 
-  k = 1;
-  turn_on_legend = false;
+  switch (position)
+    case {"north", "south", "east", "west", "northeast", "northwest", ...
+          "southeast", "southwest", "default"}
+    case "best"
+      warning ("legend: 'Best' not yet implemented for location specifier\n");
+      position = "northeast";
+    otherwise
+      error ("legend: unrecognized legend position");
+  endswitch
+
+  hlegend = [];
+  fkids = get (fig, "children");
+  for i = 1 : numel(fkids)
+    if (ishandle (fkids (i)) && strcmp (get (fkids (i), "type"), "axes") 
+        && (strcmp (get (fkids (i), "tag"), "legend")))
+      udata = get (fkids (i), "userdata");
+      if (! isempty (intersect (udata.handle, ca)))
+        hlegend = fkids (i);
+        break;
+      endif
+    endif
+  endfor
 
   if (nargs == 1)
     arg = varargin{1};
@@ -139,30 +204,29 @@
         str = tolower (deblank (arg));
         switch (str)
           case {"off", "hide"}
-            set (ca, "key", "off");
+            show = "off";
             nargs--;
           case "show"
-            set (ca, "key", "on");
+            show = "on";
             nargs--;
           case "toggle"
-            val = get (ca, "key");
-            if (strcmpi (val, "on"))
-              set (ca, "key", "off");
+            if (isempty (hlegend) || strcmp (get (hlegend, "visible"), "off"))
+              show = "on";
             else
-              set (ca, "key", "on");
+              show = "off";
             endif
             nargs--;
           case "boxon"
-            set (ca, "key", "on", "keybox", "on");
+            box = "on";
             nargs--;
           case "boxoff"
-            set (ca, "keybox", "off");
+            box = "off";
             nargs--;
           case "left"
-            set (ca, "keyreverse", "off")
+            textpos = "left";
             nargs--;
           case "right"
-            set (ca, "keyreverse", "on")
+            textpos = "right";
             nargs--;
           otherwise
         endswitch
@@ -178,62 +242,572 @@
     endif
   endif
 
-  if (nargs > 0)
-    have_data = false;
-    for k = 1:nkids
-      typ = get (kids(k), "type");
-      if (strcmp (typ, "line") || strcmp (typ, "surface")
-          || strcmp (typ, "patch") || strcmp (typ, "hggroup"))
-        have_data = true;
-        break;
+  if (strcmp (show, "off"))
+    if (! isempty (hlegend))
+      set (get (hlegend, "children"), "visible", "off");
+      hlegend = [];
+    endif
+    hobjects = [];
+    hplots  = [];
+    text_strings = {};
+  elseif (strcmp (show, "on"))
+    if (! isempty (hlegend))
+      set (get (hlegend, "children"), "visible", "on");
+    else
+      hobjects = [];
+      hplots  = [];
+      text_strings = {};
+    endif
+  elseif (strcmp (box, "on"))
+    if (! isempty (hlegend))
+      set (hlegend, "visible", "on", "box", "on");
+    endif
+  elseif (strcmp (box, "off"))
+    if (! isempty (hlegend))
+      set (hlegend, "box", "off", "visible", "off");
+    endif
+  else
+    hobjects = [];
+    hplots  = [];
+    text_strings = {};
+
+    if (nargs > 0)
+      have_data = false;
+      for k = 1:nkids
+        typ = get (kids(k), "type");
+        if (strcmp (typ, "line") || strcmp (typ, "surface")
+            || strcmp (typ, "patch") || strcmp (typ, "hggroup"))
+          have_data = true;
+          break;
+        endif
+      endfor
+
+      if (! have_data)
+        warning ("legend: plot data is empty; setting key labels has no effect");
+      endif
+    endif
+
+    if (strcmp (textpos, "default"))
+      warned = false;
+      k = nkids;
+      for i = 1 : nargs
+        arg = varargin{i};
+        if (ischar (arg))
+          typ = get (kids(k), "type");
+          while (k > 0
+                 && ! (strcmp (typ, "line") || strcmp (typ, "surface")
+                       || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
+            typ = get (kids(--k), "type");
+          endwhile
+          if (k > 0)
+            if (strcmp (get (kids(k), "type"), "hggroup"))
+              hgkids = get (kids(k), "children");
+              for j = 1 : length (hgkids)
+                hgobj = get (hgkids (j));
+                if (isfield (hgobj, "displayname"))
+                  set (hgkids(j), "displayname", arg);
+                  hplots = [hplots, hgkids(j)];
+                  text_strings = {text_strings{:}, arg};
+                  break;
+                endif
+              endfor
+            else
+              set (kids(k), "displayname", arg);
+              hplots = [hplots, kids(k)];
+              text_strings = {text_strings{:}, arg};
+            endif
+
+            if (--k == 0)
+              break;
+            endif
+          elseif (! warned)
+            warned = true;
+            warning ("legend: ignoring extra labels");
+          endif
+        else
+          error ("legend: expecting argument to be a character string");
+        endif
+      endfor
+    else
+      k = nkids;
+      while (k > 0)
+        typ = get (kids(k), "type");
+        while (k > 0
+               && ! (strcmp (typ, "line") || strcmp (typ, "surface")
+                     || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
+          typ = get (kids(--k), "type");
+        endwhile
+        if (k > 0)
+          if (strcmp (get (kids(k), "type"), "hggroup"))
+            hgkids = get (kids(k), "children");
+            for j = 1 : length (hgkids)
+              hgobj = get (hgkids (j));
+              if (isfield (hgobj, "displayname") 
+                  && ! isempty (hgobj.displayname))
+                hplots = [hplots, hgkids(j)];
+                text_strings = {text_strings{:}, hbobj.displayname};
+                break;
+              endif
+            endfor
+          else
+            if (! isempty (get (kids (k), "displayname")))
+              hplots = [hplots, kids(k)];
+              text_strings = {text_strings{:}, get(kids (k), "displayname")};
+            endif
+          endif
+          if (--k == 0)
+            break;
+          endif
+        endif
+      endwhile
+    endif
+
+    if (isempty (hplots))
+      if (! isempty (hlegend))
+        fkids = get (fig, "children");
+        delete (fkids (fkids == hlegend));
+        hlegend = [];
+        hobjects = [];
+        hplots  = [];
+        text_strings = {};
+      endif
+    else
+      ## Delete the old legend if it exists
+      if (! isempty (hlegend))
+        if (strcmp (textpos, "default"))
+          textpos = get (hlegend, "textposition");
+        endif
+        if (strcmp (position, "default"))
+          position = get (hlegend, "location");
+          inout = findstr (position, "outside");
+          if (! isempty (inout))
+            outside = true;
+            position = position(1:inout-1);
+          else
+            outside = false;
+          endif
+        endif
+        if (strcmp (orientation, "default"))
+          orientation = get (hlegend, "orientation");
+        endif
+        box = get (hlegend, "box");
+        fkids = get (fig, "children");
+        delete (fkids (fkids == hlegend));
+      else
+        if (strcmp (textpos, "default"))
+          textpos = "left";
+        endif
+        if (strcmp (position, "default"))
+          position = "northeast";
+        endif
+        if (strcmp (orientation, "default"))
+          orientation = "vertical";
+        endif
+        box = "off";
       endif
-    endfor
-    if (! have_data)
-      warning ("legend: plot data is empty; setting key labels has no effect");
+      
+      ## Force the figure to be drawn here, so that the figure position
+      ## is updated correctly before reading it
+      drawnow ();
+
+      ## Get axis size and fontsize in points.  
+      ## Rely on listener to handle coversion.
+      units = get (ca(1), "units");
+      fontunits = get (ca(1), "fontunits");
+      unwind_protect
+        set (ca(1), "units", "points");
+        set (ca(1), "fontunits", "points");
+        ca_pos = get (ca(1), "position");
+        ca_outpos = get (ca(1), "outerposition");
+        ca_fontsize = get (ca(1), "fontsize");
+      unwind_protect_cleanup
+        set (ca(1), "units", units);
+        set (ca(1), "fontunits", fontunits);
+      end_unwind_protect
+
+      ## Padding between legend entries horizontally and vertically
+      xpad = 2;
+      ypad = 2;
+
+      ## Length of line segments in the legend in points
+      linelength = 15;
+
+      ## Create the axis first
+      ## FIXME hlegend should inherit properties from "ca"
+      curaxes = get (fig, "currentaxes");
+      unwind_protect
+        hlegend = axes ("tag", "legend", "userdata", struct ("handle", ca),
+                        "box", box, "outerposition", [0, 0, 0, 0],
+                        "xtick", [], "ytick", [], "xticklabel", "",
+                        "yticklabel", "", "zticklabel", "", 
+                        "xlim", [0, 1], "ylim", [0, 1], "visible", "off",
+                        "activepositionproperty", "position");
+
+        ## Add text label to the axis first, checking their extents
+        nentries = numel (hplots);
+        texthandle = [];
+        maxwidth = 0;
+        maxheight = 0;
+        for k = 1 : nentries
+          if (strcmp (textpos, "right"))
+            texthandle = [texthandle, text(0, 0, text_strings {k}, 
+                                           "horizontalalignment", "left")];
+          else
+            texthandle = [texthandle, text(0, 0, text_strings {k},
+                                           "horizontalalignment", "right")];
+          endif
+          units = get (texthandle (end), "units");
+          unwind_protect
+            set (texthandle (end), "units", "points");
+            extents = get (texthandle (end), "extent");
+            maxwidth = max (maxwidth, extents (3));
+            maxheight = max (maxheight, extents (4));
+          unwind_protect_cleanup
+            set (texthandle (end), "units", units);
+          end_unwind_protect
+        endfor
+
+        num1 = nentries;
+        if (strcmp (orientation, "vertical"))
+          height = nentries * (ypad + maxheight);
+          if (outside)
+            if (height > ca_pos (4))
+              ## Avoid shrinking the height of the axis to zero if outside
+              num1 = ca_pos(4) / (maxheight + ypad) / 2;
+            endif
+          else
+            if (height > 0.9 * ca_pos (4))
+              num1 = 0.9 * ca_pos(4) / (maxheight + ypad);
+            endif
+          endif
+        else
+          width = nentries * (ypad + maxwidth);
+          if (outside)
+            if (width > ca_pos (3))
+              ## Avoid shrinking the width of the axis to zero if outside
+              num1 = ca_pos(3) / (maxwidth + ypad) / 2;
+            endif
+          else
+            if (width > 0.9 * ca_pos (3))
+              num1 = 0.9 * ca_pos(3) / (maxwidth + ypad);
+            endif
+          endif
+        endif
+        num2 = ceil (nentries / num1);
+
+        xstep = 3 * xpad + (maxwidth + linelength);
+        if (strcmp (textpos, "right"))
+          xoffset = xpad;
+          txoffset = 2 * xpad + linelength;
+        else
+          xoffset = 2 * xpad + maxwidth;
+          txoffset = xpad + maxwidth;
+        endif
+        ystep = (ypad + maxheight);
+        yoffset = ystep / 2;
+
+        ## Place the legend in the desired position
+        if (strcmp (orientation, "vertical"))
+          lpos = [0, 0, num2 * xstep, num1 * ystep];
+        else
+          lpos = [0, 0, num1 * xstep, num2 * ystep];
+        endif
+        switch(position)
+          case "north"
+            if (outside)
+              lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
+                      ca_outpos(2) + ca_outpos(4) - lpos(4), lpos(3), lpos(4)];
+
+              new_pos = [ca_pos(1), ca_pos(2), ca_pos(3), ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1), ca_outpos(2), ca_outpos(3), ...
+                            ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
+                      ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
+            endif
+          case "south"
+            if (outside)
+              lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ca_outpos(2), ...
+                      lpos(3), lpos(4)];
+              new_pos = [ca_pos(1), ca_pos(2) + lpos(4), ca_pos(3), ...
+                         ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1), ca_outpos(2) + lpos(4), ...
+                            ca_outpos(3), ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + (ca_pos(3) - lpos(3)) / 2, ...
+                      ca_pos(2) + ypad, lpos(3), lpos(4)];
+            endif
+          case "east"
+            if (outside)
+              lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3), ...
+                      ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
+              new_pos = [ca_pos(1), ca_pos(2), ca_pos(3) - lpos(3), ca_pos(4)];
+              new_outpos = [ca_outpos(1), ca_outpos(2), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4)];
+            else
+              lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
+                      ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
+            endif
+          case "west"
+            if (outside)
+              lpos = [ca_outpos(1), ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, ...
+                      lpos(3), lpos(4)];
+              new_pos = [ca_pos(1) + lpos(3), ca_pos(2), ...
+                         ca_pos(3) - lpos(3), ca_pos(4)];
+              new_outpos = [ca_outpos(1) + lpos(3), ca_outpos(2), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4)];
+            else
+              lpos = [ca_pos(1) +  ypad, ...
+                      ca_pos(2) + (ca_pos(4) - lpos(4)) / 2, lpos(3), lpos(4)];
+            endif
+          case "northeast"
+            if (outside)
+              lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3), ...
+                      ca_outpos(2) + ca_outpos(4) - lpos(4), lpos(3), lpos(4)];
+              new_pos = [ca_pos(1), ca_pos(2), ca_pos(3) - lpos(3), ...
+                         ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1), ca_outpos(2), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
+                      ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
+            endif
+          case "northwest"
+            if (outside)
+              lpos = [ca_outpos(1), ca_outpos(2) + ca_outpos(4) - lpos(4), ...
+                      lpos(3), lpos(4)];
+              new_pos = [ca_pos(1) + lpos(3), ca_pos(2), ...
+                         ca_pos(3) - lpos(3), ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1) + lpos(3), ca_outpos(2), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + ypad, ...
+                      ca_pos(2) + ca_pos(4) - lpos(4) - ypad, lpos(3), lpos(4)];
+            endif
+          case "southeast"
+            if (outside)
+              lpos = [ca_outpos(1) + ca_outpos(3) - lpos(3), ca_outpos(2), 
+                      lpos(3), lpos(4)];
+              new_pos = [ca_pos(1), ca_pos(2) + lpos(4), ...
+                         ca_pos(3) - lpos(3), ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1), ca_outpos(2) + lpos(4), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + ca_pos(3) - lpos(3) - ypad, ...
+                      ca_pos(2) + ypad, lpos(3), lpos(4)];
+            endif
+          case "southwest"
+            if (outside)
+              lpos = [ca_outpos(1), ca_outpos(2), 0, lpos(3), lpos(4)];
+              new_pos = [ca_pos(1) +lpos(3), ca_pos(2) + lpos(4), ...
+                         ca_pos(3) - lpos(3), ca_pos(4) - lpos(4)];
+              new_outpos = [ca_outpos(1) + lpos(3), ca_outpos(2) + lpos(4), ...
+                            ca_outpos(3) - lpos(3), ca_outpos(4) - lpos(4)];
+            else
+              lpos = [ca_pos(1) + ypad, ca_pos(2) + ypad, lpos(3), lpos(4)];
+            endif
+        endswitch
+
+        units = get (hlegend, "units");
+        unwind_protect
+          set (hlegend, "units", "points");
+          set (hlegend, "position", lpos, "outerposition", lpos);
+        unwind_protect_cleanup
+          set (hlegend, "units", units);
+        end_unwind_protect
+
+        ## Now write the line segments and place the text objects correctly
+        xk = 0;
+        yk = 0;
+        for k = 1 : numel (hplots)
+          hobjects = [hobjects, texthandle (k)];
+          color = get (hplots (k), "color");
+          style = get (hplots (k), "linestyle");
+          if (! strcmp (style, "none"))
+            l1 = line ("xdata", ([xoffset, xoffset + linelength] + xk * xstep) / lpos(3),
+                       "ydata", [1, 1] .* (lpos(4) - yoffset - yk * ystep) / lpos(4), 
+                       "color", color, "linestyle", style);
+            hobjects = [hobjects, l1];
+          endif
+          marker = get (hplots (k), "marker");
+          if (! strcmp (marker, "none"))
+            l1 = line ("xdata", (xoffset + 0.5 * linelength  + xk * xstep) / lpos(3),
+                       "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4), 
+                       "color", color, "marker", marker,
+	               "markeredgecolor", get (hplots (k), "markeredgecolor"),
+	               "markerfacecolor", get (hplots (k), "markerfacecolor"),
+	               "markersize", get (hplots (k), "markersize"));
+            hobjects = [hobjects, l1];
+          endif
+          set (texthandle (k), "position", [(txoffset + xk * xstep) / lpos(3), ...
+                                            (lpos(4) - yoffset - yk * ystep) / lpos(4)]);
+
+          if (strcmp (orientation, "vertical"))
+            yk++;
+            if (yk > num1)
+              yk = 0;
+              xk++;
+            endif
+          else
+            xk++;
+            if (xk > num1)
+              xk = 0;
+              yk++;
+            endif
+          endif
+        endfor
+
+        ## Add an invisible text object to original axis
+        ## that when it is destroyed will remove the legend
+        t1 = text (0, 0, "", "parent", ca(1), "tag", "legend", 
+                   "handlevisibility", "off", "visible", "off",
+                   "xliminclude", "off", "yliminclude", "off");
+        set (t1, "deletefcn", {@deletelegend1, hlegend});
+
+        ## Resize the axis the legend is attached to if the
+        ## legend is "outside" the plot and create listener to 
+        ## resize axis to original size if the legend is deleted, 
+        ## hidden or shown
+        if (outside)
+          for i = 1 : numel (ca)
+            units = get (ca(i), "units");
+            unwind_protect
+              set (ca(i), "units", "points");
+              set (ca (i), "position", new_pos, "outerposition", new_outpos);
+            unwind_protect_cleanup
+              set (ca(i), "units", units);
+            end_unwind_protect
+          endfor
+
+          set (hlegend, "deletefcn", {@deletelegend2, ca, ...
+                                      ca_pos, ca_outpos, t1});
+          addlistener (hlegend, "visible", {@hideshowlegend, ca, ...
+                                            ca_pos, new_pos, ...
+                                            ca_outpos, new_outpos});
+        else
+          set (hlegend, "deletefcn", {@deletelegend2, ca, [], [], t1});
+        endif
+
+        addproperty ("edgecolor", hlegend, "color", [0, 0, 0]);
+        addproperty ("textcolor", hlegend, "color", [0, 0, 0]);
+        addproperty ("location", hlegend, "radio", "north|south|east|west|{northeast}|southeast|northwest|southwest|northoutside|southoutside|eastoutside|westoutside|northeastoutside|southeastoutside|northwestoutside|southwestoutside");
+
+        addproperty ("orientation", hlegend, "radio", "{vertical}|horizontal");
+        addproperty ("string", hlegend, "any", text_strings);
+        addproperty ("textposition", hlegend, "radio", "{left}|right");
+
+        if (outside)
+          set (hlegend, "location", strcat (position, "outside"), 
+               "orientation", orientation, "textposition", textpos);
+        else
+          set (hlegend, "location", position, "orientation", orientation,
+               "textposition", textpos);
+        endif
+
+        addlistener (hlegend, "edgecolor", @updatelegendtext);
+        addlistener (hlegend, "textcolor", @updatelegendtext);
+        addlistener (hlegend, "interpreter", @updatelegendtext);
+
+        ## FIXME The listener function for these essentially has to
+        ## replace the legend with a new one. For now they are just
+        ## to stock the initial values (for the gnuplot backend)
+        ##addlistener (hlegend, "location", @updatelegend);
+        ##addlistener (hlegend, "orientation", @updatelegend);
+        ##addlistener (hlegend, "string", @updatelegend);
+        ##addlistener (hlegend, "textposition", @updatelegend);
+      unwind_protect_cleanup
+        set (fig, "currentaxes", curaxes);
+      end_unwind_protect
     endif
   endif
 
-  warned = false;
-  k = nkids;
-  for i = 1:nargs
-    arg = varargin{i};
-    if (ischar (arg))
-      typ = get (kids(k), "type");
-      while (k > 1
-             && ! (strcmp (typ, "line") || strcmp (typ, "surface")
-                   || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
-        typ = get (kids(--k), "type");
-      endwhile
-      if (k > 0)
-        if (strcmp (get (kids(k), "type"), "hggroup"))
-          hgkids = get (kids(k), "children");
-          for j = 1 : length (hgkids)
-            hgobj = get (hgkids (j));
-            if (isfield (hgobj, "keylabel"))
-              set (hgkids(j), "keylabel", arg);
-              break;
-            endif
-          endfor
+  if (nargout > 0)
+    hlegend2 = hlegend2;
+    hobjects2 = hobjects;
+    hplot2 = hplots;
+    text_strings2 = text_strings;
+  endif
+
+endfunction
+
+function updatelegendtext (h, d)
+  kids = get (h, "children");
+  k = numel (kids);
+  in = get (h, "interpreter");
+  tc = get (h, "textcolor");
+  while (k > 0)
+    typ = get (kids(k), "type");
+    while (k > 0 && ! strcmp (typ, "text"))
+      typ = get (kids(--k), "type");
+    endwhile
+    if (k > 0)
+      set (kids (k), "interpreter", in, "color", tc);
+      if (--k == 0)
+        break;
+      endif
+    endif
+  endwhile
+endfunction
+
+function hideshowlegend (h, d, ca, pos1, pos2, outpos1, outpos2)
+  isvisible = strcmp (get (h, "visible"), "off");
+  if (! isvisible)
+    kids = get (h, "children");
+    for i = 1 : numel (kids)
+      if (! strcmp (get (kids(i), "visible"), "off"))
+        isvisible = true;
+        break;
+      endif
+    endfor
+  endif
+
+  for i = 1 : numel (ca)
+    if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
+        strcmp (get (ca(i), "beingdeleted"), "off"))
+      units = get (ca(i), "units");
+      unwind_protect
+        set (ca(i), "units", "points");
+        if (isvisible)
+          set (ca(i), "position", pos2, "outerposition", outpos2);
         else
-          set (kids(k), "keylabel", arg);
-        endif
-        turn_on_legend = true;
-        if (--k == 0)
-          break;
+          set (ca(i), "position", pos1, "outerposition", outpos1);
         endif
-      elseif (! warned)
-        warned = true;
-        warning ("legend: ignoring extra labels");
-      endif
-    else
-      error ("legend: expecting argument to be a character string");
+      unwind_protect_cleanup
+        set (ca(i), "units", units);
+      end_unwind_protect
     endif
   endfor
+endfunction
 
-  if (turn_on_legend)
-    set (ca, "key", "on");
+function deletelegend1 (h, d, ca)
+  if (ishandle (ca) && strcmp (get (ca, "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
+      strcmp (get (ca, "beingdeleted"), "off"))
+    delete (ca);
   endif
+endfunction
 
+function deletelegend2 (h, d, ca, pos, outpos, t1)
+  for i = 1 : numel (ca)
+    if (ishandle (ca(i)) && strcmp (get (ca(i), "type"), "axes") && 
+      (isempty (gcbf()) || strcmp (get (gcbf(), "beingdeleted"),"off")) &&
+        strcmp (get (ca(i), "beingdeleted"), "off"))
+      if (!isempty (pos) && !isempty(outpos))
+        units = get (ca(i), "units");
+        unwind_protect
+          set (ca(i), "units", "points");
+          set (ca(i), "position", pos, "outerposition", outpos, "deletefcn", "");
+        unwind_protect_cleanup
+          set (ca(i), "units", units);
+        end_unwind_protect
+      endif
+      if (i == 1)
+        set (t1, "deletefcn", "");
+        delete (t1);
+      endif
+    endif
+  endfor
 endfunction
 
 %!demo
--- a/scripts/plot/plot3.m
+++ b/scripts/plot/plot3.m
@@ -95,7 +95,8 @@
   property_set = 0;
   fmt_set = 0;
   properties = {};
-
+  tlgnd = {};
+  hlgnd = [];
   idx = 0;
 
   ## Gather arguments, decode format, and plot lines.
@@ -171,11 +172,6 @@
         error ("plot3: x, y, and z must have the same shape");
       endif
 
-      key = options.key;
-      if (! isempty (key))
-        set (gca (), "key", "on");
-      endif
-
       for i = 1 : columns (x)
         linestyle = options.linestyle;
         marker = options.marker;
@@ -183,13 +179,18 @@
            [linestyle, marker] = __next_line_style__ ();
         endif
         color = options.color;
-        if (isempty (options.color))
+        if (isempty (color))
           color = __next_line_color__ ();
         endif
 
-        tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
+        tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
                            "color", color, "linestyle", linestyle,
                            "marker", marker, properties{:});
+        key = options.key;
+        if (! isempty (key))
+          hlgnd = [hlgnd, tmp(idx)];
+          tlgnd = {tlgnd{:}, key};
+        endif
       endfor
 
       x_set = 0;
@@ -224,11 +225,6 @@
       endif
 
       options =  __default_plot_options__ ();
-      key = options.key;
-      if (! isempty (key))
-        set (gca (), "key", "on");
-      endif
-
       for i = 1 : columns (x)
         linestyle = options.linestyle;
         marker = options.marker;
@@ -240,9 +236,14 @@
           color = __next_line_color__ ();
         endif
 
-        tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
+        tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
                            "color", color, "linestyle", linestyle,
                            "marker", marker, properties{:});
+        key = options.key;
+        if (! isempty (key))
+          hlgnd = [hlgnd, tmp(idx)];
+          tlgnd = {tlgnd{:}, key};
+        endif
       endfor
 
       x = new;
@@ -296,10 +297,6 @@
     endif
 
     options =  __default_plot_options__ ();
-    key = options.key;
-    if (! isempty (key))
-      set (gca (), "key", "on");
-    endif
 
     for i = 1 : columns (x)
       linestyle = options.linestyle;
@@ -312,12 +309,21 @@
         color = __next_line_color__ ();
       endif
 
-      tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key, 
+      tmp(++idx) = line (x(:, i), y(:, i), z(:, i),
                          "color", color, "linestyle", linestyle,
                          "marker", marker, properties{:});
+      key = options.key;
+      if (! isempty (key))
+        hlgnd = [hlgnd, tmp(idx)];
+        tlgnd = {tlgnd{:}, key};
+      endif
     endfor
   endif
 
+  if (!isempty (hlgnd))
+    legend (gca(), hlgnd, tlgnd);
+  endif
+
   set (gca (), "view", [-37.5, 30]);
 
   if (nargout > 0 && idx > 0)
--- a/scripts/plot/private/__plt__.m
+++ b/scripts/plot/private/__plt__.m
@@ -37,6 +37,9 @@
     property_set = false;
     properties = {};
 
+    hlgnd = [];
+    tlgnd = {};
+
     ## Gather arguments, decode format, gather plot strings, and plot lines.
 
     retval = [];
@@ -77,10 +80,12 @@
           endif
           if (y_set)
             tmp = __plt2__ (h, x, y, options, properties);
+            [hlgnd, tlgnd] = __plt_key__ (tmp, options);
             properties = {};
             retval = [retval; tmp];
           else
             tmp = __plt1__ (h, x, options, properties);
+            [hlgnd, tlgnd] = __plt_key__ (tmp, options);
             properties = {};
             retval = [retval; tmp];
           endif
@@ -93,6 +98,7 @@
         if (y_set)
           options = __pltopt__ (caller, {""});
           tmp = __plt2__ (h, x, y, options, properties);
+          [hlgnd, tlgnd] = __plt_key__ (tmp, options);
           retval = [retval; tmp];
           x = next_arg;
           y_set = false;
@@ -108,12 +114,32 @@
 
     endwhile
 
+    if (!isempty (hlgnd))
+      legend (gca(), hlgnd, tlgnd);
+    endif
   else
     error ("__plt__: invalid number of arguments");
   endif
 
 endfunction
-  
+
+function [hlgnd, tlgnd] = __plt_key__ (h, options)
+  hlgnd = [];
+  tlgnd = {};
+  n = numel (h);
+  if (numel (options) == 1)
+    options = repmat (options(:), n, 1);
+  endif
+
+  for i = 1 : n
+    key = options.key;
+    if (! isempty (key))
+      hlgnd = [h(i), tmp(idx)];
+      tlgnd = {tlgnd{:}, key};
+    endif
+  endfor
+endfunction
+
 function retval = __plt1__ (h, x1, options, properties)
 
   if (nargin < 2 || nargin > 4)
@@ -238,10 +264,6 @@
       endif
       retval = zeros (x_nc, 1);
       for i = 1:x_nc
-        tkey = options(i).key;
-        if (! isempty (tkey))
-          set (h, "key", "on");
-        endif
         linestyle = options(i).linestyle;
         marker = options(i).marker;
         if (isempty (marker) && isempty (linestyle))
@@ -252,7 +274,7 @@
           color = __next_line_color__ ();
         endif
 
-        retval(i) = line (x(:,i), y(:,i), "keylabel", tkey, "color", color,
+        retval(i) = line (x(:,i), y(:,i), "color", color,
                           "linestyle", linestyle,
                           "marker", marker, properties{:});
       endfor
@@ -306,10 +328,6 @@
     endif
     retval = zeros (x_nc, 1);
     for i = 1:x_nc
-      tkey = options(i).key;
-      if (! isempty (tkey))
-        set (h, "key", "on");
-      endif
       linestyle = options(i).linestyle;
       marker = options(i).marker;
       if (isempty (marker) && isempty (linestyle))
@@ -320,7 +338,7 @@
         color = __next_line_color__ ();
       endif
 
-      retval(i) = line (x(:,i), y, "keylabel", tkey, "color", color,
+      retval(i) = line (x(:,i), y, "color", color,
                         "linestyle", linestyle,
                         "marker", marker, properties{:});
     endfor
@@ -352,10 +370,6 @@
   [y_nr, y_nc] = size (y);
 
   if (x_nr == 1 && x_nr == y_nr && x_nc == 1 && x_nc == y_nc)
-    key = options.key;
-    if (! isempty (key))
-      set (h, "key", "on");
-    endif
     linestyle = options.linestyle;
     marker = options.marker;
     if (isempty (marker) && isempty (linestyle))
@@ -366,7 +380,7 @@
       color = __next_line_color__ ();
     endif
 
-    retval = line (x, y, "keylabel", key, "color", color,
+    retval = line (x, y, "color", color,
                    "linestyle", linestyle,
                    "marker", marker, properties{:});
   else
@@ -396,10 +410,6 @@
     endif
     retval = zeros (len, 1);
     for i = 1:len
-      tkey = options(i).key;
-      if (! isempty (tkey))
-        set (h, "key", "on");
-      endif
       linestyle = options(i).linestyle;
       marker = options(i).marker;
       if (isempty (marker) && isempty (linestyle))
@@ -410,7 +420,7 @@
         color = __next_line_color__ ();
       endif
 
-      retval(i) = line (x, y(i), "keylabel", tkey, "color", color,
+      retval(i) = line (x, y(i), "color", color,
                         "linestyle", linestyle,
                         "marker", marker, properties{:});
     endfor
@@ -461,10 +471,6 @@
     endif
     retval = zeros (y_nc, 1);
     for i = 1:y_nc
-      tkey = options(i).key;
-      if (! isempty (tkey))
-        set (h, "key", "on");
-      endif
       linestyle = options(i).linestyle;
       marker = options(i).marker;
       if (isempty (marker) && isempty (linestyle))
@@ -475,7 +481,7 @@
         color = __next_line_color__ ();
       endif
 
-      retval(i) = line (x, y(:,i), "keylabel", tkey, "color", color,
+      retval(i) = line (x, y(:,i), "color", color,
                         "linestyle", linestyle,
                         "marker", marker, properties{:});
     endfor
@@ -506,10 +512,6 @@
     endif
     retval = zeros (len, 1);
     for i = 1:len
-      tkey = options(i).key;
-      if (! isempty (tkey))
-        set (h, "key", "on");
-      endif
       linestyle = options(i).linestyle;
       marker = options(i).marker;
       if (isempty (marker) && isempty (linestyle))
@@ -520,7 +522,7 @@
         color = __next_line_color__ ();
       endif
 
-      retval(i) = line (x(i), y, "keylabel", tkey, "color", color,
+      retval(i) = line (x(i), y, "color", color,
                         "linestyle", linestyle,
                         "marker", marker, properties{:});
     endfor
@@ -566,10 +568,6 @@
   endif
 
   if (x_nr == y_nr)
-    key = options.key;
-    if (! isempty (key))
-      set (h, "key", "on");
-    endif
     linestyle = options.linestyle;
     marker = options.marker;
     if (isempty (marker) && isempty (linestyle))
@@ -580,7 +578,7 @@
       color = __next_line_color__ ();
     endif
 
-    retval = line (x, y, "keylabel", key, "color", color,
+    retval = line (x, y, "color", color,
               "linestyle", linestyle,
               "marker", marker, properties{:});
   else
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2010-09-18  David Bateman  <dbateman@free.fr>
+
+	* graphics.h.in: Remove properties for dead legend code.
+
 2010-09-18  Ben Abbott <bpabbott@mac.com>
 
 	* graphics.cc: Replace pagetype property value custom with <custom>.
--- a/src/graphics.cc
+++ b/src/graphics.cc
@@ -3316,10 +3316,6 @@
                                 const std::string& mode)
 {
   box = "on";
-  key = "off";
-  keybox = "off";
-  keyreverse = "off";
-  keypos = 1.0;
   colororder = default_colororder ();
   dataaspectratio = Matrix (1, 3, 1.0);
   dataaspectratiomode = "auto";
--- a/src/graphics.h.in
+++ b/src/graphics.h.in
@@ -2950,10 +2950,6 @@
     BEGIN_PROPERTIES (axes)
       array_property position u , default_axes_position ()
       bool_property box , "on"
-      bool_property key , "off"
-      bool_property keybox , "off"
-      bool_property keyreverse , "off"
-      any_property keypos , 1
       array_property colororder , default_colororder ()
       array_property dataaspectratio m , Matrix (1, 3, 1.0)
       radio_property dataaspectratiomode , "{auto}|manual"
@@ -3254,7 +3250,7 @@
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
-    // properties which are not in matlab: keylabel, interpreter
+    // properties which are not in matlab: interpreter
 
     BEGIN_PROPERTIES (line)
       row_vector_property xdata u , default_data ()
@@ -3270,7 +3266,6 @@
       color_property markeredgecolor , "{auto}|none"
       color_property markerfacecolor , "auto|{none}"
       double_property markersize , 6
-      string_property keylabel , ""
       radio_property interpreter , "{tex}|none|latex"
       string_property displayname , ""
       radio_property erasemode , "{normal}|none|xor|background"
@@ -3582,7 +3577,6 @@
       color_property markeredgecolor , "{auto}|none|flat"
       color_property markerfacecolor , "auto|{none}|flat"
       double_property markersize , 6
-      string_property keylabel , ""
       radio_property interpreter , "{tex}|none|latex"
       radio_property alphadatamapping l , "none|{scaled}|direct"
       // hidden properties for limit computation
@@ -3688,7 +3682,6 @@
       color_property markeredgecolor , "{auto}|none"
       color_property markerfacecolor , "auto|{none}"
       double_property markersize , 6
-      string_property keylabel , ""
       radio_property interpreter , "{tex}|none|latex"
       array_property alphadata u , Matrix ()
       radio_property alphadatamapping l , "none|direct|{scaled}"