changeset 6146:1a6d826e92b5

[project @ 2006-11-09 03:13:11 by jwe]
author jwe
date Thu, 09 Nov 2006 03:15:23 +0000
parents 14906c2745e3
children e14b0e9b7bf7
files scripts/ChangeLog scripts/plot/__do_legend__.m scripts/plot/__errcomm__.m scripts/plot/__errplot__.m scripts/plot/__init_plot_vars__.m scripts/plot/__plot_globals__.m scripts/plot/__plt1__.m scripts/plot/__plt2__.m scripts/plot/__plt2mm__.m scripts/plot/__plt2mv__.m scripts/plot/__plt2ss__.m scripts/plot/__plt2vm__.m scripts/plot/__plt2vv__.m scripts/plot/__plt3__.m scripts/plot/__plt__.m scripts/plot/__pltopt1__.m scripts/plot/__pltopt__.m scripts/plot/contour.m scripts/plot/legend.m scripts/plot/mesh.m scripts/plot/plot3.m scripts/plot/replot.m
diffstat 22 files changed, 607 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,5 +1,40 @@
 2006-11-08  John W. Eaton  <jwe@octave.org>
 
+	* plot/legend.m: New function, adapted from Octave Forge.
+
+	* plot/__do_legend__.m: New function.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m,
+	plot/replot.m: Call it before plotting.
+
+	* plot/plot3.m, plot/mesh.m, plot/contour.m: Don't send "set
+	noparametric" to gnuplot..
+	
+	* plot/__plotopt__.m, plot/__pltopt1__.m, plot/__plt1__.m,
+	plot/__plt2__.m, plot/__plt2mm__.m, plot/__plt2mv__.m,
+	plot/__plt2ss__.m, plot/__plt2vm__.m, plot/__plt2vv__.m: Accept
+	and return key title separate from line format.  Accept format and
+	key as cellstr.  Always return data as cell array.  Return format
+	and key title as cellstr.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m:
+	Handle line format and key titles separately.
+	* plot/__plt3__.m, plot/__plt__.m: Handle data as cell array only.
+
+	* plot/__plot_globals__.m (__plot_line_offset__,
+	__plot_key_labels__, __plot_key_properties__): New global
+	variables.  Initialize them.
+	* plot/__init_plot_vars__.m (__plot_line_offset__,
+	__plot_key_labels__, __plot_key_properties__): Initialize.
+	* plot/__errplot__.m, plot/__plt3__.m, plot/__plt__.m
+	(__plot_line_offset__, __plot_key_labels__,
+	__plot_key_properties__): Store information about plot key titles.
+
+	* plot/__errplot__.m, plot/__init_plot_vars__.m, plot/__plt3__.m,
+	plot/__plt__.m: Use cf, mxi, and myi as shorthand for
+	__current_figure__, __multiplot_xi__, and __multiplot_yi__,
+	respectively.
+
+	* plot/__errcomm__.m: Allow fmt to be cellstr.
+
 	* strings/strcat.m: Disable Octave:empty-list-elements warning
 	whle concatenating args.
 
new file mode 100644
--- /dev/null
+++ b/scripts/plot/__do_legend__.m
@@ -0,0 +1,56 @@
+function __do_legend__ ()
+
+  __plot_globals__;
+
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
+
+  props = __plot_key_properties__{cf}{mxi,myi};
+
+  if (isstruct (props))
+    if (isfield (props, "visible"))
+      visible = props.visible;
+    else
+      error ("__do_legend__: missing field \"visible\"");
+    endif
+    if (isfield (props, "box"))
+      box = props.box;
+    else
+      error ("__do_legend__: missing field \"box\"");
+    endif
+    if (isfield (props, "position"))
+      position = props.position;
+    else
+      error ("__do_legend__: missing field \"position\"");
+    endif
+    if (visible)
+      switch (position)
+	case 1
+	  __gnuplot_raw__ ("set  key right top;\n")
+	case 2
+	  __gnuplot_raw__ ("set  key left top;\n")
+	case 3
+	  __gnuplot_raw__ ("set  key left bottom;\n")
+	case 4
+	  __gnuplot_raw__ ("set  key right bottom;\n")
+	case -1
+	  __gnuplot_raw__ ("set  key right top outside;\n")
+	case -2
+	  __gnuplot_raw__ ("set  key right bottom outside;\n")
+	case -3
+	  __gnuplot_raw__ ("set  key below;\n")
+      endswitch
+      if (box)
+        __gnuplot_raw__ ("set key box;\n")
+      else
+        __gnuplot_raw__ ("set key nobox;\n")
+      endif
+    else
+      __gnuplot_raw__ ("unset key;\n")
+    endif
+  else
+    error ("__do_legend__: expecting properties to be a struct");
+  endif
+
+endfunction
--- a/scripts/plot/__errcomm__.m
+++ b/scripts/plot/__errcomm__.m
@@ -57,7 +57,7 @@
       data{ndata} = a;
       while (k <= nargs)
 	a = varargin{k++};
-	if (ischar (a))
+	if (ischar (a) || iscellstr (a))
 	  __errplot__ (a, data{1:ndata});
 	  break;
 	elseif (isvector (a))
@@ -77,7 +77,7 @@
       endwhile
     endwhile
 
-    if (! ischar (a))
+    if (! (ischar (a) || iscellstr (a)))
       __errplot__ ("~", data{1:ndata});
     endif
   unwind_protect_cleanup
--- a/scripts/plot/__errplot__.m
+++ b/scripts/plot/__errplot__.m
@@ -37,20 +37,33 @@
 
   __plot_globals__;
 
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
+
   __setup_plot__ ("__gnuplot_plot__");
 
   if (nargin < 3 || nargin > 7) # at least three data arguments needed
     print_usage ();
   endif
 
-  j = __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__);
+  j = __plot_data_offset__{cf}(mxi,myi);
+
+  loff = __plot_line_offset__{cf}(mxi,myi);
 
-  fmt = __pltopt__ ("__errplot__", fstr);
+  [fmt, key] = __pltopt__ ("__errplot__", fstr);
+
+  nkey = numel (key);
 
   nplots = size (a1, 2);
   len = size (a1, 1);
   for i = 1:nplots
