changeset 10135:4516a0c97ced

Handle linestyleorder. Remove @ markers. Treat edgecolor, markeredgecolor and markerfacecolor correctly in scatter.
author David Bateman <dbateman@free.fr>
date Wed, 20 Jan 2010 02:52:22 +0100
parents be13fa20656a
children ee18258bc002
files scripts/ChangeLog scripts/plot/__go_draw_axes__.m scripts/plot/__next_line_color__.m scripts/plot/__next_line_style__.m scripts/plot/module.mk scripts/plot/newplot.m scripts/plot/plot3.m scripts/plot/private/__color_str_rgb__.m scripts/plot/private/__default_plot_options__.m scripts/plot/private/__plt__.m scripts/plot/private/__pltopt__.m scripts/plot/private/__scatter__.m scripts/plot/private/__stem__.m src/ChangeLog src/genprops.awk src/graphics.h.in
diffstat 16 files changed, 530 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/ChangeLog	Wed Jan 20 02:52:22 2010 +0100
@@ -1,3 +1,26 @@
+2010-01-20  David Bateman  <dbateman@free.fr>
+
+	* plot/__go_draw_axes__.m (next_marker):  Remove and all uses of
+	this function.
+	Partially respect the markeredgecolor and markerfacecolor properties.
+	* plot/private/__color__str_rgb__.m: New function
+	* plot/module.mk: Add it here.
+	* plot/__next_line_style__.m: New function selected next line style
+	using the axes linestyleorder property.
+	* plot/__next_line_color.m: Increment next line style here.
+	* plot/newplot.m: Reset next line style here.
+	* plot/module.mk: Add __next_line_style__.m here.
+	* plot/plot3.m: Use __next_line_style__ here.
+	* plot/private/plt.m: And here.
+	* plot/private/stem.m: And here.
+	* plot/private/scatter.m: And here. Correctly handle nargin == 3. Use
+	matlab compatible edgecolor, markeredgecolor and markerfacecolor
+	property values.
+	* plot/private/pltopt.m: Remove "@" marker as an option.
+	* plot/private/__default_plot_options__.m: Default plot options
+	are empty signalling that __next_line_color__ and
+	__next_line_style should be used.
+
 2010-01-19  Jaroslav Hajek  <highegg@gmail.com>
 
 	* general/structfun.m: Error when invalid options are specified.
--- a/scripts/plot/__go_draw_axes__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/__go_draw_axes__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -90,10 +90,6 @@
     fputs (plot_stream, "unset x2tics;\n");
     fputs (plot_stream, "unset x2tics;\n");
 
-    # Reset next marker calculation
-    markerorder = axis_obj.markerorder;
-    next_marker (0);
-
     if (! isempty (axis_obj.title))
       t = get (axis_obj.title);
       if (isempty (t.string))
@@ -527,7 +523,7 @@
 	  endif
 
 	  style = do_linestyle_command (obj, obj.color, data_idx, mono, 
-					plot_stream, markerorder, errbars);
+					plot_stream, errbars);
 
           withclause{data_idx} = sprintf ("with %s linestyle %d",
 					  style{1}, data_idx);
@@ -728,8 +724,24 @@
 	     endif
 
              if (isfield (obj, "edgecolor"))
-	       if ((strncmp (obj.edgecolor, "flat", 4)
-		    || strncmp (obj.edgecolor, "interp", 6))
+               ## FIXME
+               ## This is the wrong thing to do as edgecolor, markeredgecolor
+               ## and markerfacecolor can have different values and we should
+               ## treat them seperately. However, the below allow the scatter
+               ## functions to work as expected, where only one of these values
+               ## is set
+	       if (strncmp (obj.edgecolor, "none", 4))
+                 if (strncmp (obj.markeredgecolor, "none", 4))
+                   ec = obj.markerfacecolor;
+                 else
+                   ec = obj.markeredgecolor;
+                 endif
+               else
+                 ec = obj.edgecolor;
+               endif
+
+	       if ((strncmp (ec, "flat", 4)
+		    || strncmp (ec, "interp", 6))
 		   && isfield (obj, "cdata"))
 		 if (ndims (obj.cdata) == 2
 		     && (size (obj.cdata, 2) == nc
@@ -746,7 +758,7 @@
 		 else
 		   ccol = cdat;
 		 endif
-		 if (strncmp (obj.edgecolor, "flat", 4))
+		 if (strncmp (ec, "flat", 4))
 		   if (numel(ccol) == 3)
 		     color = ccol;
 		   else
@@ -755,14 +767,14 @@
 		     r = max (1, min (r, size (cmap, 1)));
 		     color = cmap(r, :);
 		   endif
-		 elseif (strncmp (obj.edgecolor, "interp", 6))
+		 elseif (strncmp (ec, "interp", 6))
 		   warning ("\"interp\" not supported, using 1st entry of cdata");
 		   r = 1 + round ((size (cmap, 1) - 1) * ccol(1));
 		   r = max (1, min (r, size (cmap, 1)));
 		   color = cmap(r,:);
 		 endif
-	       elseif (isnumeric (obj.edgecolor))
-		 color = obj.edgecolor;
+	       elseif (isnumeric (ec))
+		 color = ec;
 	       else
 		 color = [0, 0, 0];
 	       endif
@@ -798,8 +810,6 @@
 	     if (isfield (obj, "marker"))
 	       if (isfield (obj, "marker"))
 		 switch (obj.marker)
-                   case "@"
-                     [pt, pt2] = next_marker (markerorder);
 		   case "+"
 		     pt = pt2 = "pt 1";
 		   case "o"
@@ -843,7 +853,7 @@
 		 endswitch
 	       endif
 	     else
-	       pt = "";
+	       pt = pt2 = "";
 	     endif
 
 	     if (mono)
@@ -1031,7 +1041,7 @@
 	    have_3d_patch(data_idx) = false;
 	    style = do_linestyle_command (obj, obj.edgecolor,
 					  data_idx, mono, 
-					  plot_stream, markerorder);
+					  plot_stream);
 	    if (isempty (obj.keylabel))
 	      titlespec{data_idx} = "title \"\"";
 	    else
@@ -1573,7 +1583,7 @@
 endfunction
 
 function style = do_linestyle_command (obj, linecolor, idx, mono,
-				       plot_stream, markerorder, errbars = "")
+				       plot_stream, errbars = "")
   style = {};
 
   fprintf (plot_stream, "set style line %d default;\n", idx);
@@ -1633,8 +1643,6 @@
 
   if (isfield (obj, "marker"))
     switch (obj.marker)
-      case "@"
-        [pt, pt2] = next_marker (markerorder);
       case "+"
 	pt = pt2 = "1";
       case "o"
@@ -1699,9 +1707,9 @@
 	  || ! isnumeric (obj.markerfacecolor) 
 	  || (isnumeric (obj.markerfacecolor) 
 	      && isequal (color, obj.markerfacecolor)))
-	style {sidx} = strcat (style{sidx}, "points");
 	if (! isempty (pt2))
 	  fprintf (plot_stream, " pointtype %s", pt2);
+	  style {sidx} = strcat (style{sidx}, "points");
 	endif
 	if (isfield (obj, "markersize"))
 	  fprintf (plot_stream, " pointsize %f", obj.markersize / 3);
@@ -1724,8 +1732,8 @@
 	  fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
 		   round (255*obj.markerfacecolor));
 	endif
-	style {sidx} = "points";
 	if (! isempty (pt2))
+	  style {sidx} = "points";
 	  fprintf (plot_stream, " pointtype %s", pt2);
 	endif
 	if (isfield (obj, "markersize"))
@@ -1741,8 +1749,8 @@
 			   && isequal (color, obj.markeredgecolor))))
 	if (sidx == 1 && ((length (style {sidx}) == 5 
 	    && strncmp (style {sidx}, "lines", 5)) || isempty (style {sidx})))
-	  style {sidx} = strcat (style{sidx}, "points");
 	  if (! isempty (pt))
+	    style {sidx} = strcat (style{sidx}, "points");
 	    fprintf (plot_stream, " pointtype %s", pt);
 	  endif
 	  if (isfield (obj, "markersize"))
@@ -1771,8 +1779,8 @@
 		     round (255*obj.markeredgecolor));
 	  endif
 	endif
-	style {sidx} = "points";
 	if (! isempty (pt))
+	  style {sidx} = "points";
 	  fprintf (plot_stream, " pointtype %s", pt);
 	endif
 	if (isfield (obj, "markersize"))
@@ -1792,57 +1800,6 @@
 
 endfunction
 
-function [pt, pt2] = next_marker (__set__)
-  persistent __next_marker__ = 0;
-
-  if (isnumeric (__set__))
-    __next_marker__ = __set__;
-  else
-
-    __marker__ = __set__ (rem (__next_marker__ ++, length (__set__)) + 1);
-    switch (__marker__)
-      case "+"
-	pt = pt2 = "1";
-      case "o"
-	pt = "6";
-	pt2 = "7";
-      case "*"
-	pt = pt2 = "3";
-      case "."
-	pt = pt2 = "0";
-      case "x"
-	pt = pt2 = "2";
-      case "s"
-	pt = "4";
-	pt2 = "5";
-      case "d"
-	pt = "13";
-	pt2 = "14";
-      case "^"
-	pt = "8";
-	pt2 = "9";
-      case "v"
-	pt = "10";
-	pt2 = "11";
-      case ">"
-	## FIXME missing point type 
-	pt = "8";
-	pt2 = "9";
-      case "<"
-	## FIXME missing point type 
-	pt = "10";
-	pt2 = "11";
-      case "p"
-	## FIXME missing point type 
-	pt = pt2 = "3";
-      case "h"
-	pt = pt2 = "3";
-      otherwise
-	pt = pt2 = "";
-    endswitch
-  endif
-endfunction
-
 function nd = __calc_dimensions__ (obj)
   kids = obj.children;
   nd = 2;