-    ifmt = fmt(1+mod(i,size(fmt,1)), :);
+    ifmt = fmt{1+mod(i-1,numel(fmt))};
+    if (i <= nkey)
+      __plot_key_labels__{cf}{mxi,myi}{loff} = key{i};
+    else
+      __plot_key_labels__{cf}{mxi,myi}{loff} = "";
+    endif
     switch (nargin - 1)
       case 2
 	tmp = [(1:len)', a1(:,i), a2(:,i)];
@@ -73,25 +86,29 @@
 	       a2(:,i)-a5(:,i), a2(:,i)+a6(:,i)];
     endswitch
 
-    __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j} = tmp;
+    __plot_data__{cf}{mxi,myi}{j} = tmp;
 
-    __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} \
-	= sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s",
-		   __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__},
-		   __plot_command_sep__, j, ifmt);
+    __plot_command__{cf}{mxi,myi} \
+	= sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s %s __plot_key_labels__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d}",
+		   __plot_command__{cf}{mxi,myi},
+		   __plot_command_sep__, j, ifmt,
+		   gnuplot_command_title, loff);
     __plot_command_sep__ = ",\\\n";
 
     j++;
+    loff++;
 
   endfor
 
-  __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = j;
+  __plot_data_offset__{cf}(mxi,myi) = j;
+  __plot_line_offset__{cf}(mxi,myi) = loff;
 
-  if (! isempty (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}))
-      if (__multiplot_mode__)
-	__gnuplot_raw__ ("clear\n");
-      endif
-    eval (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__});
+  if (! isempty (__plot_command__{cf}{mxi,myi}))
+    if (__multiplot_mode__)
+      __gnuplot_raw__ ("clear\n");
+    endif
+    __do_legend__ ();
+    eval (__plot_command__{cf}{mxi,myi});
   endif
 
 endfunction
--- a/scripts/plot/__init_plot_vars__.m
+++ b/scripts/plot/__init_plot_vars__.m
@@ -19,7 +19,11 @@
 
 function __init_plot_vars__ (cmd, sep, clear_data)
 
-  __plot_globals__
+  __plot_globals__;
+
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
 
   if (nargin < 3)
     clear_data = true;
@@ -31,12 +35,14 @@
     endif
   endif
 
-  __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = cmd;
+  __plot_command__{cf}{mxi,myi} = cmd;
   __plot_command_sep__ = sep;
 
   if (clear_data)
-    __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = [];
-    __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = 1;
+    __plot_data__{cf}{mxi,myi} = [];
+    __plot_data_offset__{cf}(mxi,myi) = 1;
+    __plot_line_offset__{cf}(mxi,myi) = 1;
+    __plot_key_labels__{cf}{mxi,myi} = [];
   endif
 
 endfunction
--- a/scripts/plot/__plot_globals__.m
+++ b/scripts/plot/__plot_globals__.m
@@ -44,9 +44,12 @@
 
 global __current_figure__;
 global __plot_data_offset__;
+global __plot_line_offset__;
 global __plot_command__;
 global __plot_command_sep__;
 global __plot_data__;
+global __plot_key_labels__;
+global __plot_key_properties__;
 
 if (isempty (__current_figure__))
   __current_figure__ = 1;
@@ -58,6 +61,12 @@
   __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = 1;
 endif
 
+if (length (__plot_line_offset__) < __current_figure__
+    || any (size (__plot_line_offset__{__current_figure__}) != [__multiplot_xi__, __multiplot_yi__]))
+
+  __plot_line_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = 1;
+endif
+
 if (length (__plot_command__) < __current_figure__
     || any (size (__plot_command__{__current_figure__}) != [__multiplot_xi__, __multiplot_yi__]))
   __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = "";
@@ -67,3 +76,13 @@
     || any (size (__plot_data__{__current_figure__}) != [__multiplot_xi__, __multiplot_yi__]))
   __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = [];
 endif
+
+if (length (__plot_key_labels__) < __current_figure__
+    || any (size (__plot_key_labels__{__current_figure__}) != [__multiplot_xi__, __multiplot_yi__]))
+  __plot_key_labels__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = [];
+endif
+
+if (length (__plot_key_properties__) < __current_figure__
+    || any (size (__plot_key_properties__{__current_figure__}) != [__multiplot_xi__, __multiplot_yi__]))
+  __plot_key_properties__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} = struct ("visible", true, "box", false, "position", 0);
+endif
--- a/scripts/plot/__plt1__.m
+++ b/scripts/plot/__plt1__.m
@@ -23,18 +23,26 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt1__ (x1, fmt)
+function [data, fmtstr, key] = __plt1__ (x1, fmt, keystr)
 
-  if (nargin < 1 || nargin > 2 || nargout != 2)
+  if (nargin < 1 || nargin > 3 || nargout < 2 || nargout > 3)
     print_usage ();
   endif
 
-  if (nargin == 1)
-    fmt = "";
+  if (nargin < 2)
+    fmt = {""};
   endif
 
-  if (! ischar (fmt))
-    error ("__plt1__: fmt must be a string");
+  if (nargin < 3)
+    keystr = {""};
+  endif
+
+  if (! iscellstr (fmt))
+    error ("__plt1__: fmt must be a cell array of character strings");
+  endif
+
+  if (! iscell (keystr))
+    error ("__plt1__: fmt must be a cell array");
   endif
 
   [nr, nc] = size (x1);
@@ -53,6 +61,6 @@
     x1 = (1:nr)';
   endif
 
-  [data, fmtstr] = __plt2__ (x1, x2, fmt);
+  [data, fmtstr, key] = __plt2__ (x1, x2, fmt, keystr);
 
 endfunction
--- a/scripts/plot/__plt2__.m
+++ b/scripts/plot/__plt2__.m
@@ -23,18 +23,26 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2__ (x1, x2, fmt)
+function [data, fmtstr, key] = __plt2__ (x1, x2, fmt, keystr)
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargout > 3)
     print_usage ();
   endif
 
-  if (nargin == 2)
-    fmt = "";
+  if (nargin < 3)
+    fmt = {""};
   endif
 
-  if (! ischar (fmt))
-    error ("__plt2__: fmt must be a string");
+  if (nargin < 4)
+    keystr = {""};
+  endif
+
+  if (! iscellstr (fmt))
+    error ("__plt1__: fmt must be a cell array of character strings");
+  endif
+
+  if (! iscell (keystr))
+    error ("__plt1__: fmt must be a cell array");
   endif
 
   if (any (any (imag (x1))))
@@ -47,29 +55,30 @@
 
   if (isscalar (x1))
     if (isscalar (x2))
-      [data, fmtstr] = __plt2ss__ (x1, x2, fmt);
+      [data, fmtstr, key] = __plt2ss__ (x1, x2, fmt, keystr);
     else
       error ("__plt2__: invalid data for plotting");
     endif
   elseif (isvector (x1))
     if (isvector (x2))
-      [data, fmtstr] = __plt2vv__ (x1, x2, fmt);
+      [data, fmtstr, key] = __plt2vv__ (x1, x2, fmt, keystr);
     elseif (ismatrix (x2))
-      [data, fmtstr] = __plt2vm__ (x1, x2, fmt);
+      [data, fmtstr, key] = __plt2vm__ (x1, x2, fmt, keystr);
     else
       error ("__plt2__: invalid data for plotting");
     endif
   elseif (ismatrix (x1))
     if (isvector (x2))
-      [data, fmtstr] = __plt2mv__ (x1, x2, fmt);
+      [data, fmtstr, key] = __plt2mv__ (x1, x2, fmt, keystr);
     elseif (ismatrix (x2))
-      [data, fmtstr] = __plt2mm__ (x1, x2, fmt);
+      [data, fmtstr, key] = __plt2mm__ (x1, x2, fmt, keystr);
     else
       error ("__plt2__: invalid data for plotting");
     endif
   elseif (isempty (x1) && isempty (x2))
-    data = [];
-    fmtstr = "";
+    data = {};
+    fmtstr = {};
+    key = {};
   else
     error ("__plt2__: invalid data for plotting");
   endif
--- a/scripts/plot/__plt2mm__.m
+++ b/scripts/plot/__plt2mm__.m
@@ -23,12 +23,18 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2mm__ (x, y, fmt)
+function [data, fmtstr, key] = __plt2mm__ (x, y, fmt, keystr)
+
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargout > 3)
+    print_usage ();
+  endif
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
-    print_usage ();
-  elseif (nargin == 2 || isempty (fmt))
-    fmt = " ";  ## Yes, this is intentionally not an empty string!
+  if (nargin < 3 || isempty (fmt))
+    fmt = {""};
+  endif
+
+  if (nargin < 4 || isempty (keystr))
+    keystr = {""};
   endif
 
   [x_nr, x_nc] = size (x);
@@ -41,15 +47,21 @@
       if (rows (fmt) == 1)
 	fmt = repmat (fmt, x_nc, 1);
       endif
+      if (rows (keystr) == 1)
+	keystr = repmat (keystr, x_nc, 1);
+      endif
       tmp = [x, y];
       dtmp = cell (x_nc, 1);
       ftmp = cell (x_nc, 1);
+      ktmp = cell (x_nc, 1);
       for i = 1:x_nc
 	dtmp{i} = tmp(:,[i,x_nc+i]);
-	ftmp{i} = deblank (fmt(i,:));
+	ftmp{i} = deblank (fmt{i});
+	ktmp{i} = deblank (keystr{i});
       endfor
       data = dtmp;
       fmtstr = ftmp;
+      key = ktmp;
     else
       error ("__plt2mm__: arguments must be a matrices");
     endif
--- a/scripts/plot/__plt2mv__.m
+++ b/scripts/plot/__plt2mv__.m
@@ -23,12 +23,18 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2mv__ (x, y, fmt)
+function [data, fmtstr, key] = __plt2mv__ (x, y, fmt, keystr)
+
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargou > 3)
+    print_usage ();
+  endif
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
-    print_usage ();
-  elseif (nargin == 2 || isempty (fmt))
-    fmt = " ";  ## Yes, this is intentionally not an empty string!
+  if (nargin < 3 || isempty (fmt))
+    fmt = {""};
+  endif
+
+  if (nargin < 3 || isempty (keystr))
+    keystr = {""};
   endif
 
   [x_nr, x_nc] = size (x);
@@ -56,15 +62,21 @@
     if (rows (fmt) == 1)
       fmt = repmat (fmt, x_nc, 1);
     endif
+    if (rows (keystr) == 1)
+      keystr = repmat (keystr, x_nc, 1);
+    endif
     tmp = [x, y];
     dtmp = cell (x_nc, 1);
     ftmp = cell (x_nc, 1);
+    ktmp = cell (x_nc, 1);
     for i = 1:x_nc
       dtmp{i} = tmp(:,[i,x_nc+1]);
-      ftmp{i} = deblank (fmt(i,:));
+      ftmp{i} = deblank (fmt{i});
+      ktmp{i} = deblank (keystr{i});
     endfor
     data = dtmp;
     fmtstr = ftmp;
+    key = ktmp;
   else
     error ("__plt2mv__: arguments must be a matrices");
   endif
--- a/scripts/plot/__plt2ss__.m
+++ b/scripts/plot/__plt2ss__.m
@@ -23,23 +23,35 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2ss__ (x, y, fmt)
+function [data, fmtstr, key] = __plt2ss__ (x, y, fmt, keystr)
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargout > 3)
     print_usage ();
-  elseif (nargin == 2)
-    fmt = "";
-  elseif (rows (fmt) > 1)
-    fmt = fmt (1, :);
+  endif
+
+  if (nargin < 3)
+    fmt = {""};
+  endif
+
+  if (nargin < 4)
+    keystr = {""};
+  endif
+
+  if (rows (fmt) > 1)
+    fmt = fmt(1);
+  endif
+
+  if (rows (keystr) > 1)
+    keystr = keystr(1);
   endif
 
   [x_nr, x_nc] = size (x);
   [y_nr, y_nc] = size (y);
 
   if (x_nr == 1 && x_nr == y_nr && x_nc == 1 && x_nc == y_nc)