--- a/scripts/plot/__next_line_color__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/__next_line_color__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -40,6 +40,7 @@
       rgb = color_rotation(color_index,:);
       if (++color_index > num_colors)
 	color_index = 1;
+        __next_line_style__ ("incr");
       endif
     else
       error ("__next_line_color__: color_rotation not initialized");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/__next_line_style__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -0,0 +1,58 @@
+## Copyright (C) 2010 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{style} =} __next_line_style__ (@var{reset})
+## Undocumented internal function.
+## @end deftypefn
+
+## Return the next line style in the rotation.
+
+
+function [linestyle, marker] = __next_line_style__ (reset)
+
+  persistent style_rotation;
+  persistent num_styles;
+  persistent style_index;
+
+  if (nargin < 2)
+    if (nargin == 1)
+      if (ischar (reset) && strncmp (reset, "incr", 4))
+        if (isempty (style_rotation))
+          error ("__next_line_style__: style_rotation not initialized");
+        elseif (++style_index > num_styles)
+	  style_index = 1;
+        endif
+      elseif (reset)
+        style_rotation = strsplit (get (gca (), "linestyleorder"), "|");
+        num_styles = length (style_rotation);
+        style_index = 1;
+      endif
+    elseif (! isempty (style_rotation))
+      options = __pltopt__ ("__next_line_style__", 
+                            style_rotation (style_index));
+      linestyle = options.linestyle;
+      marker = options.marker;   
+    else
+      error ("__next_line_style__: style_rotation not initialized");
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
--- a/scripts/plot/module.mk	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/module.mk	Wed Jan 20 02:52:22 2010 +0100
@@ -12,6 +12,7 @@
   plot/private/__axis_label__.m \
   plot/private/__bar__.m \
   plot/private/__clabel__.m \
+  plot/private/__color_str_rgb__.m \
   plot/private/__contour__.m \
   plot/private/__default_plot_options__.m \
   plot/private/__errcomm__.m \
@@ -37,6 +38,7 @@
   plot/__go_draw_figure__.m \
   plot/__marching_cube__.m \
   plot/__next_line_color__.m \
+  plot/__next_line_style__.m \
   plot/__plt_get_axis_arg__.m \
   plot/allchild.m \
   plot/ancestor.m \
--- a/scripts/plot/newplot.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/newplot.m	Wed Jan 20 02:52:22 2010 +0100
@@ -27,6 +27,7 @@
 
   if (nargin == 0)
     __next_line_color__ (true);
+    __next_line_style__ (true);
     cf = gcf ();
     fnp = get (cf, "nextplot");
     switch (fnp)
--- a/scripts/plot/plot3.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/plot3.m	Wed Jan 20 02:52:22 2010 +0100
@@ -177,15 +177,19 @@
       endif
 
       for i = 1 : columns (x)
+        linestyle = options.linestyle;
+        marker = options.marker;
+	if (isempty (marker) && isempty (linestyle))
+	   [linestyle, marker] = __next_line_style__ ();
+	endif
 	color = options.color;
 	if (isempty (options.color))
 	  color = __next_line_color__ ();
 	endif
 
 	tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
-			   "color", color,
-			   "linestyle", options.linestyle,
-			   "marker", options.marker, properties{:});
+			   "color", color, "linestyle", linestyle,
+			   "marker", marker, properties{:});
       endfor
 
       x_set = 0;
@@ -226,15 +230,19 @@
       endif
 
       for i = 1 : columns (x)
+        linestyle = options.linestyle;
+        marker = options.marker;
+	if (isempty (marker) && isempty (linestyle))
+	   [linestyle, marker] = __next_line_style__ ();
+	endif
 	color = options.color;
 	if (isempty (color))
 	  color = __next_line_color__ ();
 	endif
 
 	tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key,
-			   "color", color,
-			   "linestyle", options.linestyle,
-			   "marker", options.marker, properties{:});
+			   "color", color, "linestyle", linestyle,
+			   "marker", marker, properties{:});
       endfor
 
       x = new;
@@ -294,15 +302,19 @@
     endif
 
     for i = 1 : columns (x)
+      linestyle = options.linestyle;
+      marker = options.marker;
+      if (isempty (marker) && isempty (linestyle))
+	[linestyle, marker] = __next_line_style__ ();
+      endif
       color = options.color;
       if (isempty (color))
 	color = __next_line_color__ ();
       endif
 
       tmp(++idx) = line (x(:, i), y(:, i), z(:, i),  "keylabel", key, 
-			 "color", color,
-			 "linestyle", options.linestyle,
-			 "marker", options.marker, properties{:});
+			 "color", color, "linestyle", linestyle,
+			 "marker", marker, properties{:});
     endfor
   endif
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/private/__color_str_rgb__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -0,0 +1,50 @@
+## Copyright (C) 2010 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave 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 Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{rgb} =} __scatter__ (@var{str})
+## Undocumented internal function.
+## @end deftypefn
+
+function rgb = __color_str_rgb__ (str)
+
+  if (ischar (str))
+    if (strncmpi (str, "black", 5))
+      rgb = [0, 0, 0];
+    elseif (strncmpi (str, "red", 3))
+      rgb = [1, 0, 0];
+    elseif (strncmpi (str, "green", 5))
+      rgb = [0, 1, 0];
+    elseif (strncmpi (str, "blue", 4))
+      rgb = [0, 0, 1];
+
+    elseif (strncmpi (str, "yellow", 6))
+      rgb = [1, 1, 0];
+    elseif (strncmpi (str, "magenta", 7))
+      rgb = [1, 0, 1];
+    elseif (strncmpi (str, "cyan", 4))
+      rgb = [0, 1, 1];
+    elseif (strncmpi (str, "white", 5))
+      rgb = [1, 1, 1];
+    else
+      rgb = [0, 0, 0];
+    endif
+  else
+    error ("expecting a string argument");
+  endif
+endfunction
--- a/scripts/plot/private/__default_plot_options__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/private/__default_plot_options__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -27,7 +27,7 @@
 
   options.key = "";
   options.color = [];
-  options.linestyle = "-";
-  options.marker = "none";
+  options.linestyle = [];
+  options.marker = [];
 
 endfunction
--- a/scripts/plot/private/__plt__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/private/__plt__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -246,14 +246,19 @@
 	if (! isempty (tkey))
 	  set (h, "key", "on");
 	endif
+        linestyle = options(i).linestyle;
+        marker = options(i).marker;
+	if (isempty (marker) && isempty (linestyle))
+	   [linestyle, marker] = __next_line_style__ ();
+	endif
 	color = options(i).color;
 	if (isempty (color))
 	  color = __next_line_color__ ();
 	endif
 
 	retval(i) = line (x(:,i), y(:,i), "keylabel", tkey, "color", color,
-			  "linestyle", options(i).linestyle,
-			  "marker", options(i).marker, properties{:});
+			  "linestyle", linestyle,
+			  "marker", marker, properties{:});
       endfor
     else
       error ("__plt2mm__: arguments must be a matrices");
@@ -309,14 +314,19 @@
       if (! isempty (tkey))
 	set (h, "key", "on");
       endif
+      linestyle = options(i).linestyle;
+      marker = options(i).marker;
+      if (isempty (marker) && isempty (linestyle))
+	[linestyle, marker] = __next_line_style__ ();
+      endif
       color = options(i).color;
       if (isempty (color))
 	color = __next_line_color__ ();
       endif
 
       retval(i) = line (x(:,i), y, "keylabel", tkey, "color", color,
-			"linestyle", options(i).linestyle,
-			"marker", options(i).marker, properties{:});
+			"linestyle", linestyle,
+			"marker", marker, properties{:});
     endfor
   else
     error ("__plt2mv__: arguments must be a matrices");
@@ -350,14 +360,19 @@
     if (! isempty (key))
       set (h, "key", "on");
     endif
+    linestyle = options.linestyle;
+    marker = options.marker;
+    if (isempty (marker) && isempty (linestyle))
+      [linestyle, marker] = __next_line_style__ ();
+    endif
     color = options.color;
     if (isempty (color))
       color = __next_line_color__ ();
     endif
 
     retval = line (x, y, "keylabel", key, "color", color,
-		   "linestyle", options.linestyle,
-		   "marker", options.marker, properties{:});
+		   "linestyle", linestyle,
+		   "marker", marker, properties{:});
   else
     error ("__plt2ss__: arguments must be scalars");
   endif
@@ -389,14 +404,19 @@
       if (! isempty (tkey))
 	set (h, "key", "on");
       endif
+      linestyle = options(i).linestyle;
+      marker = options(i).marker;
+      if (isempty (marker) && isempty (linestyle))
+        [linestyle, marker] = __next_line_style__ ();
+      endif
       color = options(i).color;
       if (isempty (color))
 	color = __next_line_color__ ();
       endif
 
       retval(i) = line (x, y(i), "keylabel", tkey, "color", color,
-			"linestyle", options(i).linestyle,
-			"marker", options(i).marker, properties{:});
+			"linestyle", linestyle,
+			"marker", marker, properties{:});
     endfor
   else
     error ("__plt2sv__: first arg must be scalar, second arg must be vector");
@@ -449,14 +469,19 @@
       if (! isempty (tkey))
 	set (h, "key", "on");
       endif