-    tmp = [x, y];
-    data = tmp;
+    data = {[x, y]};
     fmtstr = fmt;
+    key = keystr;
   else
     error ("__plt2ss__: arguments must be scalars");
   endif
--- a/scripts/plot/__plt2vm__.m
+++ b/scripts/plot/__plt2vm__.m
@@ -23,12 +23,18 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2vm__ (x, y, fmt)
+function [data, fmtstr, key] = __plt2vm__ (x, y, fmt, keystr)
+
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargout > 3)
+    print_usage ();
+  endif
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
-    print_usage ();
-  elseif (nargin == 2 || isempty (fmt))
-    fmt = " ";  ## Yes, this is intentionally not an empty string!
+  if (nargin < 3 || isempty (fmt))
+    fmt = {""};
+  endif
+
+  if (nargin < 4 || isempty (keystr))
+    keystr = {""};
   endif
 
   [x_nr, x_nc] = size (x);
@@ -56,15 +62,21 @@
     if (rows (fmt) == 1)
       fmt = repmat (fmt, y_nc, 1);
     endif
+    if (rows (keystr) == 1)
+      keystr = repmat (keystr, y_nc, 1);
+    endif
     tmp = [x, y];
     dtmp = cell (y_nc, 1);
     ftmp = cell (y_nc, 1);
+    ktmp = cell (y_nc, 1);
     for i = 1:y_nc
       dtmp{i} = tmp(:,[1,i+1]);
-      ftmp{i} = deblank (fmt(i,:));
+      ftmp{i} = deblank (fmt{i});
+      ktmp{i} = deblank (keystr{i});
     endfor
     data = dtmp;
     fmtstr = ftmp;
+    key = ktmp;
   else
     error ("__plt2vm__: arguments must be a matrices");
   endif
--- a/scripts/plot/__plt2vv__.m
+++ b/scripts/plot/__plt2vv__.m
@@ -23,14 +23,26 @@
 
 ## Author: jwe
 
-function [data, fmtstr] = __plt2vv__ (x, y, fmt)
+function [data, fmtstr, key] = __plt2vv__ (x, y, fmt, keystr)
 
-  if (nargin < 2 || nargin > 3 || nargout != 2)
+  if (nargin < 2 || nargin > 4 || nargout < 2 || nargout > 3)
     print_usage ();
-  elseif (nargin == 2)
-    fmt = "";
-  elseif (rows (fmt) > 1)
-    fmt = fmt (1, :);
+  endif
+
+  if (nargin < 3)
+    fmt = {""};
+  endif
+
+  if (nargin < 4)
+    keystr = {""};
+  endif
+
+  if (rows (fmt) > 1)
+    fmt = fmt(1);
+  endif
+
+  if (rows (keystr) > 1)
+    keystr = keystr(1);
   endif
 
   [x_nr, x_nc] = size (x);
@@ -54,7 +66,8 @@
     error ("__plt2vv__: vector lengths must match");
   endif
 
-  data = [x, y];
+  data = {[x, y]};
   fmtstr = fmt;
+  key = keystr;
 
 endfunction
--- a/scripts/plot/__plt3__.m
+++ b/scripts/plot/__plt3__.m
@@ -33,7 +33,7 @@
 ## David Bateman <dbateman@free.fr>
 ## May 25, 2006
 
-function __plt3__ (x, usingstr, fmtstr, withstr)
+function __plt3__ (x, usingstr, fmtstr, keystr, withstr)
 
   if (nargin < 2)
     have_usingstr = false;
@@ -45,46 +45,46 @@
     fmtstr = "";
   endif
   if (nargin < 4)
+    keystr = "";
+  endif
+  if (nargin < 5)
     withstr = "";
   endif
 
   __plot_globals__;
 
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
+
   __setup_plot__ ("__gnuplot_splot__");
 
-  j = __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__);
-
-  __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j} = x;
+  j = __plot_data_offset__{cf}(mxi,myi);
+  loff = __plot_line_offset__{cf}(mxi,myi);
+  loff1 = loff;
 
-  if (iscell (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j}))
-    for i = 1:length (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j})
-    if (! have_usingstr)
-	usingstr = __make_using_clause__ (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j}{i});
-      endif
-      __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} \
-	  = sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d}{%d} %s %s",
-		     __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__},
-		     __plot_command_sep__, j, i, usingstr, fmtstr{i});
-      __plot_command_sep__ = ",\\\n";
-    endfor
-  else
-    if (! have_usingstr)
-      usingstr = __make_using_clause__ (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j});
-    endif
-    __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} \
-	= sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s %s %s",
-		   __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__},
-		   __plot_command_sep__, j, usingstr, fmtstr, withstr);
-    __plot_command_sep__ = ",\\\n";
+  __plot_data__{cf}{mxi,myi}{j} = x;
+  __plot_key_labels__{cf}{mxi,myi}{loff1++} = keystr;
+
+  if (! have_usingstr)
+    usingstr = __make_using_clause__ (__plot_data__{cf}{mxi,myi}{j});
   endif
 
-  __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = ++j;
+  __plot_command__{cf}{mxi,myi} ...
+      = sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s %s %s __plot_key_labels__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s",
+		 __plot_command__{cf}{mxi,myi},
+		 __plot_command_sep__, j++, usingstr, fmtstr,
+		 gnuplot_command_title, loff++, withstr);
+  __plot_command_sep__ = ",\\\n";
+
+  __plot_data_offset__{cf}(mxi,myi) = j;
+  __plot_line_offset__{cf}(mxi,myi) = loff;
 
   if (__multiplot_mode__)
     __gnuplot_raw__ ("clear\n");
   endif
 
-  if (! strcmp (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}, "__gnuplot_splot__"))
-    eval (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__});
+  if (! strcmp (__plot_command__{cf}{mxi,myi}, "__gnuplot_splot__"))
+    eval (__plot_command__{cf}{mxi,myi});
   endif
 endfunction
--- a/scripts/plot/__plt__.m
+++ b/scripts/plot/__plt__.m
@@ -27,6 +27,10 @@
 
   __plot_globals__;
 
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
+
   __setup_plot__ ("__gnuplot_plot__");
 
   nargs = nargin ();