+      linestyle = options(i).linestyle;
+      marker = options(i).marker;
+      if (isempty (marker) && isempty (linestyle))
+        [linestyle, marker] = __next_line_style__ ();
+      endif
       color = options(i).color;
       if (isempty (color))
 	color = __next_line_color__ ();
       endif
 
       retval(i) = line (x, y(:,i), "keylabel", tkey, "color", color,
-			"linestyle", options(i).linestyle,
-			"marker", options(i).marker, properties{:});
+			"linestyle", linestyle,
+			"marker", marker, properties{:});
     endfor
   else
     error ("__plt2vm__: arguments must be a matrices");
@@ -489,14 +514,19 @@
       if (! isempty (tkey))
 	set (h, "key", "on");
       endif
+      linestyle = options(i).linestyle;
+      marker = options(i).marker;
+      if (isempty (marker) && isempty (linestyle))
+        [linestyle, marker] = __next_line_style__ ();
+      endif
       color = options(i).color;
       if (isempty (color))
 	color = __next_line_color__ ();
       endif
 
       retval(i) = line (x(i), y, "keylabel", tkey, "color", color,
-			"linestyle", options(i).linestyle,
-			"marker", options(i).marker, properties{:});
+			"linestyle", linestyle,
+			"marker", marker, properties{:});
     endfor
   else
     error ("__plt2vs__: first arg must be vector, second arg must be scalar");
@@ -544,14 +574,19 @@
     if (! isempty (key))
       set (h, "key", "on");
     endif
+    linestyle = options.linestyle;
+    marker = options.marker;
+    if (isempty (marker) && isempty (linestyle))
+      [linestyle, marker] = __next_line_style__ ();
+    endif
     color = options.color;
     if (isempty (color))
       color = __next_line_color__ ();
     endif
 
     retval = line (x, y, "keylabel", key, "color", color,
-	      "linestyle", options.linestyle,
-	      "marker", options.marker, properties{:});
+	      "linestyle", linestyle,
+	      "marker", marker, properties{:});
   else
     error ("__plt2vv__: vector lengths must match");
   endif
--- a/scripts/plot/private/__pltopt__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/private/__pltopt__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -155,9 +155,9 @@
 	    || strncmp (opt, "#", 1))
       n = 1;
     endif
-      options.linestyle = opt(1:n);
-      opt(1:n) = [];
-      have_linestyle = true;
+    options.linestyle = opt(1:n);
+    opt(1:n) = [];
+    have_linestyle = true;
   endif
 
   while (! isempty (opt))
@@ -177,6 +177,10 @@
 	      || topt == ">" || topt == "<" || topt == "p"
 	      || topt == "h" || topt == "@")
 	have_marker = true;
+        ## Backward compatibility.  Leave undocumented.
+	if (topt == "@")
+	  topt = "+";
+	endif
 	options.marker = topt;
 ### Numeric color specs for backward compatibility.  Leave undocumented.
       elseif (topt == "k" || topt == "0")
@@ -224,8 +228,12 @@
     opt(1:n) = [];
   endwhile
 
-  if (have_marker && ! have_linestyle)
+  if (! have_linestyle && have_marker)
     options.linestyle = "none";
   endif
 
+  if (have_linestyle && ! have_marker)
+    options.marker = "none";
+  endif
+
 endfunction
--- a/scripts/plot/private/__scatter__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/private/__scatter__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -52,7 +52,7 @@
     endif
   endfor
 
-  if (istart < nargin && firstnonnumeric > istart)
+  if (istart <= nargin)
     s = varargin{istart};
     if (isempty (s))
       s = 6;
@@ -67,14 +67,12 @@
       if (columns (c) != 3)
 	c = c(:);
       endif
-    elseif (isempty (c))
-      c = __next_line_color__();
     endif
   elseif (firstnonnumeric == istart + 1 && ischar (varargin{istart + 1}))
     c = varargin{istart + 1};
     firstnonnumeric++;
   else
-    c = __next_line_color__();
+    c = [];
   endif
 
   newargs = {};
@@ -93,6 +91,8 @@
 	marker = linespec.marker;
 	if (strncmp (marker, "none", 4))
 	  marker = "o";
+        elseif (isempty (marker))
+          [dummy, marker] = __next_line_style__ ();
 	endif
       else
 	error ("%s: invalid linespec", fcn);
@@ -105,6 +105,10 @@
     endif
   endwhile
 
+  if (isempty (c))
+    c = __next_line_color__();
+  endif
+
   hg = hggroup ();
   newargs = __add_datasource__ (fcn, hg, {"x", "y", "z", "c", "size"}, 
 			     newargs{:});
@@ -112,7 +116,11 @@
   addproperty ("xdata", hg, "data", x);
   addproperty ("ydata", hg, "data", y);
   addproperty ("zdata", hg, "data", z);
-  addproperty ("cdata", hg, "data", c);
+  if (ischar (c))
+    addproperty ("cdata", hg, "data", __color_str_rgb__ (c));
+  else
+    addproperty ("cdata", hg, "data", c);
+  endif
   addproperty ("sizedata", hg, "data", s);
   addlistener (hg, "xdata", @update_data);
   addlistener (hg, "ydata", @update_data);
@@ -128,30 +136,43 @@
       s = repmat (s, numel(x), 1);
     endif
 
-    if (ischar (c))
+    if (ischar (c) || rows(c) == 1)
       for i = 1 : numel (x)
-        h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                          "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
-                          "facecolor", "none", "edgecolor", c, "marker", marker, 
-                          "markersize", s(i), "linestyle", "none");
         if (filled)
-          set(h, "markerfacecolor", c); 
+          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                            "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+                            "facecolor", "none", "edgecolor", "none", 
+                            "marker", marker,  "markersize", s(i), 
+                            "markeredgecolor", none, "markerfacecolor", c,
+                            "linestyle", "none");
+        else
+          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                            "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+                            "facecolor", "none", "edgecolor", "none", 
+                            "marker", marker,  "markersize", s(i), 
+                            "markeredgecolor", c, "markerfacecolor", "none",
+                            "linestyle", "none");
         endif
       endfor
     else
-      if (rows (c) == 1)
-        c = repmat (c, numel (x), 1);
-      endif
+      for i = 1 : numel (x)
+        if (filled)
+          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                            "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+                            "facecolor", "none", "edgecolor", "none", 
+                            "marker", marker, "markersize", s(i), 
+                            "markeredgecolor", "none", 
+                            "markerfacecolor", "flat",
+                            "cdata", c(i,:), "linestyle", "none");
+        else
+          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                            "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
+                            "facecolor", "none", "edgecolor", "none", 
+                            "marker", marker, "markersize", s(i), 
+                            "markeredgecolor", "flat", 
+                            "markerfacecolor", "none",
+                            "cdata", c(i,:), "linestyle", "none");
 
-      for i = 1 : numel (x)
-        h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                          "faces", 1, "vertices", [x(i), y(i), z(i,:)], 
-                          "facecolor", "none", "edgecolor", "flat", 
-                          "cdata", c(i,:), 
-                          "marker", marker, "markersize", s(i), 
-                          "linestyle", "none");
-        if (filled)
-          set(h, "markerfacecolor", "flat"); 
         endif
       endfor
     endif
@@ -163,44 +184,52 @@
     vert = [x, y, z];
 
     if (ischar (c) || rows (c) == 1)
-      h = render_size_color (hg, vert, s, c, marker, filled); 
+      h = render_size_color (hg, vert, s, c, marker, filled, false); 
     else
       [cc, idx] = unique_idx (c, "rows");
       if (isscalar (s))
         for i = 1:rows (x)
-          h = render_size_color (hg, vert(idx{i},:), s, cc(i,:), marker, filled);
+          h = render_size_color (hg, vert(idx{i},:), s, cc(i,:), 
+                                 marker, filled, true);
         endfor
       else
         for i = 1:rows (x)
-          h = render_size_color (hg, vert(idx{i},:), s(idx{i}), cc(i,:), marker, filled);
+          h = render_size_color (hg, vert(idx{i},:), s(idx{i}), cc(i,:), 
+                                 marker, filled, true);
         endfor
       endif
     endif
 
   endif
 
-    if (! ischar (c))
-      ax = get (hg, "parent");
-      clim = get (ax, "clim");
-      if (min(c(:)) < clim(1))
-        clim(1) = min(c(:));
-        set (ax, "clim", clim);
-      endif
-      if (max(c(:)) > clim(2))
-        set (ax, "clim", [clim(1), max(c(:))]);
-      endif
+  if (! ischar (c) && rows (c) > 1)
+    ax = get (hg, "parent");
+    clim = get (ax, "clim");
+    if (min(c(:)) < clim(1))
+      clim(1) = min(c(:));
+      set (ax, "clim", clim);
     endif
+    if (max(c(:)) > clim(2))
+      set (ax, "clim", [clim(1), max(c(:))]);
+    endif
+  endif
 
   addproperty ("linewidth", hg, "patchlinewidth", 0.5);
   addproperty ("marker", hg, "patchmarker", marker);
-  if (numel (x) > 0)
-    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "none");
+  if (filled)
     addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", "none");
+    if (ischar (c) || rows (c) == 1)
+      addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", c);
+    else
+      addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "flat");
+    endif
   else
-    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", 
-		 get (h, "markerfacecolor"));
-    addproperty ("markeredgecolor", hg, "patchmarkeredgecolor",
-		 get (h, "color"));
+    addproperty ("markerfacecolor", hg, "patchmarkerfacecolor", "none");
+    if (ischar (c) || rows (c) == 1)
+      addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", c);
+    else
+      addproperty ("markeredgecolor", hg, "patchmarkeredgecolor", "flat");
+    endif
   endif
   addlistener (hg, "linewidth", @update_props); 
   addlistener (hg, "marker", @update_props); 