@@ -34,7 +38,9 @@
   if (nargs > 1)
 
     k = 1;
-    j = __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__);
+    j = __plot_data_offset__{cf}(mxi,myi);
+    loff = __plot_line_offset__{cf}(mxi,myi);
+    loff1 = loff;
 
     x_set = false;
     y_set = false;
@@ -45,23 +51,26 @@
 
       if (nargs == 0)
 	## Force the last plot when input variables run out.
-	next_arg = "";
+	next_arg = {""};
       else
 	next_arg = varargin{k++};
       endif
 
       have_data = false;
 
-      if (ischar (next_arg))
+      if (ischar (next_arg) || iscellstr (next_arg))
 	if (x_set)
-	  fmt = __pltopt__ (caller, next_arg);
+	  [fmt, keystr] = __pltopt__ (caller, next_arg);
 	  if (y_set)
-	    [tdata, tfmtstr] = __plt2__ (x, y, fmt);
+	    [tdata, tfmtstr, key] = __plt2__ (x, y, fmt, keystr);
 	  else
-	    [tdata, tfmtstr] = __plt1__ (x, fmt);
+	    [tdata, tfmtstr, key] = __plt1__ (x, fmt, keystr);
 	  endif
 	  if (! isempty (tdata))
-	    __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j} = tdata;
+	    __plot_data__{cf}{mxi,myi}{j} = tdata;
+	    for i = 1:length (key)
+	      __plot_key_labels__{cf}{mxi,myi}{loff1++} = key{i};
+	    endfor
 	    fmtstr = tfmtstr;
 	    have_data = true;
 	  endif
@@ -72,10 +81,13 @@
 	endif
       elseif (x_set)
 	if (y_set)
-	  fmt = __pltopt__ (caller, "");
-	  [tdata, tfmtstr] = __plt2__ (x, y, fmt);
+	  [fmt, keystr] = __pltopt__ (caller, {""});
+	  [tdata, tfmtstr, key] = __plt2__ (x, y, fmt, keystr);
 	  if (! isempty (tdata))
-	    __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j} = tdata;
+	    __plot_data__{cf}{mxi,myi}{j} = tdata;
+	    for i = 1:length (key)
+	      __plot_key_labels__{cf}{mxi,myi}{loff1++} = key{i};
+	    endfor
 	    fmtstr = tfmtstr;
 	    have_data = true;
 	  endif
@@ -91,35 +103,30 @@
       endif
 
       if (have_data)
-	if (iscell (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j}))
-	  for i = 1:length (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j})
-	    usingstr = __make_using_clause__ (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j}{i});
-	    __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} \
-		= sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d}{%d} %s %s",
-			   __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__},
-			   __plot_command_sep__, j, i, usingstr, fmtstr{i});
-	    __plot_command_sep__ = ",\\\n";
-	  endfor
-	else
-	  usingstr = __make_using_clause__ (__plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{j});
-	  __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__} \
-	    = sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d} %s %s",
-		       __plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__},
-		       __plot_command_sep__, j, usingstr, fmtstr);
+	for i = 1:length (__plot_data__{cf}{mxi,myi}{j})
+	  usingstr = __make_using_clause__ (__plot_data__{cf}{mxi,myi}{j}{i});
+	  __plot_command__{cf}{mxi,myi} ...
+	      = sprintf ("%s%s __plot_data__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d}{%d} %s %s %s __plot_key_labels__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}{%d}",
+			 __plot_command__{cf}{mxi,myi},
+			 __plot_command_sep__, j, i, usingstr,
+			 fmtstr{i}, gnuplot_command_title, loff++);
 	  __plot_command_sep__ = ",\\\n";
-	endif
+	endfor
 	j++;
       endif
 
     endwhile
 
-    __plot_data_offset__{__current_figure__}(__multiplot_xi__,__multiplot_yi__) = j;
+    __plot_data_offset__{cf}(mxi,myi) = j;
+    __plot_line_offset__{cf}(mxi,myi) = loff;
 
     if (__multiplot_mode__)
       __gnuplot_raw__ ("clear\n");
     endif
-    if (! strcmp (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__}, "__gnuplot_plot__"))
-      eval (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__});
+
+    if (! strcmp (__plot_command__{cf}{mxi,myi}, "__gnuplot_plot__"))
+      __do_legend__ ();
+      eval (__plot_command__{cf}{mxi,myi});
     endif
 
   else
--- a/scripts/plot/__pltopt1__.m
+++ b/scripts/plot/__pltopt1__.m
@@ -27,7 +27,7 @@
 ## Adapted-By: jwe
 ## Maintainer: jwe
 
-function fmt = __pltopt1__ (caller, opt)
+function [fmt, keystr] = __pltopt1__ (caller, opt)
 
   set_color = 0;
   set_symbol = 0;
@@ -41,7 +41,8 @@
   set_xerrbars = 0;
   set_linestyle = "solid";
 
-  key_title = "";
+  fmt = "";
+  keystr = "";
 
   more_opts = 1;
 
@@ -65,7 +66,7 @@
   endif
 
   if (! ischar (opt))
-    error ("__pltopt1__: argument must be a string");
+    return;
   endif
 
   while (more_opts)
@@ -189,14 +190,10 @@
         if strcmp (char, ";")
           working = 0;
         else
-          if (isempty (key_title))  # needs this to avoid empty matrix warning.
-            key_title = char;
-          else
-            key_title = strcat (key_title, char);
-          endif
+          keystr = strcat (keystr, char);
         endif
       endwhile
-      key_title = undo_string_escapes (key_title);
+      keystr = undo_string_escapes (keystr);
     elseif (strcmp (char, " "))
     elseif (isempty(char))
       ## whitespace -- do nothing.
@@ -258,6 +255,4 @@
     fmt = strcat (fmt, " 1 ", symbol);
   endif
 
-  fmt = sprintf ("%s %s \"%s\" ", fmt, TITLE, key_title);
-
 endfunction
--- a/scripts/plot/__pltopt__.m
+++ b/scripts/plot/__pltopt__.m
@@ -108,17 +108,28 @@
 
 ## Author: jwe
 
-function fmt = __pltopt__ (caller, opt)
+function [fmt, keystr] = __pltopt__ (caller, opt)
 
-  if (! ischar (opt))
+  if (nargin == 2 && nargout == 2)
+    if (ischar (opt))
+      nel = rows (opt);
+    elseif (iscellstr (opt))
+      nel = numel (opt);
+    else
+      error ("__pltopt__: expecting argument to be character string or cell array of character strings");
+    endif
+    fmt = cell (nel, 1);
+    keystr = cell (nel, 1);
+    if (ischar (opt))
+      opt = cellstr (opt);
+    endif
+    for i = 1:nel
+      [tfmt, tkey]  = __pltopt1__ (caller, opt{i});
+      fmt{i} = tfmt;
+      keystr{i} = tkey;
+    endfor
+  else
     print_usage ();
   endif
 
-  nr = rows (opt);
-  fmt = "";
-  for i = 1:nr
-    t = __pltopt1__ (caller, deblank (opt(i,:)));
-    fmt(i,1:length(t)) = t;
-  endfor
-
 endfunction
--- a/scripts/plot/contour.m
+++ b/scripts/plot/contour.m
@@ -42,29 +42,24 @@
       n = y; 
     endif
     if (ismatrix (z))
-      unwind_protect
-	__gnuplot_raw__ ("set nosurface;\n");
-	__gnuplot_raw__ ("set contour;\n");
-	__gnuplot_raw__ ("set cntrparam bspline;\n");
-	if (isscalar (n))
-          command = sprintf ("set cntrparam levels %d;\n", n);
-	elseif (isvector (n))
-          tmp = sprintf ("%f", n(1));
-          for i = 2:length (n)
-            tmp = sprintf ("%s, %f", tmp, n(i));
-          endfor
-          command = sprintf ("set cntrparam levels discrete %s;\n", tmp);
-	else
-	  error ("contour: levels must be a scalar or vector") ;
-	endif
-	__gnuplot_raw__ (command);
-	__gnuplot_set__ parametric;
-	__gnuplot_raw__ ("set view 0, 0, 1, 1;\n");
-	__plt3__ (z, "", "", [gnuplot_command_with, " l 1"]);
-      unwind_protect_cleanup
-	__gnuplot_set__ noparametric;
-      end_unwind_protect
-
+      __gnuplot_raw__ ("set nosurface;\n");
+      __gnuplot_raw__ ("set contour;\n");
+      __gnuplot_raw__ ("set cntrparam bspline;\n");
+      if (isscalar (n))
+	command = sprintf ("set cntrparam levels %d;\n", n);
+      elseif (isvector (n))
+	tmp = sprintf ("%f", n(1));
+	for i = 2:length (n)
+	  tmp = sprintf ("%s, %f", tmp, n(i));
+	endfor
+	command = sprintf ("set cntrparam levels discrete %s;\n", tmp);
+      else
+	error ("contour: levels must be a scalar or vector") ;
+      endif
+      __gnuplot_raw__ (command);
+      __gnuplot_set__ parametric;
+      __gnuplot_raw__ ("set view 0, 0, 1, 1;\n");
+      __plt3__ (z, "", "", "", [gnuplot_command_with, " l 1"]);
     else
       error ("contour: z of contour (z, levels) must be a matrix");
     endif
@@ -107,28 +102,24 @@
 	  error (size_msg);
 	endif
       endif
-      unwind_protect
-	__gnuplot_raw__ ("set nosurface;\n");
-	__gnuplot_raw__ ("set contour;\n");
-	__gnuplot_raw__ ("set cntrparam bspline;\n");
-	if (isscalar (n))
-          command = sprintf ("set cntrparam levels %d;\n", n);
-	elseif (isvector (n))
-          tmp = sprintf ("%f", n(1));
-          for i = 2:length (n)
-            tmp = sprintf ("%s, %f", tmp, n(i));
-          endfor
-          command = sprintf ("set cntrparam levels discrete %s;\n", tmp);
-	else
-	  error ("contour: levels must be a scalar or vector") ;
-	endif
-	__gnuplot_raw__ (command);
-	__gnuplot_set__ parametric;
-	__gnuplot_raw__ ("set view 0, 0, 1, 1;\n");
-	__plt3__ (zz, "", "", [gnuplot_command_with, " l 1"]);
-      unwind_protect_cleanup
-	__gnuplot_set__ noparametric;
-      end_unwind_protect
+      __gnuplot_raw__ ("set nosurface;\n");
+      __gnuplot_raw__ ("set contour;\n");
+      __gnuplot_raw__ ("set cntrparam bspline;\n");
+      if (isscalar (n))
+	command = sprintf ("set cntrparam levels %d;\n", n);
+      elseif (isvector (n))
+	tmp = sprintf ("%f", n(1));
+	for i = 2:length (n)
+	  tmp = sprintf ("%s, %f", tmp, n(i));
+	endfor
+	command = sprintf ("set cntrparam levels discrete %s;\n", tmp);
+      else
+	error ("contour: levels must be a scalar or vector") ;
+      endif
+      __gnuplot_raw__ (command);
+      __gnuplot_set__ parametric;
+      __gnuplot_raw__ ("set view 0, 0, 1, 1;\n");
+      __plt3__ (zz, "", "", "", [gnuplot_command_with, " l 1"]);
     else
       error ("contour: x and y must be vectors and z must be a matrix");
     endif