@@ -235,35 +264,54 @@
   endif
 endfunction
 
-function h = render_size_color(hg, vert, s, c, marker, filled)
+function h = render_size_color(hg, vert, s, c, marker, filled, isflat)
   if (isscalar (s))
     x = vert(:,1);
     y = vert(:,2);
     z = vert(:,3:end);
-    if (ischar (c))
-      h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
-                        "faces", 1, "vertices", vert, 
-                        "facecolor", "none", "edgecolor", c, "marker", marker, 
-                        "markersize", s, "linestyle", "none");
+    if (ischar (c) || !isflat)
       if (filled)
-        set(h, "markerfacecolor", c); 
+        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1, "vertices", vert, 
+                          "facecolor", "none", "edgecolor", "none", 
+                          "marker", marker, 
+                          "markeredgecolor", "none", 
+                          "markerfacecolor", c,
+                          "markersize", s, "linestyle", "none");
+      else
+        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1, "vertices", vert, 
+                          "facecolor", "none", "edgecolor", "none", 
+                          "marker", marker, 
+                          "markeredgecolor", c, 
+                          "markerfacecolor", "none",
+                          "markersize", s, "linestyle", "none");
       endif
     else
-      h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
-                        "faces", 1, "vertices", vert, 
-                        "facecolor", "none", "edgecolor", "flat", 
-                        "cdata", c, 
-                        "marker", marker, "markersize", s, 
-                        "linestyle", "none");
       if (filled)
-        set(h, "markerfacecolor", "flat"); 
+        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1, "vertices", vert,
+                          "facecolor", "none", "edgecolor", "none", 
+                          "marker", marker, "markersize", s, 
+                          "markeredgecolor", "none", 
+                          "markerfacecolor", "flat",
+                          "cdata", c, "linestyle", "none");
+      else
+        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+                          "faces", 1, "vertices", vert,
+                          "facecolor", "none", "edgecolor", "none", 
+                          "marker", marker, "markersize", s, 
+                          "markeredgecolor", "flat", 
+                          "markerfacecolor", "none",
+                          "cdata", c, "linestyle", "none");
       endif
     endif
   else
     ## FIXME: round the size to one decimal place. It's not quite right, though.
     [ss, idx] = unique_idx (ceil (s*10) / 10);
     for i = 1:rows (ss)
-      h = render_size_color (hg, vert(idx{i},:), ss(i), c, marker, filled);
+      h = render_size_color (hg, vert(idx{i},:), ss(i), c, 
+                             marker, filled, isflat);
     endfor
   endif
 endfunction
--- a/scripts/plot/private/__stem__.m	Tue Jan 19 21:45:21 2010 +0100
+++ b/scripts/plot/private/__stem__.m	Wed Jan 20 02:52:22 2010 +0100
@@ -443,8 +443,14 @@
       mc = lc = cur_props(i).color;
     elseif (isfield (cur_props(i), "linestyle"))
       ls = cur_props(i).linestyle;
+      if (isempty (ls))
+        ls = __next_line_style__ ();
+      endif
     elseif (isfield (cur_props(i), "marker") && ! strcmpi (cur_props(i).marker, "none"))
       ms = cur_props(i).marker;
+      if (isempty (ms))
+        [dummy, ms] = __next_line_style__ ();
+      endif
     endif
   endfor
 endfunction
--- a/src/ChangeLog	Tue Jan 19 21:45:21 2010 +0100
+++ b/src/ChangeLog	Wed Jan 20 02:52:22 2010 +0100
@@ -1,3 +1,10 @@
+2010-01-20  David Bateman  <dbateman@free.fr>
+
+	* graphics.h.in (string_array_property): New property.
+	(axes::properties): Use it here for the linestyleorder property.
+	Remove the markerorder property.
+	* genprops.awk: Emit string_array_property
+
 2010-01-19  Jaroslav Hajek  <highegg@gmail.com>
 
 	* DLD-FUNCTIONS/strfind.cc: Optimize searching for 1 or 2 characters.
--- a/src/genprops.awk	Tue Jan 19 21:45:21 2010 +0100
+++ b/src/genprops.awk	Wed Jan 20 02:52:22 2010 +0100
@@ -300,6 +300,8 @@
         emit_get_accessor(i, "graphics_handle", "handle_value");
       else if (type[i] == "string_property")
         emit_get_accessor(i, "std::string", "string_value");
+      else if (type[i] == "string_array_property")
+          emit_get_accessor(i, "octave_value", "get");
       else if (type[i] == "double_property")
         emit_get_accessor(i, "double", "double_value");
       else if (type[i] == "double_radio_property")
--- a/src/graphics.h.in	Tue Jan 19 21:45:21 2010 +0100
+++ b/src/graphics.h.in	Wed Jan 20 02:52:22 2010 +0100
@@ -514,6 +514,166 @@
 
 // ---------------------------------------------------------------------
 