new file mode 100644
--- /dev/null
+++ b/scripts/plot/legend.m
@@ -0,0 +1,160 @@
+## Copyright (C) 2001 Laurent Mazet
+## Copyright (C) 2006 John W. Eaton
+##
+## This program is free software; it is distributed in the hope that it
+## will be useful, but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+## the GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this file; see the file COPYING.  If not, write to the
+## Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+## 02111-1307, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} legend (@var{st1}, @var{st2}, @var{st3}, @var{...})
+## @deftypefnx {Function File} {} legend (@var{st1}, @var{st2}, @var{st3}, @var{...}, @var{pos})
+## @deftypefnx {Function File} {} legend (@var{matstr})
+## @deftypefnx {Function File} {} legend (@var{matstr}, @var{pos})
+## @deftypefnx {Function File} {} legend (@var{cell})
+## @deftypefnx {Function File} {} legend (@var{cell}, @var{pos})
+## @deftypefnx {Function File} {} legend ('@var{func}')
+##
+## Legend puts a legend on the current plot using the specified strings
+## as labels. Use independant strings (@var{st1}, @var{st2}, @var{st3}...), a
+## matrix of strings (@var{matstr}), or a cell array of strings (@var{cell}) to
+## specify legends. Legend works on line graphs, bar graphs, etc...
+## Be sure to call plot before calling legend.
+##
+## @var{pos} optionally  places the legend in the specified location:
+##
+## @multitable @columnfractions 0.1 0.1 0.8
+## @item @tab 0 @tab
+##   Don't move the legend box (default)
+## @item @tab 1 @tab
+##   Upper right-hand corner
+## @item @tab 2 @tab
+##   Upper left-hand corner
+## @item @tab 3 @tab
+##   Lower left-hand corner
+## @item @tab 4 @tab
+##   Lower right-hand corner
+## @item @tab -1 @tab
+##   To the top right of the plot
+## @item @tab -2 @tab
+##   To the bottom right of the plot
+## @item @tab -3 @tab
+##   To the bottom of the plot
+## @item @tab [@var{x}, @var{y}] @tab
+##   To the arbitrary postion in plot [@var{x}, @var{y}]
+## @end multitable
+##
+## Some specific functions are directely avaliable using @var{func}:
+##
+## @table @code
+## @item show
+##   Show legends from the plot
+## @item hide
+## @itemx off
+##   Hide legends from the plot
+## @item boxon
+##   Draw a box around legends
+## @item boxoff
+##   Withdraw the box around legends
+## @item left
+##   Text is to the left of the keys
+## @item right
+##   Text is to the right of the keys
+## @end table
+## @end deftypefn
+
+## PKG_ADD mark_as_command legend
+
+function legend (varargin)
+
+  __plot_globals__;
+
+  cf = __current_figure__;
+  mxi = __multiplot_xi__;
+  myi = __multiplot_yi__;
+
+  nargs = nargin;
+
+  if (nargs > 0)
+    pos = varargin{nargs};
+    if (isnumeric (pos) && isscalar (pos) && round (pos) == pos)
+      if (pos >= -3 && pos <= 4)
+	__plot_key_properties__{cf}{mxi,myi}.position = pos;
+	nargs--;
+      else
+	error ("legend: invalid position specified");
+      endif
+    endif
+  endif
+
+  if (nargs == 1)
+    arg = varargin{1};
+    if (ischar (arg))
+      if (rows (arg) == 1)
+	str = tolower (deblank (arg));
+	switch (str)
+	  case {"off", "hide"}
+	    __plot_key_properties__{cf}{mxi,myi}.visible = false;
+	  case "show"
+	    __plot_key_properties__{cf}{mxi,myi}.visible = true;
+	  case "toggle"
+	    __plot_key_properties__{cf}{mxi,myi}.visible ...
+	      = ! __plot_key_properties__{cf}{mxi,myi}.visible;
+	  case "boxon"
+	    __plot_key_properties__{cf}{mxi,myi}.visible = true;
+	    __plot_key_properties__{cf}{mxi,myi}.box = true;
+	  case "boxoff"
+	    __plot_key_properties__{cf}{mxi,myi}.box = false;
+	  otherwise
+	    __plot_key_labels__{cf}{mxi,myi}{1} = arg;
+	endswitch
+	nargs--;
+      else
+	varargin = cellstr (arg);
+	nargs = numel (vargin);
+      endif
+    elseif (iscellstr (arg))
+      varargin = arg;
+      nargs = numel (varargin);
+    else
+      error ("legend: expecting argument to be a character string");
+    endif
+  endif
+
+  for i = 1:nargs
+    arg = varargin{i};
+    if (ischar (arg))
+      __plot_key_labels__{cf}{mxi,myi}{i} = arg;
+    else
+      error ("legend: expecting argument to be a character string");
+    endif
+  endfor
+
+  if (automatic_replot)
+    replot ();
+  endif
+
+endfunction
+
+%!demo
+%! close all;
+%! plot(1:10, 1:10);
+%! title("a very long label can sometimes cause problems");
+%! legend({"hello world"}, -1)
+
+%!demo
+%! close all;
+%! labels = {};
+%! for i = 1:5
+%!     plot(1:100, i + rand(100,1)); hold on;
+%!     labels = {labels{:}, strcat("Signal ", num2str(i))};
+%! endfor; hold off;
+%! title("Signals with random offset and uniform noise")
+%! xlabel("Sample Nr [k]"); ylabel("Amplitude [V]");
+%! legend(labels, -1)
+%! legend("boxon")
--- a/scripts/plot/mesh.m
+++ b/scripts/plot/mesh.m
@@ -67,20 +67,16 @@
           zz(:,i+2) = z(:,k);
           k++;
         endfor
-	unwind_protect
-          __gnuplot_raw__ ("set hidden3d;\n");
-          __gnuplot_raw__ ("set data style lines;\n");
-          __gnuplot_raw__ ("set surface;\n");
-          __gnuplot_raw__ ("set nocontour;\n");
-          __gnuplot_raw__ ("set nologscale;\n");
-          __gnuplot_set__ parametric;
-          __gnuplot_raw__ ("set view 60, 30, 1, 1;\n");
-          __gnuplot_raw__ ("set palette defined (0 \"dark-blue\", 1 \"blue\", 2 \"cyan\", 3 \"yellow\", 4 \"red\" , 5 \"dark-red\");\n");
-          __gnuplot_raw__ ("set nocolorbox;\n");
-	  __plt3__ (zz, "", "", [gnuplot_command_with " line palette"]);
-	unwind_protect_cleanup
-	  __gnuplot_set__ noparametric;
-	end_unwind_protect
+	__gnuplot_raw__ ("set hidden3d;\n");
+	__gnuplot_raw__ ("set data style lines;\n");
+	__gnuplot_raw__ ("set surface;\n");
+	__gnuplot_raw__ ("set nocontour;\n");
+	__gnuplot_raw__ ("set nologscale;\n");
+	__gnuplot_set__ parametric;
+	__gnuplot_raw__ ("set view 60, 30, 1, 1;\n");
+	__gnuplot_raw__ ("set palette defined (0 \"dark-blue\", 1 \"blue\", 2 \"cyan\", 3 \"yellow\", 4 \"red\" , 5 \"dark-red\");\n");
+	__gnuplot_raw__ ("set nocolorbox;\n");
+	__plt3__ (zz, "", "", "", [gnuplot_command_with " line palette"]);
       else
         msg = "mesh: rows (z) must be the same as length (y) and";
         msg = sprintf ("%s\ncolumns (z) must be the same as length (x)", msg);
@@ -100,17 +96,13 @@
           zz(:,i+2) = z(:,k);
           k++;
         endfor
-	unwind_protect
-          __gnuplot_raw__ ("set data style lines;\n");
-          __gnuplot_raw__ ("set surface;\n");
-          __gnuplot_raw__ ("set nocontour;\n");
-          __gnuplot_raw__ ("set nologscale;\n");
-          __gnuplot_set__ parametric;
-          __gnuplot_raw__ ("set view 60, 30, 1, 1;\n");
-          __plt3__ (zz, "");
-	unwind_protect_cleanup
-	  __gnuplot_set__ noparametric;
-	end_unwind_protect
+	__gnuplot_raw__ ("set data style lines;\n");
+	__gnuplot_raw__ ("set surface;\n");
+	__gnuplot_raw__ ("set nocontour;\n");
+	__gnuplot_raw__ ("set nologscale;\n");
+	__gnuplot_set__ parametric;
+	__gnuplot_raw__ ("set view 60, 30, 1, 1;\n");
+	__plt3__ (zz, "");
       else
         error ("mesh: x, y, and z must have same dimensions");
       endif
--- a/scripts/plot/plot3.m
+++ b/scripts/plot/plot3.m
@@ -59,7 +59,7 @@
 ## An optional format argument can be given as
 ##
 ## @example
-## plot3 (@var{x}, @var{y}, @var{y}, @var{fmt})
+## plot3 (@var{x}, @var{y}, @var{z}, @var{fmt})
 ## @end example
 ##
 ## If the @var{fmt} argument is supplied, it is interpreted as
@@ -132,7 +132,7 @@
 ## Arguments can also be given in groups of three as
 ##
 ## @example
-## plot3 (@var{x1}, @var{y1}, @var{y1}, @var{x2}, @var{y2}, @var{y2}, @dots{})
+## plot3 (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2}, @dots{})
 ## @end example
 ## 
 ## @noindent
@@ -199,7 +199,7 @@
 	    z_set = 1;
 	  endif
 	endif
-	fmt = __pltopt__ ("plot3", new);
+	[fmt, key] = __pltopt__ ("plot3", new);
 
 	if (isvector (x) && isvector (y))
 	  if (isvector (z))
@@ -217,18 +217,13 @@
 	  error ("plot3: x, y, and z must have the same shape");
 	endif
 
-	unwind_protect
-          __gnuplot_raw__ ("set nohidden3d;\n")
-	  __gnuplot_set__ parametric; 
+	__gnuplot_raw__ ("set nohidden3d;\n")
+	__gnuplot_set__ parametric; 
 
-	  __plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
-		   ([y; NaN*ones(1,size(y,2))])(:), ...
-		   ([z; NaN*ones(1,size(z,2))])(:)],
-		    "u($1):($2):($3)", fmt);
-
-	unwind_protect_cleanup
-	  __gnuplot_set__ noparametric; 
-	end_unwind_protect
+	__plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
+		 ([y; NaN*ones(1,size(y,2))])(:), ...
+		 ([z; NaN*ones(1,size(z,2))])(:)],
+		  "u($1):($2):($3)", fmt{1}, key{1});
 
 	hold ("on");
 	x_set = 0;
@@ -260,17 +255,12 @@
 	  error ("plot3: x, y, and z must have the same shape");
 	endif
 
-	unwind_protect
-          __gnuplot_raw__ ("set nohidden3d;\n")
-	  __gnuplot_set__ parametric; 
+	__gnuplot_raw__ ("set nohidden3d;\n")
+	__gnuplot_set__ parametric; 
 
-	  __plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
-		     ([y; NaN*ones(1,size(y,2))])(:), ...
-		     ([z; NaN*ones(1,size(z,2))])(:)]);
-
-	unwind_protect_cleanup
-	  __gnuplot_set__ noparametric; 
-	end_unwind_protect
+	__plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
+		   ([y; NaN*ones(1,size(y,2))])(:), ...
+		   ([z; NaN*ones(1,size(z,2))])(:)]);
 
 	hold ("on");
 	x = new;
@@ -317,16 +307,12 @@
 	error ("plot3: x, y, and z must have the same shape");
       endif
 
-      unwind_protect
-        __gnuplot_raw__ ("set nohidden3d;\n")
-	__gnuplot_set__ parametric; 
+      __gnuplot_raw__ ("set nohidden3d;\n")
+      __gnuplot_set__ parametric; 
 
-	__plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
-		   ([y; NaN*ones(1,size(y,2))])(:), ...
-		   ([z; NaN*ones(1,size(z,2))])(:)]);
-      unwind_protect_cleanup
-	__gnuplot_set__ noparametric; 
-      end_unwind_protect
+      __plt3__ ([([x; NaN*ones(1,size(x,2))])(:), ...
+		 ([y; NaN*ones(1,size(y,2))])(:), ...
+		 ([z; NaN*ones(1,size(z,2))])(:)]);
     endif
     
   unwind_protect_cleanup
--- a/scripts/plot/replot.m
+++ b/scripts/plot/replot.m
@@ -19,7 +19,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} replot ()
-## Refressh the plot window.
+## Refresh the plot window.
 ## @end deftypefn
 
 ## Author: jwe
@@ -33,6 +33,7 @@
       if (__multiplot_mode__)
 	__gnuplot_raw__ ("clear\n");
       endif
+      __do_legend__ ();
       eval (__plot_command__{__current_figure__}{__multiplot_xi__,__multiplot_yi__});
     endif
   else