+class string_array_property : public base_property
+{
+public:
+  enum desired_enum { string_t, cell_t };
+
+  string_array_property (const std::string& s, const graphics_handle& h,
+		  const std::string& val = "", const char& sep = '|', 
+		  const desired_enum& typ = string_t)
+    : base_property (s, h), desired_type (typ), separator (sep)
+    { 
+      size_t pos = 0;
+
+      while (true)
+	{
+	  size_t new_pos = val.find_first_of (separator, pos);
+
+	  if (new_pos == std::string::npos)
+	    {
+	      str.append (val.substr (pos));
+	      break;
+	    }
+	  else
+	    str.append (val.substr (pos, new_pos - pos));
+
+	  pos = new_pos + 1;
+	}
+    }
+
+  string_array_property (const std::string& s, const graphics_handle& h, 
+		  const Cell& c, const char& sep = '|', 
+		  const desired_enum& typ = string_t)
+    : base_property (s, h), desired_type (typ), separator (sep)
+    { 
+      if (c.is_cellstr ())
+	{
+	  string_vector strings (c.numel ());
+
+	  for (octave_idx_type i = 0; i < c.numel (); i++)
+	    strings (i) = c(i).string_value ();
+
+	  str = strings;
+	}
+      else
+        error ("set: invalid order property value for \"%s\"",
+               get_name ().c_str ());
+    }
+
+  string_array_property (const string_array_property& p)
+    : base_property (p), desired_type (p.desired_type),
+      separator (p.separator), str (p.str) { }
+
+  octave_value get (void) const
+    { 
+      if (desired_type == string_t)
+	return octave_value (string_value ());
+      else
+	return octave_value (cell_value ());
+    }
+
+  std::string string_value (void) const 
+    { 
+      std::string _str;
+
+      for (octave_idx_type i = 0; i < str.length (); i++)
+	{
+	  _str += str(i);
+	  if (i != str.length() - 1)
+	    _str += separator;
+	}
+
+      return _str;
+    }
+
+  Cell cell_value (void) const {return Cell (str);}
+
+  string_array_property& operator = (const octave_value& val)
+    {
+      set (val);
+      return *this;
+    }
+
+  base_property* clone (void) const { return new string_array_property (*this); }
+
+protected:
+  bool do_set (const octave_value& val)
+    {
+      if (val.is_string ())
+	{
+	  bool replace = false;
+	  std::string new_str = val.string_value ();
+	  string_vector strings;
+	  size_t pos = 0;
+
+	  while (pos != std::string::npos)
+	    {
+	      size_t new_pos = new_str.find_first_of (separator, pos);
+
+	      if (new_pos == std::string::npos)
+		{
+		  strings.append (new_str.substr (pos));
+		  break;
+		}
+	      else
+		strings.append (new_str.substr (pos, new_pos - pos));
+
+	      pos = new_pos + 1;
+	    }
+
+	  if (str.numel () == strings.numel ())
+	    {
+	      for (octave_idx_type i = 0; i < str.numel (); i++)
+		if (strings (i) != str(i))
+		  {
+		    replace = true;
+		    break;
+		  }
+	    }
+	  else
+	    replace = true;
+
+	  if (replace)
+	    {
+	      str = strings;
+	      return true;
+	    }
+	}
+      else if (val.is_cellstr ())
+	{
+	  bool replace = false;
+	  Cell new_cell = val.cell_value ();
+
+	  string_vector strings (new_cell.numel ());
+
+	  for (octave_idx_type i = 0; i < new_cell.numel (); i++)
+	    {
+	      strings (i) = new_cell(i).string_value ();
+	      if (strings (i) != str (i))
+		replace = true;
+	    }
+
+	  if (replace)
+	    {
+	      str = strings;
+	      return true;
+	    }
+	}
+      else
+        error ("set: invalid string property value for \"%s\"",
+               get_name ().c_str ());
+      return false;
+    }
+
+private:
+  desired_enum desired_type;
+  char separator;
+  string_vector str;
+};
+
+// ---------------------------------------------------------------------
+
 class radio_values
 {
 public:
@@ -2761,11 +2921,8 @@
       radio_property fontunits , "{points}|normalized|inches|centimeters|pixels"
       radio_property fontweight , "{normal}|light|demi|bold"
       radio_property gridlinestyle , "-|--|{:}|-.|none"
-      // FIXME -- should be kind of string array.
-      string_property linestyleorder , "-"
+      string_array_property linestyleorder , "-"
       double_property linewidth , 0.5
-      // FIXME -- should be kind of string array.
-      string_property markerorder , "+o*xsd^vh."
       radio_property minorgridlinestyle , "-|--|{:}|-.|none"
       array_property plotboxaspectratio m , Matrix (1, 3, 1.0)
       radio_property plotboxaspectratiomode , "{auto}|manual"