* Bug 15481 fixed: scatter() & scatter3d() 17/21417/3
Samuel GOUGEON [Thu, 20 Feb 2020 18:44:57 +0000 (19:44 +0100)]
  http://bugzilla.scilab.org/15481

  Moved from master @ https://codereview.scilab.org/21373

  A short list of fixed issues:

  USAGES
  * scatter() nor scatter3d() could display a single data point (reported bug).
  * The type of X, Y, Z was not checked, leading to weird error messages.
  * X, Y (and Z) should have had the same shape, while only the same
    length is actually required.
  * The properties names were case-sensitive.
  * Colors could not be scaled to data < %eps.
  * Colors could not be specified by their #RRGGBB code nor their index.
  * The handle of polylines was returned even when not requested.
  * The example cleared the current figure instead of the current axes.

  INTERNAL
    a) Warnings were generated, instead of errors.
    b) Warnings messages were not standard.
    c) Warning messages were not localized.
    d) The same colorIndex name was used to name a function and
       a regular variable.

  DOCUMENTATION
    * The thickness option is for all markers. It was not indicated.
    * Examples:
      scatter():
      . 2 clouds of points : images did not match the code
        (negative coord impossible from rand())
      . First spiral: the image did not match with the example code:
        The code does not vary the size of dots.
      scatter3d(): last example:
       . p refered to nothing.
       . color() was called with RGB in [0,1] instead of in [0,255] => dark

  * UNIT TESTS: More than 50+50 tests added.

  * FEATURES ADDED:
      + colors identified with "#RRGGBB" or indices
      + options "smallOnTop" and "datatips"
        (documented only for scatter())

Change-Id: Id26797f8e713d7e3078031c8fc4d1db7c529606c

28 files changed:
scilab/CHANGES.md
scilab/modules/graphics/help/en_US/2d_plot/scatter.xml
scilab/modules/graphics/help/en_US/3d_plot/scatter3d.xml
scilab/modules/graphics/macros/scatter.sci
scilab/modules/graphics/macros/scatter3d.sci
scilab/modules/graphics/tests/nonreg_tests/bug_15481.tst [new file with mode: 0644]
scilab/modules/graphics/tests/unit_tests/scatter.dia.ref [deleted file]
scilab/modules/graphics/tests/unit_tests/scatter.tst
scilab/modules/graphics/tests/unit_tests/scatter3d.tst
scilab/modules/helptools/etc/images_md5.txt
scilab/modules/helptools/images/scatter3d_1.png
scilab/modules/helptools/images/scatter3d_2.png
scilab/modules/helptools/images/scatter3d_3.png
scilab/modules/helptools/images/scatter3d_4.png
scilab/modules/helptools/images/scatter3d_5.png [deleted file]
scilab/modules/helptools/images/scatter3d_6.png [deleted file]
scilab/modules/helptools/images/scatter3d_7.png [deleted file]
scilab/modules/helptools/images/scatter3d_8.png [deleted file]
scilab/modules/helptools/images/scatter3d_9.png [deleted file]
scilab/modules/helptools/images/scatter_1.png
scilab/modules/helptools/images/scatter_2.png
scilab/modules/helptools/images/scatter_3.png
scilab/modules/helptools/images/scatter_4.png
scilab/modules/helptools/images/scatter_5.png
scilab/modules/helptools/images/scatter_6.png [deleted file]
scilab/modules/helptools/images/scatter_7.png [deleted file]
scilab/modules/helptools/images/scatter_8.png [deleted file]
scilab/modules/helptools/images/scatter_9.png [deleted file]

index 313e68a..3bbcefe 100644 (file)
@@ -237,6 +237,7 @@ Feature changes and additions on 6.1.1
 * `mopen` and `mclose` now handle multiple files and file descriptors.
 * `hash` function with SHA-1,SHA-2 and SHA-3 Secure Hash Algorithms has been added.
 * `loglog`, `semilogx`, `semilogy` Matlab-compatible functions added.
+* `scatter` and `scatter3d` are reforged. New `scatter` options: `"smallOnTop"` and `"datatips"`.
 
 
 Help pages:
@@ -563,6 +564,7 @@ Bug Fixes
 * [#15428](https://bugzilla.scilab.org/15428): `repmat` was slow. Its code did not use `kron` and was complex.
 * [#15431](https://bugzilla.scilab.org/15431): The empty matrix `[]` and its non-convertibility were poorly documented.
 * [#15451](https://bugzilla.scilab.org/15451): The code was not adapted to use `lucene 4.10` in Debian.
+* [#15481](https://bugzilla.scilab.org/15481): `scatter` and `scatter3d` failed when specifying a single data point.
 * [#15514](https://bugzilla.scilab.org/15514): The `set` documentation page needed to be overhauled.
 * [#15517](https://bugzilla.scilab.org/15517): `factorial` could be actually used up to only n=170.
 * [#15522](https://bugzilla.scilab.org/15522): `unique` was not able to consider all Nan values as the same value. A `uniqueNan` option now allows it.
index f916f15..68f30bf 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) Scilab Enterprises - 2015 - 2012 - Juergen Koch
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2020 - Samuel GOUGEON
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
     <refsynopsisdiv>
         <title>Syntax</title>
         <synopsis>
-            polyline = scatter(x, y, msizes, mcolors, "fill", marker, &lt;marker_property, value&gt;)
-            polyline = scatter(axes_handle,...)
+            scatter()   // Example
+            scatter(x, y)
+            scatter(x, y, msizes)
+            scatter(x, y, msizes, mcolors)
+            scatter(.., "fill")
+            scatter(.., "smallOnTop")
+            scatter(.., marker)
+            scatter(..., &lt;marker_property, value>)
+            scatter(axes, ..)
+            polyline = scatter(..)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
                 </listitem>
             </varlistentry>
             <varlistentry>
+                <term>axes</term>
+                <listitem>
+                    Handle of the graphical axes in which the scatter plot must be drawn.
+                    By default, the current axes is targeted.
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>polyline</term>
+                <listitem>
+                    Handle of the created polyline.
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
                 <term>msizes</term>
                 <listitem>
                     <para>
-                        Specifying the sizes of the markers. To plot each marker with equal sizes,
-                        specify <varname>msizes</varname> as a scalar.
-                        To plot each marker with a different size, specify <varname>msizes</varname>
-                        as a vector with length equal to the length of <varname>x</varname> and
-                        <varname>x</varname>.
-                        The units for <varname>msizes</varname> is points squared with a default
-                        value of 36 points squared.
-                        The size equals the area of the circle surrounding the marker.
+                        Sizes of the markers, as of the area of the circle surrounding the marker,
+                        in point-square. Default value = 36. If it is scalar,
+                        the same size is used for all markers. Otherwise <varname>msizes</varname>
+                        and <varname>x</varname> must have the same number of elements.
                     </para>
                 </listitem>
             </varlistentry>
                 <term>mcolors</term>
                 <listitem>
                     <para>
-                        Specifying the colors of the markers.
-                        To plot each marker with the same color, specify <varname>mcolors</varname>
-                        as a string representing a known color, see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values between 0 and 1.
-                        To plot each marker with a different color, specify <varname>mcolors</varname>
-                        as a vector with length equal to the length of <varname>x</varname>.
+                        Colors of markers. If it is scalar, the same color is used for all markers.
+                        Otherwise, <varname>mcolors</varname> and <varname>x</varname> must have
+                        the same number of elements.
+                    </para>
+                    <para>
+                        The same color is used for filling the body and drawing the edge of markers.
+                    </para>
+                    <para>
                         The values of <varname>mcolors</varname> are linearly mapped to the colors
                         in the current colormap.
-                        Colors can also by specified by a matrix of RGB values or a vector of
-                        strings representing known colors.
-                        A matrix of RGB values has 3 columns and the number of rows equals the
-                        length of <varname>x</varname>.
+                    </para>
+                    <para>
+                        A color can be specified by one of the following:
+                        <itemizedlist>
+                            <listitem>
+                                Its name, among the predefined names colors
+                                (see the <link linkend="color_list">color_list</link>).
+                            </listitem>
+                            <listitem>
+                                Its standard hexadecimal RGB code as a string, like "#A532FB".
+                            </listitem>
+                            <listitem>
+                                A matrix of RGB values with 3 columns and n rows, with Red Green and
+                                Blue intensities in [0,1].
+                            </listitem>
+                            <listitem>
+                                Its index in the current color map
+                            </listitem>
+                        </itemizedlist>
                         The default color is "blue".
                     </para>
                 </listitem>
                 <term>"fill"</term>
                 <listitem>
                     <para>
-                        This string indicates that the markers are filled with some colors.
-                        By default, the filling colors are the same as the patterns ones.
-                        Both sets of colors can be defined independently by using the properties
+                        By default, only the edge of markers is drawn, unless this keyword or the
                         <varname>"markerFaceColor"</varname> or
-                        <varname>"markerBackgroundColor"</varname>.
+                        <varname>"markerBackgroundColor"</varname> properties are set.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>"smallOnTop"</term>
+                <listitem>
+                    <para>
+                        When markers have not all the same size and the population of points becomes
+                        crowdy, big markers can hide smaller ones located around the same place.
+                        This option can be used to avoid such masking effects. Then points are
+                        priorly sorted by decreasing sizes, in order to plot the smallest points
+                        at the end, on top of bigger ones.
                     </para>
                 </listitem>
             </varlistentry>
                 <term>marker</term>
                 <listitem>
                     <para>
-                        Select the type of the marker. The same marker shape is used for all
-                        specified points. The figure below shows the 15 different marker types.
+                        Selects the shape of the markers. The same shape is used for all
+                        specified points. The figure below shows the 15 different marker shapes.
                     </para>
                     <para>
                         <inlinemediaobject>
                         </inlinemediaobject>
                     </para>
                     <para>
-                        Marker types are specified by strings, see the table below.
+                        Each marker shape is specified either by its index (list above) or by
+                        its string symbol (table below).
                     </para>
                     <para>
                         <informaltable border="1">
-                            <tr>
-                                <td>
-                                    String
-                                </td>
-                                <td>
-                                    Marker type
-                                </td>
+                            <tr><td>Index</td>
+                                <td>String</td>
+                                <td>Marker type</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"."</literal>
-                                </td>
+                                <td>0</td>
+                                <td><literal>"."</literal></td>
                                 <td>Point</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"+"</literal>
-                                </td>
+                                <td>1</td>
+                                <td><literal>"+"</literal></td>
                                 <td>Plus sign</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"x"</literal>
-                                </td>
+                                <td>2</td>
+                                <td><literal>"x"</literal></td>
                                 <td>Cross</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"circle plus"</literal>
-                                </td>
+                                <td>3</td>
+                                <td><literal>"circle plus"</literal></td>
                                 <td>Circle with plus</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"filled diamond"</literal>
-                                </td>
+                                <td>4</td>
+                                <td><literal>"filled diamond"</literal></td>
                                 <td>Filled diamond</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"d"</literal> or
-                                    <literal>"diamond"</literal>
-                                </td>
+                                <td>5</td>
+                                <td><literal>"d"</literal> or <literal>"diamond"</literal></td>
                                 <td>Diamond</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"^"</literal>
-                                </td>
+                                <td>6</td>
+                                <td><literal>"^"</literal></td>
                                 <td>Upward-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"v"</literal>
-                                </td>
+                                <td>7</td>
+                                <td><literal>"v"</literal></td>
                                 <td>Downward-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"diamond plus"</literal>
-                                </td>
+                                <td>8</td>
+                                <td><literal>"diamond plus"</literal></td>
                                 <td>Diamond with plus</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"o"</literal>
-                                </td>
+                                <td>9</td>
+                                <td><literal>"o"</literal></td>
                                 <td>Circle (default)</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"*"</literal>
-                                </td>
+                                <td>10</td>
+                                <td><literal>"*"</literal></td>
                                 <td>Asterisk</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"s"</literal> or
-                                    <literal>"square"</literal>
-                                </td>
+                                <td>11</td>
+                                <td><literal>"s"</literal> or <literal>"square"</literal></td>
                                 <td>Square</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"&gt;"</literal>
-                                </td>
+                                <td>12</td>
+                                <td><literal>">"</literal></td>
                                 <td>Right-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"&lt;"</literal>
-                                </td>
+                                <td>13</td>
+                                <td><literal>"&lt;"</literal></td>
                                 <td>Left-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"pentagram"</literal> or
-                                    <literal>"p"</literal>
-                                </td>
+                                <td>14</td>
+                                <td><literal>"pentagram"</literal> or <literal>"p"</literal></td>
                                 <td>Five-pointed star</td>
                             </tr>
                         </informaltable>
                     </para>
                 </listitem>
             </varlistentry>
+        </variablelist>
+        <refsect3>
+            <title>Property Name, Value pairs</title>
+            <para>
+                A series of property &lt;Name,Value> pairs can be used to specify
+                the filling color of markers body, the color and thickness of the markers edges,
+                or the points on which a datatip must be created.
+            </para>
+        </refsect3>
+        <variablelist>
             <varlistentry>
-                <term>&lt;marker_property, value&gt;</term>
-                <listitem>
-                    <para>
-                        A sequence of property value pairs can be used to specify type, color and
-                        line width of the markers.
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>&lt;"marker", value&gt; or &lt;"markerStyle", value&gt;</term>
+                <term>"marker",value  or  "markerStyle",value</term>
                 <listitem>
                     <para>
-                        Specify the type of the marker, see the table above.
+                        Shape of the marker (index or string keyword). See the table above.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"markerEdgeColor", value&gt; or &lt;"markerForeground", value&gt;</term>
+                <term>"markerEdgeColor",value  or  "markerForeground",value</term>
                 <listitem>
                     <para>
-                        Specify the foreground color of the marker.
-                        A color can be specified by a string representing a known color,
-                        see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values.
-                        RGB values correspond to red, green and blue intensity between 0 and 1.
-                        This option is superseded by argument <varname>mcolors</varname>.
+                        Color of the edge of markers. Colors can be specified as for
+                        <varname>mcolors</varname>.
+                        This option supersedes <varname>mcolors</varname>.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"markerFaceColor",value&gt; or &lt;"markerBackground",value&gt;</term>
+                <term>"markerFaceColor",value  or  "markerBackground",value</term>
                 <listitem>
                     <para>
-                        Specify the background color of the marker.
-                        A color can be specified by a string representing a known color
-                        see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values.
-                        RGB values correspond to red, green and blue intensity between 0 and 1.
-                        This option is superseded by argument <varname>mcolors</varname>.
+                        Color filling the body of markers. Colors can be specified as for
+                        <varname>mcolors</varname>.
+                        This option supersedes <varname>mcolors</varname>.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"linewidth",value&gt; or &lt;"thickness",value&gt;</term>
+                <term>"linewidth",value  or  "thickness",value</term>
                 <listitem>
                     <para>
-                        Specify the thickness of the edge of the marker.
+                        Specify the thickness of the edge for all markers.
                         The unit for the value is one point.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;axes_handle&gt;</term>
+                <term>"datatips", k</term>
                 <listitem>
-                    <para>This optional argument forces the scatter plot to appear inside the
-                        selected axes given by <literal>axes_handle</literal> rather than inside the
-                        current axes, see <link linkend="gca">gca</link>.
+                    <para>
+                        Creates a datatip for all (X,Y) points whose indices are in the vector
+                        <varname>k</varname>.
                     </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>polyline</term>
-                <listitem>
                     <para>
-                        Handle of the created polyline.
+                        The <literal>datatip_display_mode</literal> is set to
+                        <literal>"mouseover"</literal>. The datatip anchor is reduced to a point
+                        set at the middle of the marker. The default datatips display the
+                        (x,y) coordinates of the point. If <varname>msizes</varname> is a vector,
+                        the size of each marker is also displayed.
                     </para>
                 </listitem>
             </varlistentry>
             For more details see the description of the arguments and the examples.
         </para>
         <note>
-          To skip an argument, just replace it with <literal>[]</literal> like in
-          <literal>scatter3d(x,y,z,[],mcolors)</literal>.
+          To skip an argument, just .. skip it, or replace it with <literal>[]</literal>, like in
+          <literal>scatter3d(x,y, , mcolors)</literal> or <literal>scatter3d(x,y,[], mcolors)</literal>.
         </note>
     </refsection>
     <refsection>
         <title>Examples</title>
         <para>
-            Create 2D scatter plot
+            With the default circle shape, and the same color for all points:
         </para>
         <programlisting role="example"><![CDATA[
-// x and y initialisation
-x = linspace(0,2,200);
-y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-// create 2D scatter plot
-scatter(x,y);
+n = 130;
+x = rand(1,n);
+y = rand(1,n);
+
+clf
+subplot(2,3,1)
+scatter(x, y)
+title("scatter(x, y)", "fontsize",3)
+
+subplot(2,3,2)
+scatter(x, y, 100)
+title("scatter(x, y, 100)", "fontsize",3)
+
+subplot(2,3,3)
+mAreas = 10.^grand(1,n,"unf",1,2.4);
+scatter(x, y, mAreas)
+title("scatter(x, y, mAreas)", "fontsize",3)
+
+subplot(2,3,4)
+scatter(x, y, , "orange")
+tit = "scatter(x, y, ,""orange"")";
+title(tit, "fontsize",3)
+
+subplot(2,3,5)
+scatter(x, y, "fill")
+tit = "scatter(x, y, ""fill"")";
+title(tit, "fontsize",3)
+
+subplot(2,3,6)
+scatter(x, y, mAreas, "markerBackground", "yellow")
+tit = "scatter(x, y, mAreas,""markerBackground"", ""yellow"")";
+title(tit, "fontsize",1)
  ]]></programlisting>
         <scilab:image>
-            x = linspace(0,2,200)
-            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x))
-            scatter(x,y)
+            n = 130;
+            x = rand(1,n);
+            y = rand(1,n);
+
+            clf
+            subplot(2,3,1)
+            scatter(x, y)
+            title("scatter(x, y)", "fontsize",3)
+
+            subplot(2,3,2)
+            scatter(x, y, 100)
+            title("scatter(x, y, 100)", "fontsize",3)
+
+            subplot(2,3,3)
+            mAreas = 10.^grand(1,n,"unf",1,2.4);
+            scatter(x, y, mAreas)
+            title("scatter(x, y, mAreas)", "fontsize",3)
+
+            subplot(2,3,4)
+            scatter(x, y, , "orange")
+            tit = "scatter(x, y, ,""orange"")";
+            title(tit, "fontsize",3)
+
+            subplot(2,3,5)
+            scatter(x, y, "fill")
+            tit = "scatter(x, y, ""fill"")";
+            title(tit, "fontsize",3)
+
+            subplot(2,3,6)
+            scatter(x, y, mAreas, "markerBackground", "yellow")
+            tit = "scatter(x, y, mAreas,""markerBackground"", ""yellow"")";
+            title(tit, "fontsize",1)
+
+            gcf().axes_size = [750 500];
         </scilab:image>
         <para>
-            Vary marker size
+            <emphasis role="bold">Option "smallOnTop"</emphasis>, avoiding intermasking effects:
         </para>
         <programlisting role="example"><![CDATA[
-// x and y initialisation
-x = linspace(0,2,200);
-y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-// specify different sizes
-s = linspace(1,30,length(x));
-// create 2D scatter plot
-scatter(x, y, s);
+n = 170;
+x = rand(1,n);
+y = rand(1,n);
+mAreas = 10.^grand(1,n,"unf",1,2.8);
+
+clf
+subplot(1,2,1)
+scatter(x, y, mAreas, "wheat", "fill", "markerEdgeColor", "red")
+title("Raw display", "fontsize",3)
+
+subplot(1,2,2)
+scatter(x, y, mAreas, "wheat", "fill", "smallOnTop", "markerEdgeColor", "red")
+title("""SmallOnTop"" option", "fontsize",3)
  ]]></programlisting>
         <scilab:image>
-            x = linspace(0,2,200)
-            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x))
-            s = linspace(1,30,length(x))
-            scatter(x,y,s)
+            n = 170;
+            x = rand(1,n);
+            y = rand(1,n);
+            mAreas = 10.^grand(1,n,"unf",1,2.8);
+
+            clf
+            subplot(1,2,1)
+            scatter(x, y, mAreas, "wheat", "fill", "markerEdgeColor", "red")
+            title("Raw display", "fontsize",3)
+
+            subplot(1,2,2)
+            scatter(x, y, mAreas, "wheat", "fill", "SmallOnTop", "markerEdgeColor", "red")
+            title("""SmallOnTop"" option", "fontsize",3)
+
+            gcf().axes_size = [600 270];
         </scilab:image>
+
         <para>
             Vary marker size and color
         </para>
         <programlisting role="example"><![CDATA[
-// x and y initialisation
-x = linspace(0, 2, 200);
-y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-// specify different sizes
-s = linspace(1, 30, length(x));
-// set color map
-gcf().color_map = coolcolormap(64);
-// colors according to x values
-c = x;
-// create 2D scatter plot
-scatter(x,y,s,c);
- ]]></programlisting>
-        <scilab:image>
-            x = linspace(0,2,200)
-            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x))
-            s = linspace(1,30,length(x))
-            gcf().color_map = coolcolormap(64)
-            c = x
-            scatter(x,y,s,c)
-        </scilab:image>
-        <para>
-            Fill the markers
-        </para>
-        <programlisting role="example"><![CDATA[
-// x and y initialisation
 x = linspace(0, 2, 200);
 y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-// specify different sizes
-s = linspace(1, 30, length(x));
-// set color map
-gcf().color_map = coolcolormap(64);
-// colors according to y values
-c = y;
-// create 2D scatter plot
+
+s = linspace(1, 30, length(x));     // specify different sizes
+gcf().color_map = coolcolormap(64); // set color map
+c = x;                  // colors according to x values
+subplot(1,2,1)
+scatter(x, y, s, c);    // create 2D scatter plot
+
+// Fill the markers
+subplot(1,2,2)
 scatter(x, y, s, c, "fill");
  ]]></programlisting>
         <scilab:image>
-            x = linspace(0,2,200)
-            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x))
-            s = linspace(1,30,length(x))
-            gcf().color_map = coolcolormap(64);
-            c = y
-            scatter(x,y,s,c,"fill")
+            x = linspace(0, 2, 200);
+            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
+
+            s = linspace(1, 30, length(x));     // specify different sizes
+            gcf().color_map = coolcolormap(64); // set color map
+            c = x;                  // colors according to x values
+            subplot(1,2,1)
+            scatter(x, y, s, c);    // create 2D scatter plot
+
+            // Fill the markers
+            subplot(1,2,2)
+            scatter(x, y, s, c, "fill");
+            gcf().axes_size = [700 350];
         </scilab:image>
         <para>
-            Specify marker symbol
+            Specify the marker
         </para>
         <programlisting role="example"><![CDATA[
-// x and y initialisation
 x = rand(1, 200);
 y = rand(1, 200);
-// create 2D scatter plot
+
+subplot(2,2,1)
 scatter(x, y, "d");
- ]]></programlisting>
-        <scilab:image>
-            x = rand(1,200)
-            y = rand(1,200)
-            scatter(x,y,"d")
-        </scilab:image>
-        <para>
-            Change marker color and line width
-        </para>
-        <programlisting role="example"><![CDATA[
-// x and y initialisation
-x = rand(1, 200);
-y = rand(1, 200);
-// create 2D scatter plot
+
+subplot(2,2,2)
 scatter(x, y, "markerEdgeColor",[0 .4 .4],...
-              "markerFaceColor",[0 .8 .8],...
+              "markerFaceColor","magenta",...
               "linewidth",1.5);
+
+subplot(2,2,3)
+scatter(x, y, 60, "red", "+");  // Marker's symbol
+
+subplot(2,2,4)
+scatter(x, y, 60, "green", 14); // Marker's index
  ]]></programlisting>
         <scilab:image>
-            x = rand(1,200)
-            y = rand(1,200)
-            scatter(x,y,"markerEdgeColor",[0 .4 .4],...
-            "markerFaceColor",[0 .8 .8],...
-            "linewidth",1.5)
+            x = rand(1, 200);
+            y = rand(1, 200);
+
+            subplot(2,2,1)
+            scatter(x, y, "d");
+
+            subplot(2,2,2)
+            scatter(x, y, "markerEdgeColor",[0 .4 .4],...
+                          "markerFaceColor","magenta",...
+                          "linewidth",1.5);
+
+            subplot(2,2,3)
+            scatter(x, y, 60, "red", "+");  // Marker's symbol
+
+            subplot(2,2,4)
+            scatter(x, y, 60, "green", 14); // Marker's index
+
+            gcf().axes_size = [600 500];
         </scilab:image>
         <para>
-            Specify subplot for scatter plot
+            Post-processing a scatter plot:
         </para>
         <programlisting role="example"><![CDATA[
-// x and y initialisation
-x = linspace(0, 2, 100);
-y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-// create 2D scatter subplot
-subplot(2, 1, 1)
-scatter(gca(), x, y);
-// create 2D scatter subplot
-subplot(2, 1, 2)
-scatter(gca(), x, y, "fill", "s");
- ]]></programlisting>
-        <scilab:image>
-            x = linspace(0,2,100)
-            y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x))
-            subplot(2,1,1)
-            scatter(gca(),x,y)
-            subplot(2,1,2)
-            scatter(gca(),x,y,"fill","s")
-        </scilab:image>
-        <para>
-            Modify scatter plot after creation
-        </para>
-        <programlisting role="example"><![CDATA[
-// x and y initialisation
-t = linspace(0,1,200);
-x = t .* cos(10*%pi*t);
-y = t .* sin(10*%pi*t);
-// create 2D scatter plot
-p = scatter(x, y);
- ]]></programlisting>
-        <scilab:image>
-            t = linspace(0,25,200)
-            x = t.*cos(t)
-            y = t.*sin(t)
-            p = scatter(x,y,t)
-        </scilab:image>
-        <programlisting role="example"><![CDATA[
-// modify polyline
-p.thickness = 0.5;
-p.mark_foreground = color("darkblue");
-p.mark_background = color("darkcyan");
- ]]></programlisting>
-        <scilab:image>
-            t = linspace(0,25,200)
-            x = t.*cos(t)
-            y = t.*sin(t)
-            p = scatter(x,y,t)
-            p.thickness = 0.5
-            p.mark_foreground = color("darkblue")
-            p.mark_background = color("darkcyan")
-        </scilab:image>
+n = 150;
+x = rand(1,n);
+y = rand(1,n);
+mAreas = 10.^grand(1,n,"unf",1,2.8);
+
+clf
+p = scatter(x, y, mAreas, "yel", "fill", "markerEdgeColor", "red")
+
+// Post-processing
+k = mAreas<median(mAreas)*2;
+bg = ones(1,n) * p.mark_background;
+bg(k) = color("orange");
+p.mark_background = bg;
+     ]]></programlisting>
+        <scilab:image><![CDATA[
+            n = 150;
+            x = rand(1,n);
+            y = rand(1,n);
+            mAreas = 10.^grand(1,n,"unf",1,2.8);
+
+            clf
+            p = scatter(x, y, mAreas, "yel", "fill", "markerEdgeColor", "red")
+
+            // Post-processing
+            k = mAreas<median(mAreas)*2;
+            bg = ones(1,n) * p.mark_background;
+            bg(k) = color("orange");
+            p.mark_background = bg;
+
+            gcf().axes_size = [450 300];
+        ]]></scilab:image>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
@@ -503,7 +570,22 @@ p.mark_background = color("darkcyan");
             <revision>
                 <revnumber>6.0.0</revnumber>
                 <revremark>
-                    Function <function>scatter</function> introduced.
+                    Function scatter() introduced.
+                </revremark>
+            </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revremark>
+                    <itemizedlist>
+                        <listitem>
+                            Colors can be specified as well with their "#RRGGBB" hexadecimal
+                            standard code, or their index in the color map.
+                        </listitem>
+                        <listitem>
+                            Options <emphasis>SmallOnTop</emphasis> and
+                            <emphasis>"datatips"</emphasis> added.
+                        </listitem>
+                    </itemizedlist>
                 </revremark>
             </revision>
         </revhistory>
index 44bc01c..77d1ecd 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) Scilab Enterprises - 2015 - 2012 - Juergen Koch
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2020 - Samuel GOUGEON
  *
  * This file is hereby licensed under the terms of the GNU GPL v2.0,
  * pursuant to article 5.3.4 of the CeCILL v.2.1.
     </refnamediv>
     <refnamediv xml:id="scatter3">
         <refname>scatter3</refname>
-        <refpurpose>3D scatter plot (obsolete)</refpurpose>
+        <refpurpose>3D scatter plot <emphasis role="bold">(obsolete)</emphasis></refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
         <synopsis>
-            polyline = scatter3d(x, y, z, msizes, mcolors, "fill", marker, &lt;marker_property,value&gt;)
-            polyline = scatter3d(axes_handle,...)
+            scatter3d()      // Example
+            scatter3d(x, y, z)
+            scatter3d(x, y, z, msizes)
+            scatter3d(x, y, z, msizes, mcolors)
+            scatter3d(.., "fill")
+            scatter3d(.., "fill", marker)
+            scatter3d(..., &lt;marker_property, value>)
+            scatter3d(axes, ..)
+            polyline = scatter3d(..)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
                 </listitem>
             </varlistentry>
             <varlistentry>
+                <term>axes</term>
+                <listitem>
+                    Handle of the graphical axes in which the scatter plot must be drawn.
+                    By default, the current axes is targeted.
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>polyline</term>
+                <listitem>
+                    Handle of the created polyline.
+                    <para/>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
                 <term>msizes</term>
                 <listitem>
                     <para>
-                        Specifying the sizes of the markers.
-                        To plot each marker with equal size, specify <varname>msizes</varname> as a scalar.
-                        To plot each marker with a different size, specify <varname>msizes</varname>
-                        as a vector with n components.
-                        The units for <varname>msizes</varname> is points squared, with a default
-                        value of 36 points squared.
-                        The size equals the area of the circle surrounding the marker.
+                        Sizes of the markers, as of the area of the circle surrounding the marker,
+                        in point-square. Default value = 36. If it is scalar,
+                        the same size is used for all markers. Otherwise <varname>msizes</varname>
+                        and <varname>x</varname> must have the same number of elements.
                     </para>
                 </listitem>
             </varlistentry>
                 <term>mcolors</term>
                 <listitem>
                     <para>
-                        Specifying the colors of the markers.
-                        To plot each marker with the same color, specify <varname>mcolors</varname>
-                        as a string representing a known color: see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values.
-                        RGB values correspond to red, green and blue intensity between 0 and 1.
-                        To plot each marker with a different color, specify <varname>mcolors</varname>
-                        as a vector with n components.
+                        Colors of markers. If it is scalar, the same color is used for all markers.
+                        Otherwise, <varname>mcolors</varname> and <varname>x</varname> must have
+                        the same number of elements.
+                    </para>
+                    <para>
+                        The same color is used for filling the body and drawing the edge of markers.
+                    </para>
+                    <para>
                         The values of <varname>mcolors</varname> are linearly mapped to the colors
                         in the current colormap.
-                        Colors can also by specified by a matrix of RGB values or a vector of
-                        strings representing known colors.
-                        A matrix of RGB values has 3 columns and n rows.
+                    </para>
+                    <para>
+                        A color can be specified by one of the following:
+                        <itemizedlist>
+                            <listitem>
+                                Its name, among the predefined names colors
+                                (see the <link linkend="color_list">color_list</link>).
+                            </listitem>
+                            <listitem>
+                                Its standard hexadecimal RGB code as a string, like "#A532FB".
+                            </listitem>
+                            <listitem>
+                                A matrix of RGB values with 3 columns and n rows, with Red Green and
+                                Blue intensities in [0,1].
+                            </listitem>
+                            <listitem>
+                                Its index in the current color map
+                            </listitem>
+                        </itemizedlist>
                         The default color is "blue".
                     </para>
                 </listitem>
                 <term>"fill"</term>
                 <listitem>
                     <para>
-                        This string indicates that the markers are filled with some colors.
-                        By default the filling colors of markers are the same as their shape ones.
-                        However, both colors can be set independently by using the properties
-                        <literal>"markerFaceColor"</literal> or <literal>"markerBackgroundColor"</literal>.
+                        By default, only the edge of markers is drawn, unless this keyword or the
+                        <varname>"markerFaceColor"</varname> or
+                        <varname>"markerBackgroundColor"</varname> properties are set.
                     </para>
                 </listitem>
             </varlistentry>
                 <term>marker</term>
                 <listitem>
                     <para>
-                        Select the type of the marker. The same marker shape is used for all
-                        specified points.
-                        The figure below shows the 15 different marker types.
+                        Selects the shape of the markers. The same shape is used for all
+                        specified points. The figure below shows the 15 different marker shapes.
                     </para>
                     <para>
                         <inlinemediaobject>
                         </inlinemediaobject>
                     </para>
                     <para>
-                        Marker types are specified by strings: see the table below.
+                        Each marker shape is specified either by its index (list above) or by
+                        its string symbol (table below).
                     </para>
                     <para>
                         <informaltable border="1">
-                            <tr>
-                                <td>
-                                    String
-                                </td>
-                                <td>
-                                    Marker type
-                                </td>
+                            <tr><td>Index</td>
+                                <td>String</td>
+                                <td>Marker type</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"."</literal>
-                                </td>
+                                <td>0</td>
+                                <td><literal>"."</literal></td>
                                 <td>Point</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"+"</literal>
-                                </td>
+                                <td>1</td>
+                                <td><literal>"+"</literal></td>
                                 <td>Plus sign</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"x"</literal>
-                                </td>
+                                <td>2</td>
+                                <td><literal>"x"</literal></td>
                                 <td>Cross</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"circle plus"</literal>
-                                </td>
+                                <td>3</td>
+                                <td><literal>"circle plus"</literal></td>
                                 <td>Circle with plus</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"filled diamond"</literal>
-                                </td>
+                                <td>4</td>
+                                <td><literal>"filled diamond"</literal></td>
                                 <td>Filled diamond</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"d"</literal> or
-                                    <literal>"diamond"</literal>
-                                </td>
+                                <td>5</td>
+                                <td><literal>"d"</literal> or <literal>"diamond"</literal></td>
                                 <td>Diamond</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"^"</literal>
-                                </td>
+                                <td>6</td>
+                                <td><literal>"^"</literal></td>
                                 <td>Upward-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"v"</literal>
-                                </td>
+                                <td>7</td>
+                                <td><literal>"v"</literal></td>
                                 <td>Downward-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"diamond plus"</literal>
-                                </td>
+                                <td>8</td>
+                                <td><literal>"diamond plus"</literal></td>
                                 <td>Diamond with plus</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"o"</literal>
-                                </td>
+                                <td>9</td>
+                                <td><literal>"o"</literal></td>
                                 <td>Circle (default)</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"*"</literal>
-                                </td>
+                                <td>10</td>
+                                <td><literal>"*"</literal></td>
                                 <td>Asterisk</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"s"</literal> or
-                                    <literal>"square"</literal>
-                                </td>
+                                <td>11</td>
+                                <td><literal>"s"</literal> or <literal>"square"</literal></td>
                                 <td>Square</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"&gt;"</literal>
-                                </td>
+                                <td>12</td>
+                                <td><literal>">"</literal></td>
                                 <td>Right-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"&lt;"</literal>
-                                </td>
+                                <td>13</td>
+                                <td><literal>"&lt;"</literal></td>
                                 <td>Left-pointing triangle</td>
                             </tr>
                             <tr>
-                                <td>
-                                    <literal>"pentagram"</literal> or
-                                    <literal>"p"</literal>
-                                </td>
+                                <td>14</td>
+                                <td><literal>"pentagram"</literal> or <literal>"p"</literal></td>
                                 <td>Five-pointed star</td>
                             </tr>
                         </informaltable>
                     </para>
                 </listitem>
             </varlistentry>
+        </variablelist>
+        <refsect3>
+            <title>Property &lt;Name, Value> pairs</title>
+            <para>
+                A series of property value pairs can be used to specify type, color and
+                line width of the markers.
+            </para>
+        </refsect3>
+        <variablelist>
             <varlistentry>
-                <term>&lt;marker_property, value&gt;</term>
-                <listitem>
-                    <para>
-                        A sequence of property value pairs can be used to specify type, color and
-                        line width of the markers.
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>&lt;"marker", value&gt; or &lt;"markerStyle", value&gt;</term>
+                <term>"marker", value  or  "markerStyle", value</term>
                 <listitem>
                     <para>
-                        Specify the type of the marker, see the table above.
+                        Shape of the marker (index or string keyword). See the table above.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"markerEdgeColor", value&gt; or &lt;"markerForeground", value&gt;</term>
+                <term>"markerEdgeColor", value  or  "markerForeground", value</term>
                 <listitem>
                     <para>
-                        Specify the foreground color of the marker.
-                        A color can be specified by a string representing a known color:
-                        see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values.
-                        RGB values correspond to red, green and blue intensity between 0 and 1.
-                        This option is superseded by the <varname>mcolors</varname> argument.
+                        Color of the edge of markers. Colors can be specified as for
+                        <varname>mcolors</varname>.
+                        This option supersedes <varname>mcolors</varname>.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"markerFaceColor", value&gt; or &lt;"markerBackground", value&gt;</term>
+                <term>"markerFaceColor",value  or  "markerBackground",value</term>
                 <listitem>
                     <para>
-                        Specify the background color of the marker.
-                        A color can be specified by a string representing a known color:
-                        see <link linkend="color_list">color_list</link>.
-                        A color can also be specified by a vector of 3 RGB values.
-                        RGB values correspond to red, green and blue intensity between 0 and 1.
-                        This option is superseded by argument <varname>mcolors</varname>.
+                        Color filling the body of markers. Colors can be specified as for
+                        <varname>mcolors</varname>.
+                        This option supersedes <varname>mcolors</varname>.
                     </para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>&lt;"linewidth", value&gt; or &lt;"thickness", value&gt;</term>
+                <term>"linewidth",value  or  "thickness",value</term>
                 <listitem>
                     <para>
-                        Specify the thickness of the edge of the marker.
+                        Specify the thickness of the edge for all markers.
                         The unit for the value is one point.
                     </para>
                 </listitem>
             </varlistentry>
-            <varlistentry>
-                <term>axes_handle</term>
-                <listitem>
-                    <para>This optional argument forces the scatter plot to appear inside the
-                        selected axes given by <literal>axes_handle</literal> rather than inside the
-                        current axes, see <link linkend="gca">gca</link>.
-                    </para>
-                </listitem>
-            </varlistentry>
-            <varlistentry>
-                <term>polyline</term>
-                <listitem>
-                    <para>
-                        Handle of the created polyline.
-                    </para>
-                </listitem>
-            </varlistentry>
         </variablelist>
     </refsection>
     <refsection>
         <title>Description</title>
-        <warning>
-            <literal>scatter3()</literal> is obsolete and will be removed in Scilab 6.1.x.
-            Please use <literal>scatter3d()</literal> instead.
-        </warning>
         <para>
             <literal>scatter3d(x,y,z)</literal> creates a scatter plot with markers at the locations
             specified by <varname>x</varname>, <varname>y</varname>, and <varname>z</varname>.
         <note>
             <itemizedlist>
               <listitem>
-                To skip an argument, just replace it with <literal>[]</literal> as in
-                <literal>scatter3d(x,y,z,[],mcolors)</literal>.
+                  To skip an argument, just .. skip it, or replace it with <literal>[]</literal>,
+                  like in <literal>scatter3d(x,y,z, , mcolors)</literal> or in
+                  <literal>scatter3d(x,y,z,[], mcolors)</literal>.
               </listitem>
               <listitem>
                  When the axes is rotated, the markers are automatically rotated as well in order
             Create 3D scatter plot
         </para>
         <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-t = 1:200;
-x = t .* cos(t) .* sin(t);
-y = t .* sin(t) .* sin(t);
-z = t .* cos(t);
-// create 3D scatter plot
-scatter3d(x, y, z);
-// modify rotation angles
-gca().rotation_angles = [60, 45];
+// Data: points on an hemisphere
+azimuth = 0:12:359;
+latitude = 3:12:89;
+[az, lat] = ndgrid(azimuth, latitude);
+r = cosd(lat);
+x = 1.1*cosd(az+lat/3) .* r;
+y = 1.1*sind(az+lat/3) .* r;
+z = sind(lat);
+
+clf
+gcf().color_map = parulacolormap(50);
+
+subplot(1,2,1)    // Plot on the left
+// Markers size according to r
+scatter3d(x, y, z, r.^2*80);
+
+subplot(1,2,2)    // Plot on the right
+options = list("fill", "markerEdgeColor","red","thickness",0.5);
+mcolors = az;     // + colors according to the azimuth
+scatter3d(x, y, z, r.^2*80, mcolors, options(:));
+
+// Tuning axes rendering
+gcf().children.grid = [1 1 1]*color("grey50");
+gcf().children.rotation_angles = [83 -20];
  ]]></programlisting>
         <scilab:image>
-            t = 1:200
-            x = t.*cos(t).*sin(t)
-            y = t.*sin(t).*sin(t)
-            z = t.*cos(t)
-            scatter3d(x,y,z)
-            gca().rotation_angles = [60, 45];
+            // Data: points on an hemisphere
+            azimuth = 0:12:359;
+            latitude = 3:12:89;
+            [az, lat] = ndgrid(azimuth, latitude);
+            r = cosd(lat);
+            x = 1.1*cosd(az+lat/3) .* r;
+            y = 1.1*sind(az+lat/3) .* r;
+            z = sind(lat);
+
+            clf
+            gcf().color_map = parulacolormap(50);
+
+            subplot(1,2,1)    // Plot on the left
+            // Markers size according to r
+            scatter3d(x, y, z, r.^2*80);
+
+            subplot(1,2,2)    // Plot on the right
+            options = list("fill", "markerEdgeColor","red","thickness",0.5);
+            mcolors = az;     // + colors according to the azimuth
+            scatter3d(x, y, z, r.^2*80, mcolors, options(:));
+
+            // Tuning axes rendering
+            gcf().children.grid = [1 1 1]*color("grey50");
+            gcf().children.rotation_angles = [83 -20];
+            gcf().axes_size = [750 400];
         </scilab:image>
         <para>
-            Vary marker size
+            Styling the markers:
         </para>
         <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-t = 1:200;
-x = t .* cos(t) .* sin(t);
-y = t .* sin(t) .* sin(t);
-z = t .* cos(t);
-// size according to radius
-s = linspace(50, 1, length(t));
-// create 3D scatter plot
-scatter3d(x, y, z, s);
-// modify rotation angles
-gca().rotation_angles = [60, 45];
- ]]></programlisting>
-        <scilab:image>
-            t = 1:200
-            x = t .* cos(t) .* sin(t)
-            y = t .* sin(t) .* sin(t)
-            z = t .* cos(t)
-            s = linspace(50, 1, length(t))
-            scatter3d(x, y, z, s)
-            gca().rotation_angles = [60, 45];
-        </scilab:image>
-        <para>
-            Vary marker size and color
-        </para>
-        <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-t = 1:200;
-x = t .* cos(t) .* sin(t);
-y = t .* sin(t) .* sin(t);
-z = t .* cos(t);
-// size according to radius
-s = linspace(50, 1, length(t));
-// set color map
-gcf().color_map = coolcolormap(64);
-// color according to radius
-c = t;
-// create 3D scatter plot
-scatter3d(x, y, z, s, c);
-// modify rotation angles
-gca().rotation_angles = [60, 45];
- ]]></programlisting>
-        <scilab:image>
-            t = 1:200
-            x = t.*cos(t).*sin(t)
-            y = t.*sin(t).*sin(t)
-            z = t.*cos(t)
-            s = linspace(50,1,length(t))
-            gcf().color_map = coolcolormap(64);
-            c = t
-            scatter3d(x,y,z,s,c)
-            gca().rotation_angles = [60, 45];
-        </scilab:image>
-        <para>
-            Fill the markers
-        </para>
-        <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-z = linspace(0, 25, 200);
-x = z .* cos(z);
-y = z .* sin(z);
-// create 3D scatter plot
-scatter3d(x, y, z, "fill");
-// modify rotation angles
-gca().rotation_angles = [60, 45];
- ]]></programlisting>
-        <scilab:image>
-            z = linspace(0,25,200)
-            x = z.*cos(z)
-            y = z.*sin(z)
-            scatter3d(x,y,z,"fill")
-            gca().rotation_angles = [60, 45];
-        </scilab:image>
-        <para>
-            Specify marker symbol
-        </para>
-        <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-z = linspace(0, 25, 200);
+// Data
+z = linspace(0, 25, 150);
 x = z .* cos(z);
 y = z .* sin(z);
-// create 3D scatter plot
+
+subplot(2,2,1)
+scatter3d(x, y, z)
+
+// Fill the markers
+subplot(2,2,2)
+scatter3d(x, y, z, , "turquoise", "fill")
+
+// Choose another marker shape
+subplot(2,2,3)
 scatter3d(x, y, z, "*");
-// modify rotation angles
-gca().rotation_angles = [60, 45];
- ]]></programlisting>
-        <scilab:image>
-            z = linspace(0,25,200)
-            x = z.*cos(z)
-            y = z.*sin(z)
-            scatter3d(x,y,z,"*")
-            gca().rotation_angles = [60,45];
-        </scilab:image>
-        <para>
-            Change marker edge and face color
-        </para>
-        <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-z = linspace(0, 25, 200);
-x = z .* cos(z);
-y = z .* sin(z);
-// create 3D scatter plot
+
+// Customize the markers colors
+subplot(2,2,4)
 scatter3d(x, y, z,...
-        "markerEdgeColor", "black",...
-        "markerFaceColor", [0 .8 .8]);
-// modify rotation angles
-gca().rotation_angles = [60, 45];
+        "markerEdgeColor", [1 0 0],...
+        "markerFaceColor", "yellow");
+
+// Tune the 3D orientation of all axes
+gcf().children.rotation_angles = [65 35];
  ]]></programlisting>
         <scilab:image>
-            z = linspace(0,25,200)
-            x = z.*cos(z)
-            y = z.*sin(z)
-            scatter3d(x,y,z,...
-            "markerEdgeColor","black",...
-            "markerFaceColor",[0 .8 .8])
-            gca().rotation_angles = [60, 45];
+            // Data
+            z = linspace(0, 25, 150);
+            x = z .* cos(z);
+            y = z .* sin(z);
+
+            subplot(2,2,1)
+            scatter3d(x, y, z)
+
+            // Fill the markers
+            subplot(2,2,2)
+            scatter3d(x, y, z, , "turquoise", "fill")
+
+            // Choose another marker shape
+            subplot(2,2,3)
+            scatter3d(x, y, z, "*");
+
+            // Customize the markers colors
+            subplot(2,2,4)
+            scatter3d(x, y, z,...
+                    "markerEdgeColor", [1 0 0],...
+                    "markerFaceColor", "yellow");
+
+            // Tune the 3D orientation of all axes
+            gcf().children.rotation_angles = [65 35];
+
+            gcf().axes_size = [750 450];
         </scilab:image>
         <para>
             Specify subplot for scatter plot
         </para>
         <programlisting role="example"><![CDATA[
-// x, y and z initialisation
+// Data
 n = 20;
 [x, y] = meshgrid(linspace(-2, 2, n));
 z = exp(-x.^2 - y.^2);
-// create 3D scatter subplot
-subplot(2,1,1)
-scatter3d(gca(), x(:), y(:), z(:));
-// modify rotation angles
-gca().rotation_angles = [60,45];
-// create 3D scatter subplot
+
 subplot(2,1,2)
-scatter3d(gca(), x(:), y(:), z(:), "markerFaceColor", [0 .8 .8]);
-// modify rotation angles
-gca().rotation_angles = [60,45];
+axes2 = gca();
+subplot(2,1,1)
+
+scatter3d(x, y, z);
+scatter3d(axes2, x(:), y(:), z(:), "markerFaceColor", [0 .8 .8]);
+
+// Tune axes view
+Axes = gcf().children;
+Axes.rotation_angles = [60,45];
+Axes.grid = [1 1 1]*color("grey50");
  ]]></programlisting>
         <scilab:image>
-            n = 20
-            [x,y] = meshgrid(linspace(-2,2,n))
-            z = exp(-x.^2 - y.^2)
-            subplot(2,1,1)
-            scatter3d(gca(), x(:), y(:), z(:))
-            gca().rotation_angles = [60, 45];
+            // Data
+            n = 20;
+            [x, y] = meshgrid(linspace(-2, 2, n));
+            z = exp(-x.^2 - y.^2);
+
             subplot(2,1,2)
-            scatter3d(gca(),x(:),y(:),z(:),"markerFaceColor",[0 .8 .8])
-            gca().rotation_angles = [60, 45];
+            axes2 = gca();
+            subplot(2,1,1)
+
+            scatter3d(x, y, z);
+            scatter3d(axes2, x(:), y(:), z(:), "markerFaceColor", [0 .8 .8]);
+
+            // Tune axes view
+            Axes = gcf().children;
+            Axes.rotation_angles = [60,45];
+            Axes.grid = [1 1 1]*color("grey50");
+
+            gcf().axes_size = [500 350];
         </scilab:image>
         <para>
-            Modify scatter plot after creation
+            <emphasis role="bold">Use the handle to post-process the scatter plot</emphasis>:
         </para>
         <programlisting role="example"><![CDATA[
-// x, y and z initialisation
-t = 1:200;
-x = t .* cos(t) .* sin(t);
-y = t .* sin(t) .* sin(t);
-z = t .* cos(t);
-// size according to radius
-s = linspace(50, 1, length(t));
-// create 3D scatter plot
-scatter3d(x, y, z, s);
-// modify rotation angles
-gca().rotation_angles = [60,45];
+// Data: points on an hemisphere
+azimuth = 0:12:359;
+latitude = 3:12:89;
+[az, lat] = ndgrid(azimuth, latitude);
+r = cosd(lat);
+x = 1.1*cosd(az+lat/3) .* r;
+y = 1.1*sind(az+lat/3) .* r;
+z = sind(lat);
+
+clf
+
+subplot(1,2,1)
+scatter3d(x, y, z, r.^2*80);
+title("Initial plot", "fontsize",3)
+
+subplot(1,2,2)
+p = scatter3d(x, y, z, r.^2*80); // The same
+title("Final plot", "fontsize",3)
+
+// Let's post-process it through the handle:
+
+// 1) Let's set all markers at y < 0 in yellow, and others in orange
+np = size(p.data,1);  // number of points
+tmp = ones(1,np) * color("orange");
+tmp(p.data(:,2)<0) = color("yellow");
+p.mark_background = tmp;
+
+// 2) and markers at x > 0  1.4 smaller than other
+tmp = p.data(:,1) > 0;
+p.mark_size(tmp) = p.mark_size(tmp)/1.4;
+
+// 3) Changing the edge color and thickness for all markers
+p.mark_foreground = color("red");
+p.thickness = 0.5;
+
+// Tuning axes
+Axes = gcf().children;
+Axes.rotation_angles = [82, -40];
+Axes.grid = [1 1 1]*color("grey60");
  ]]></programlisting>
-        <scilab:image>
-            t = 1:200
-            x = t.*cos(t).*sin(t)
-            y = t.*sin(t).*sin(t)
-            z = t.*cos(t)
-            s = linspace(50,1,length(t))
-            p = scatter3d(x,y,z,s)
-            gca().rotation_angles = [60,45];
-        </scilab:image>
-        <programlisting role="example"><![CDATA[
-// modify polyline
-p.mark_foreground = color(0.5, 0, 0);
-p.mark_background = color(0.5, 0.5, 0);
- ]]></programlisting>
-        <scilab:image>
-            t = 1:200
-            x = t.*cos(t).*sin(t)
-            y = t.*sin(t).*sin(t)
-            z = t.*cos(t)
-            s = linspace(50,1,length(t))
-            p = scatter3d(x,y,z,s)
-            set(gca(),"rotation_angles",[60,45])
-            // modify polyline
-            p.mark_foreground = color(0.5, 0, 0)
-            p.mark_background = color(0.5, 0.5, 0)
-        </scilab:image>
+        <scilab:image><![CDATA[
+            // Data: points on an hemisphere
+            azimuth = 0:12:359;
+            latitude = 3:12:89;
+            [az, lat] = ndgrid(azimuth, latitude);
+            r = cosd(lat);
+            x = 1.1*cosd(az+lat/3) .* r;
+            y = 1.1*sind(az+lat/3) .* r;
+            z = sind(lat);
+
+            clf
+
+            subplot(1,2,1)
+            scatter3d(x, y, z, r.^2*80);
+            title("Initial plot", "fontsize",3)
+
+            subplot(1,2,2)
+            p = scatter3d(x, y, z, r.^2*80); // The same
+            title("Final plot", "fontsize",3)
+
+            // Let's post-process it through the handle:
+
+            // 1) Let's set all markers at y < 0 in yellow, and others in orange
+            np = size(p.data,1);  // number of points
+            tmp = ones(1,np) * color("orange");
+            tmp(p.data(:,2)<0) = color("yellow");
+            p.mark_background = tmp;
+
+            // 2) and markers at x > 0  1.4 smaller than other
+            tmp = p.data(:,1) > 0;
+            p.mark_size(tmp) = p.mark_size(tmp)/1.4;
+
+            // 3) Changing the edge color and thickness for all markers
+            p.mark_foreground = color("red");
+            p.thickness = 0.5;
+
+            // Tuning axes
+            Axes = gcf().children;
+            Axes.rotation_angles = [82, -40];
+            Axes.grid = [1 1 1]*color("grey60");
+
+            gcf().axes_size = [700 350];
+        ]]></scilab:image>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
@@ -564,7 +578,21 @@ p.mark_background = color(0.5, 0.5, 0);
             <revision>
                 <revnumber>6.0.0</revnumber>
                 <revremark>
-                    Function <function>scatter3d</function> introduced.
+                    Function scatter3() introduced.
+                </revremark>
+            </revision>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revremark>
+                    <itemizedlist>
+                        <listitem>
+                            Function scatter3() set obsolete. scatter3d() is introduced.
+                        </listitem>
+                        <listitem>
+                            Colors can be specified as well with their "#RRGGBB" hexadecimal
+                            standard code or their index in the color map.
+                        </listitem>
+                    </itemizedlist>
                 </revremark>
             </revision>
         </revhistory>
index d2cda48..d22413b 100644 (file)
@@ -1,7 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) Scilab Enterprises - 2015 - 2012 - Juergen Koch <juergen.koch@hs-esslingen.de>
-// 
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018 - 2020 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function polyLine = scatter(varargin)
+function varargout = scatter(varargin)
 
     polyLine = 0;
     [lhs,rhs] = argn(0);
 
+    // Example:
     if ~rhs
-        clf;
-        t = linspace(0,25,200);
-        x = t.*cos(t);
-        y = t.*sin(t);
-        polyLine = scatter(x,y,t,t,"fill","markerEdgeColor","darkblue")
-        return;
+        r = gca().axes_bounds; delete(gca()); xsetech(r);
+        t = linspace(0, 25, 200);
+        x = t .* cos(t);
+        y = t .* sin(t);
+        polyLine = scatter(x, y, t, t, "fill", "markerEdgeColor", "darkblue")
+        if lhs > 0
+            varargout = list(polyLine);
+        end
+        return
     end
 
-    //detect and set the current axes now:
-    n = size(varargin);
-    if type(varargin(1)) == 9 then // graphic handle
-        hdle = varargin(1);
-        if hdle.type == "Axes" then
-            if n < 3 then
-                warning("Not enough input arguments.")
-                return;
-            else
-                axesHandle = varargin(1);
-                X = varargin(2);
-                Y = varargin(3);
-                polyLine = scatter3d(axesHandle,X,Y,[],varargin(4:n));
-            end
-        else
-            warning("Handle should be an Axes handle.")
-            return;
+    // Minimal arguments checking to call scatter3(), and call it.
+    msg = _("%s: Wrong number of input arguments: At least %d expected.\n");
+    if type(varargin(1))==9 then    // graphic handle
+        if rhs < 3
+            error(msprintf(msg, "scatter", 3));
         end
+        _from_Scatter_ = 1  // calling flag = shift of argins (for argins ranks in error msgs)
+        polyLine = scatter3d(varargin(1:3), [], varargin(4:$));
     else
-        if size(varargin) < 2 then
-            warning("Not enough input arguments.")
-            return;
-        else
-            X = varargin(1);
-            Y = varargin(2);
-            polyLine = scatter3d(X,Y,[],varargin(3:n));
+        if rhs < 2
+            error(msprintf(msg, "scatter", 2))
         end
+        _from_Scatter_ = %eps/4
+        polyLine = scatter3d(gca(), varargin(1:2), [], varargin(3:$));
+    end
+    if lhs > 0
+        varargout = list(polyLine);
     end
-    
 endfunction
index 620504f..2f3df8d 100644 (file)
@@ -1,7 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) Scilab Enterprises - 2015 - 2012 - Juergen Koch <juergen.koch@hs-esslingen.de>
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018 - 2020 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-function polyLine = scatter3d(varargin)
+function varargout = scatter3d(varargin)
 
     polyLine = 0;
-    [lhs,rhs] = argn(0);
+    [lhs, rhs] = argn(0);
+    fname = "scatter3d";
+    FS = 0  // For argins shift in error messages, to substract from argin rank after Z
+    if isdef("_from_Scatter_") then
+        fname = "scatter";
+        FS = 1  // FromScatter
+    end
 
+    // Example 3D
+    // ----------
     if ~rhs
-        clf;
+        r = gca().axes_bounds; delete(gca()); xsetech(r);
         z = linspace(0,25,200);
-        x = z.*cos(z);
-        y = z.*sin(z);
-        polyLine = scatter3d(x,y,z,z,z,"fill","markerEdgeColor","darkblue");
+        x = z .* cos(z);
+        y = z .* sin(z);
+        polyLine = scatter3d(x,y,z,10+z.^1.2,z,"fill","markerEdgeColor","darkblue");
         set(gca(),"rotation_angles",[60,45])
-        return;
+        if lhs > 0
+            varargout = list(polyLine)
+        end
+        return
     end
 
-   //detect and set the current axes now:
-    if type(varargin(1)) == 9 then // graphic handle
-        hdle = varargin(1);
-        if hdle.type == "Axes" then
-            if size(varargin) < 4 then
-                warning("Not enough input arguments.")
-                return;
-            else
-                axesHandle = varargin(1);
-                X = varargin(2);
-                Y = varargin(3);
-                Z = varargin(4);
-                nextArgin = 5;
-            end
-        else
-            warning("Handle should be an Axes handle.")
-            return;
+    // PARSING, CHECKING and INITIALIZING MANDATORY ARGUMENTS
+    // ------------------------------------------------------
+    // graphic handle
+        // nh = 1  if primary call with argin#1 = axes, 0 otherwise
+    if type(varargin(1)) == 9 then
+        axesHandle = varargin(1);
+        if axesHandle.type ~= "Axes"
+            msg = _("%s: Argument #%d: Wrong type of graphic handle: ''%s'' expected.\n");
+            error(msprintf(msg, fname, 1, "Axes"));
         end
-    else
-        if size(varargin) < 3 then
-            warning("Not enough input arguments.")
-            return;
+        varargin(1) = null()
+        if FS==1
+            nh = floor(_from_Scatter_)
         else
-            axesHandle = [];
-            X = varargin(1);
-            Y = varargin(2);
-            Z = varargin(3);
-            nextArgin = 4;
+            nh = 1
         end
+    else
+        nh = 0
+        axesHandle = gca();
     end
-
-    if (isempty(X) & isempty(Y) & isempty(Z)) then
-        // nothing has to be done
-        return;
+    // Number of input arguments
+    if length(varargin) < 3 then    // should not occur from scatter() call
+        msg = _("%s: Wrong number of input arguments: At least %d expected.\n")
+        error(msprintf(msg, fname, 3+nh))
     end
+    // Now we know that at least the 3 next argins are defined
+    iarg = nh + 1   // rank of next argin
 
-    if ( isempty(Z) ) then
-        if (~isvector(X) | ~isvector(Y) | size(X) ~= size(Y)) then
-            warning("X and Y must be vectors of the same length.")
-            return;
-        end
+    // X:
+    X = varargin(1);
+    if ~or(type(X)==[1 5]) | ~isreal(X,0)
+        msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
+        error(msprintf(msg, fname, iarg))
     else
-        if (~isvector(X) | ~isvector(Y) | ~isvector(Z) | or(size(X) ~= size(Y)) | or(size(X) ~= size(Z))) then
-            warning("X, Y and Z must be vectors of the same length.")
-            return;
-        end
+        X = full(real(X(:)));
     end
+    varargin(1) = null();
+    iarg = iarg + 1
 
-    n = length(X);
-    [S,C,thickness,markStyle,markFg,markBg,fill,scanFailed] = scatterScanVargin(varargin,nextArgin,n);
-    if (scanFailed) then
-        return;
+    // Y:
+    Y = varargin(1);
+    if ~or(type(Y)==[1 5]) | ~isreal(Y,0)
+        msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
+        error(msprintf(msg, fname, iarg))
+    else
+        if length(Y)~=length(X) then
+            msg = _("%s: Arguments #%d and #%d: Same numbers of elements expected.\n")
+            error(msprintf(msg, fname, nh+1, iarg));
+        end
+        Y = full(real(Y(:)));
     end
+    varargin(1) = null();
+    iarg = iarg + 1
 
-    f = gcf();
-    old_drawing_mode = f.immediate_drawing;
-    f.immediate_drawing = "off";
-
-    if isempty(Z) then
-        if isempty(axesHandle) then
-            plot(X,Y);
+    // Z:
+    if ~FS then
+        Z = varargin(1);
+        if ~or(type(Z)==[1 5]) | ~isreal(Z,0)
+            msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
+            error(msprintf(msg, fname, iarg))
         else
-            plot(axesHandle,X,Y);
+            if length(Z)~=length(X) then
+                msg = _("%s: Arguments #%d and #%d: Same numbers of elements expected.\n")
+                error(msprintf(msg, fname, nh+1, iarg));
+            end
+            Z = full(real(Z(:)));
         end
-        currentEntity = gce();
-        polyLine = currentEntity.children;
+        iarg = iarg + 1
     else
-        if isempty(axesHandle) then
-            param3d(X,Y,Z);
-        else
-            set("current_axes",axesHandle)
-            param3d(X,Y,Z);
-        end
-        polyLine = gce();
+        Z = []
     end
+    varargin(1) = null();
 
-    if polyLine.Type <> "Polyline" then
-        warning("Handle should be a Polyline handle.");
-    else
-        scatterSetPolyline(polyLine,S,C,thickness,markStyle,markFg,markBg,fill);
-
-        if ~isempty(Z) then
-            set(gca(),"cube_scaling","on");
-            set(gca(),"grid",[1 1 1]);
-        end
+    // Empty case
+    if X==[] then
+        return
     end
 
-    f.immediate_drawing = old_drawing_mode;
-endfunction
+    // List of properties names (lower case) (capital = added)
+    // "fill"
+    // "marker" "markerstyle" "Markstyle"
+    // "markerfacecolor" "markerbackgroundcolor"
+    // "markeredgecolor" "markerforeground" "markerbackgroundcolor"
+    // "thickness" "linewidth"
+    // Markers Text styles (available)
+    properties = ["marker" "markerstyle" "markstyle" ..
+                  "markerfacecolor" "markerbackground" ..
+                  "markeredgecolor" "markerforeground" ..
+                  "thickness" "linewidth" "datatips"];
+    markersT = ["." "+" "x" "o" "o+" "circle plus" "d" "fd" "filled diamond" ..
+    "d+" "diamond plus" "^" "v" ">" "<" "*" "*5" "p" "pentagram" "s" "square"];
+    // Markers Numerical codes styles (available)
+    markersN = [ 0   1   2   9   3        3         5   4         4 ..
+      8       8          6   7   12  13  10  14  14      14      11    11];
 
-function [S,C,thickness,markStyle,markFg,markBg,fill,scanFailed] = scatterScanVargin(argins,nextArgin,n)
+    // PARSING, CHECKING and INITIALIZING OPTIONS
+    // ------------------------------------------
+    // Marks sizes | "fill" | marker_symbol |
+    msizes = 36;                // Default markers area
+    mcolors = [];
+    markers = 9;
+    fill = %f;
+    smallOnTop = %f;
+    step = 1;
+    // Parsing step: 1 = msizes       2 = mcolors 3 = "fill"
+    //             3.5 = "smallOnTop" 4 = marker  5 = properties
 
-    scanFailed = %F;
+    while length(varargin) > 0 & step < 5
+       v = varargin(1)
+       if type(varargin(1))==0
+           v = []
+       end
+       select step
+       case 1
+           if type(v) == 10
+                if size(v,"*") == 1
+                   v = convstr(v)
+                   if v=="fill"
+                       [fill, step, iarg] = (%t, 3.5, iarg+1)
+                       varargin(1) = null()
+                       continue
+                   end
+                   if v=="smallontop"
+                       [fill, step, iarg] = (%t, 4, iarg+1)
+                       varargin(1) = null()
+                       continue
+                   end
+                   if or(v==markersT)
+                       markers = markersN(find(v==markersT, 1))
+                       [step, iarg] = (5, iarg+1)
+                       varargin(1) = null()
+                       continue
+                   end
+                   if or(v==properties)
+                       step = 5
+                       continue
+                   end
+                   msg = _("%s: Argument #%d: Wrong value. Please check allowed syntaxes and values.\n")
+                   error(msprintf(msg, fname, iarg))
+               else
+                   msg = _("%s: Argument #%d: Wrong value. Please check allowed syntaxes and values.\n")
+                   error(msprintf(msg, fname, iarg))
+               end
 
-    // check for size argument
-    S = [];
-    if  size(argins) >= nextArgin then
-        if isempty(argins(nextArgin)) then
-            nextArgin = nextArgin + 1;
-        else
-            if type(argins(nextArgin)) == 1 then
-                [n1,n2] = size(argins(nextArgin));
-                if (n1 == 1 & n2 == 1) | (n1 == n & n2 == 1) | (n1 == 1 & n2 == n) then
-                    S = argins(nextArgin);
-                    if iscolumn(S) then
-                        S = S.';
+           elseif type(v) == 1
+               if v==[]
+                   [step, iarg] = (2, iarg+1)
+                   varargin(1) = null()
+                   continue
+               end
+               if ~and(isreal(v,0))
+                   msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
+                   error(msprintf(msg, fname, iarg))
+               end
+               v = real(v);
+               if or(v<0)
+                   msg = _("%s: Argument #%d: Must be >= %d.\n")
+                   error(msprintf(msg, fname, iarg, 0))
+               end
+               if length(v) ~= 1 & length(v) ~= length(X)
+                   msg = _("%s: Arguments #%d and #%d: Same numbers of elements expected.\n")
+                   error(msprintf(msg, fname, nh+1, iarg));
+               end
+               [msizes, step, iarg] = (v, 2, iarg+1)
+               varargin(1) = null()
+
+           else
+               msg = _("%s: Argument #%d: Number(s) or text expected.\n")
+               error(msprintf(msg, fname, iarg))
+           end
+
+       case 2   // mcolors
+           if type(v)==1
+               if ~isreal(v,0)
+                   msg = _("%s: Argument #%d: Decimal number(s) expected.\n")
+                   error(msprintf(msg, fname, iarg))
+               end
+               v = real(v)
+               if v==[]
+                   [step, iarg] = (3, iarg+1)
+                   varargin(1) = null()
+                   continue
+               end
+               if length(v) == length(X)
+                    // Whole colormap scaled to data
+                    [cMin, cMax] = (min(v), max(v));
+                    cmap = gcf().color_map;
+                    numColors = size(cmap,1);
+                    if ((cMax-cMin)/(cMin+cMax) > %eps) then
+                        mcolors = round((numColors-1)*(v - cMin)/(cMax - cMin)) + 1;
+                    else
+                        mcolors = cMin;
                     end
-                    nextArgin = nextArgin + 1;
-                else
-                    warning("S must be a scalar or a vector of the same length as X.");
-                    scanFailed = %T;
-                    return;
+                   [step, iarg] = (3, iarg+1)
+                   varargin(1) = null()
+                   continue
                 end
+           end
+           c = iscolor(v)
+           if ~or(isnan(c(:,1)))
+               if length(c) <> 1 & ~(type(c)==1 & and(size(c)==[1 3])) ..
+                   & size(c,1) <> length(X)
+                   msg = _("%s: Argument #%d: Wrong size: one or %d colors expected.\n")
+                   error(msprintf(msg, fname, iarg, length(X)))
+               end
+               if size(c,2) > 1
+                   mcolors = addcolor(c)
+               else
+                   mcolors = c
+               end
+               [step, iarg] = (3, iarg+1)
+               varargin(1) = null()
+           else
+               step = 3
+           end
+
+       case 3  // "fill"
+           if type(v)==10 & size(v,"*")==1
+               v = convstr(v)
+               if v=="fill"
+                   [fill, iarg] = (%t, iarg+1)
+                   varargin(1) = null()
+               end
             end
-        end
-    end
+            step = 3.5
 
-    // check for color argument
-    C = [];
-    if  size(argins) >= nextArgin then
-        if isempty(argins(nextArgin)) then
-            nextArgin = nextArgin + 1;
-        else
-            [n1,n2] = size(argins(nextArgin));
-            if type(argins(nextArgin)) == 1 then
-                if (n1 == n & n2 == 1) | (n1 == 1 & n2 == n) then
-                    C = scatterLinearColorMap(argins(nextArgin));
-                    nextArgin = nextArgin + 1;
-                elseif n1 == n & n2 == 3 then
-                    C = addcolor(argins(nextArgin));
-                    nextArgin = nextArgin + 1;
-                else
-                    warning("C must be a vector or a matrix of the same length as X.");
-                    scanFailed = %T;
-                    return;
-                end
-                if iscolumn(C) then
-                    C = C.';
-                end
-            elseif type(argins(nextArgin)) == 10 then
-                if n1 == 1 & n2 == 1 then
-                    // check if string specifies a color
-                    colorRGB = name2rgb(argins(nextArgin));
-                    if ~isempty(colorRGB) then
-                        C = addcolor(colorRGB/255);
-                        nextArgin = nextArgin + 1;
+       case 3.5  // "smallOnTop"
+           if type(v)==10 & size(v,"*")==1
+               v = convstr(v)
+               if v=="smallontop"
+                   [smallOnTop, iarg] = (%t, iarg+1)
+                   varargin(1) = null()
+               end
+            end
+            step = 4
+
+       case 4
+           // symbol or symbol id or property name
+           if size(v,"*") <> 1
+               msg = _("%s: Argument #%d: Scalar (1 element) expected.\n")
+               error(msprintf(msg, fname, iarg))
+           end
+           if and(type(v) <> [1 10])
+               msg = _("%s: Argument #%d: Number or text expected.\n")
+               error(msprintf(msg, fname, iarg))
+           end
+           if type(v)==1
+               tmp = find(v==markersN, 1)
+               if tmp == []
+                   msg = _("%s: Argument #%d: Wrong marker id.\n")
+                   error(msprintf(msg, fname, iarg))
+               end
+               markers = v
+               [step, iarg] = (5, iarg+1)
+               varargin(1) = null()
+           else
+               v = convstr(v)
+               tmp = find(v==markersT, 1)
+               if tmp <> []
+                   markers = markersN(tmp)
+                   [step, iarg] = (5, iarg+1)
+                   varargin(1) = null()
+               end
+               step = 5
+           end
+
+       end  // select
+   end  // while
+
+    // <Property, Value> pairs
+    // .......................
+    thickness = 1;
+    mBGcolors = [];
+    mFGcolors = [];
+    datatips = [];
+
+    while length(varargin) > 0
+        v = varargin(1)
+        if type(v)~=10
+            msg = _("%s: Argument #%d: keyword or property name expected.\n")
+            error(msprintf(msg, fname, iarg));
+        end
+        if size(v,"*") > 1
+            msg = _("%s: Argument #%d: Scalar (1 element) expected.\n");
+            error(msprintf(msg, fname, iarg));
+        end
+        if ~or(convstr(v)==properties)
+            msg = _("%s: Argument #%d: Unknown property name ''%s''.\n");
+            error(msprintf(msg, fname, iarg, v));
+        end
+        v = convstr(v);
+        varargin(1) = null()
+        if length(varargin)==0
+            msg = _("%s: Argument #%d: Value missing for the given property.\n")
+            error(msprintf(msg, fname, iarg))
+        end
+        val = varargin(1);
+        iarg = iarg+1;
+        if or(v==["marker" "markerstyle" "markstyle"]) then
+            if size(val,"*")~=1
+                msg = _("%s: Argument #%d: Scalar (1 element) expected.\n")
+                error(msprintf(msg, fname, iarg))
+            end
+            if type(val)==10 & ~or(convstr(val)==markersT) | ..
+               type(val)==1 & ~or(val==markersN)
+                msg = _("%s: Argument #%d: Wrong marker specification.\n")
+                error(msprintf(msg, fname, iarg))
+            end
+            if type(val)==10
+                markers = markersN(find(markersT==val));
+            else
+                markers = val
+            end
+        elseif or(v==["thickness" "linewidth"]) then
+            if size(val,"*")~=1
+                msg = _("%s: Argument #%d: Scalar (1 element) expected.\n");
+                error(msprintf(msg, fname, iarg));
+            end
+            if type(val)~=1 | ~isreal(val,0) | val<0
+                msg = _("%s: Argument #%d: Non-negative integers expected.\n");
+                error(msprintf(msg, fname, iarg));
+            end
+            thickness = val;
+        elseif or(v==["markeredgecolor" "markerforeground" ..
+                      "markerfacecolor" "markerbackground" ]);
+            c = iscolor(val);
+            if or(isnan(c(:,1))) then
+                msg = _("%s: Argument #%d: Wrong color specification.\n");
+                error(msprintf(msg, fname, iarg));
+            end
+            if size(c,1)==1
+                if or(v==["markeredgecolor" "markerforeground" "markforeground"]);
+                    mFGcolors = c;
+                    if length(c)>1
+                        mFGcolors = addcolor(c);
                     end
-                elseif (n1 == n & n2 == 1) | (n1 == 1 & n2 == n) then
-                    C = addcolor(name2rgb(argins(nextArgin))/255);
-                    if isempty(C) then
-                        warning("Wrong color specified.");
-                        scanFailed = %T;
-                        return;
-                    else
-                         nextArgin = nextArgin + 1;
+                else
+                    mBGcolors = c;
+                    if length(c)>1
+                        mBGcolors = addcolor(c);
                     end
                 end
+            else
+                msg = _("%s: Argument #%d: Scalar (1 element) expected.\n");
+                error(msprintf(msg, fname, iarg));
             end
-        end
-    end
 
-    // check for "fill" argument
-    fill = %F;
-    if  size(argins) >= nextArgin then
-        if type(argins(nextArgin)) == 10 then
-            if argins(nextArgin) == "fill" then
-                fill = %T;
-                nextArgin = nextArgin + 1;
+        elseif v=="datatips"
+            if typeof(val)=="implicitlist"
+                val = horner(val, length(X))
+            elseif type(val)<>1 | ~isreal(val) | ..
+                or(val<1|val>length(X)) | or(val <> int(val))
+                msg = _("%s: Argument #%d: Integers in %s expected.\n")
+                tmp = msprintf("[1,%d]",length(X));
+                error(msprintf(msg, fname, iarg, tmp))
             end
+            // Indices of points for which a datatip must be created
+            datatips = val;
         end
+        varargin(1) = null();
+        iarg = iarg + 1;
     end
-
-    // check for marker argument
-    markStyle = 9; // default circle
-    if  size(argins) >= nextArgin then
-        if type(argins(nextArgin)) == 10 then
-            ms = getMarkStyle(argins(nextArgin));
-            if ms >= 0 & ms <= 14 then
-                markStyle = ms;
-                nextArgin = nextArgin + 1;
-            end
+    if mFGcolors==[] then
+        if mcolors <> [] then
+            mFGcolors = mcolors
+        else
+            mFGcolors = color("blue");
         end
     end
-
-    // check for property-value pairs
-    markFg = -1;
-    markBg = -1;
-    thickness = 1.0; // default
-    while  size(argins) >= nextArgin do
-        if size(argins) == nextArgin then
-            warning("Incorrect number of inputs for property-value pairs.");
-            scanFailed = %T;
-            return;
+    if mBGcolors==[] then
+        if mcolors <> [] & fill
+            mBGcolors = mcolors
         else
-            select argins(nextArgin)
-            case "marker"
-                markStyle = getMarkStyle(argins(nextArgin+1));
-                if markStyle == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property marker."]));
-                    scanFailed = %T;
-                    return;
-                end
-            case "markerStyle"
-                markStyle = getMarkStyle(argin(nextArgin+1));
-                if markStyle == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property markerStyle."]));
-                    scanFailed = %T;
-                    return;
-                end
-            case "markerEdgeColor"
-                markFg = colorIndex(argins(nextArgin+1));
-                if markFg == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property markerEdgeColor."]));
-                    scanFailed = %T;
-                    return;
-                end;
-            case "markerForeground"
-                markFg = colorIndex(argins(nextArgin+1));
-                if markFg == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property markerForeground."]));
-                    scanFailed = %T;
-                    return;
-                end;
-            case "markerFaceColor"
-                fill = %T;
-                markBg = colorIndex(argins(nextArgin+1));
-                if markBg == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property markerFaceColor."]));
-                    scanFailed = %T;
-                    return;
-                end;
-            case "markerBackground"
-                fill = %T;
-                markBg = colorIndex(argins(nextArgin+1));
-                if markBg == -1 then
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property markerBackground."]));
-                    scanFailed = %T;
-                    return;
-                end;
-            case "linewidth"
-                if type(argins(nextArgin+1)) == 1 then
-                    thickness = argins(nextArgin+1);
-                else
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property linewidth."]));
-                    scanFailed = %T;
-                    return;
-                end
-            case "thickness"
-                if type(argins(nextArgin+1)) == 1 then
-                    thickness = argins(nextArgin+1);
-                else
-                    warning(strcat([argins(nextArgin+1) " is not a valid value for property thickness."]));
-                    scanFailed = %T;
-                    return;
-                end
+            if ~fill
+                mBGcolors = 0   // Transparent
+            elseif mcolors <> []
+                mBGcolors = mcolors
             else
-                warning(strcat(["There is no " argins(nextArgin) " property on the Scatter class."]));
-                scanFailed = %T;
-                return;
+                mBGcolors = color("blue")
             end
         end
-        nextArgin = nextArgin + 2;
     end
-
-endfunction
-
-function colorInd = colorIndex(colorSpec)
-    colorInd = -1;
-    if type(colorSpec) == 10 & size(colorSpec) == [1 1] then
-        colorRGB = name2rgb(colorSpec);
-        if ~isempty(colorRGB) then
-            colorInd = addcolor(colorRGB/255);
-            return;
-        end
-    elseif type(colorSpec) == 1 & (size(colorSpec) == [1 3] | size(colorSpec) == [3 1]) then
-        colorInd = addcolor(colorSpec);
-        return;
+    if mcolors == [] then
+        mcolors = color("blue");    // Default markers color
     end
-    warning("Specified string is an invalid color value.");
-endfunction
 
-function markStyle = getMarkStyle(name)
-    if type(name) ~= 10 then
-        markStyle = -1;
-    else
-        select name
-        case "."
-            markStyle = 0;
-        case "+"
-            markStyle = 1;
-        case "x"
-            markStyle = 2;
-        case "circle plus"
-            markStyle = 3;
-        case "filled diamond"
-            markStyle = 4;
-        case "d"
-            markStyle = 5;
-        case "diamond"
-            markStyle = 5;
-        case "^"
-            markStyle = 6;
-        case "v"
-            markStyle = 7;
-        case "diamond plus"
-            markStyle = 8;
-        case "o"
-            markStyle = 9;
-        case "*"
-            markStyle = 10;
-        case "s"
-            markStyle = 11;
-        case "square"
-            markStyle = 11;
-        case ">"
-            markStyle = 12;
-        case "<"
-            markStyle = 13;
-        case "p"
-            markStyle = 14;
-        case "pentagram"
-            markStyle = 14;
-        else
-            markStyle = -1;
+    // Option "smallOnTop"
+    // -------------------
+    if smallOnTop & length(msizes) > 1 then
+        [msizes, k] = gsort(msizes,"g");
+        X = X(k);
+        Y = Y(k);
+        if Z <> []
+            Z = Z(k);
+        end
+        if length(thickness) > 1
+            thickness = thickness(k);
+        end
+        if length(markers) > 1
+            markers = markers(k);
+        end
+        if length(mFGcolors) > 1
+            mFGcolors = mFGcolors(k);
+        end
+        if length(mBGcolors) > 1
+            mBGcolors = mBGcolors(k);
+        end
+        if length(datatips) > 1
+            [?,kk] = gsort(k,"g","i");
+            datatips = kk(datatips);
         end
     end
-endfunction
 
-function colorIndex = scatterLinearColorMap(colorValue)
-    cMin = min(colorValue);
-    cMax = max(colorValue);
-    cmap = get(gcf(),"color_map");
-    numColors = size(cmap,1);
-    if (cMax-cMin > %eps) then
-        colorIndex = (numColors-1)*(colorValue - cMin)/(cMax - cMin) + 1;
+    // ========
+    // PLOTTING
+    // ========
+    f = gcf();
+    old_drawing_mode = f.immediate_drawing;
+    f.immediate_drawing = "off";
+
+    if isempty(Z) then
+        plot(axesHandle, X,Y);
+        currentEntity = gce();
+        polyLine = currentEntity.children;
     else
-        colorIndex = 1; // default color index
+        set("current_axes", axesHandle);
+        param3d(X,Y,Z);
+        polyLine = gce();
     end
-endfunction
-
-function scatterSetPolyline(polyLine,S,C,thickness,markStyle,markFg,markBg,fill)
-
-    // set mark mode
-    polyLine.line_mode = "off";
-    polyLine.mark_mode = "on";
-
-    // set thickness
-    polyLine.thickness = thickness;
-
-    // set mark style
-    polyLine.mark_style = markStyle;
 
-    // set mark size
-    polyLine.mark_size_unit = "point";
-    if isempty(S) then
-        polyLine.mark_size = 7;
+    if polyLine.Type <> "Polyline" then
+        msg = _("%s: Argument #%d: Wrong type of graphic handle: ''%s'' expected.\n");
+        warning(msprintf(msg, fname, -1, "Polyline"));
     else
-        if size(S) == [1 1] | size(S) == [1 n]
-            polyLine.mark_size = ceil(sqrt(4*S/%pi));
-        else
-            warning("S must be a scalar or a vector of the same length as X.");
-            return;
-        end
-    end
+        polyLine.line_mode = "off";
+        polyLine.mark_mode = "on";
+        polyLine.thickness = matrix(thickness, -1, 1);
+        polyLine.mark_style = matrix(markers, -1, 1);
+        polyLine.mark_size_unit = "point";
+        polyLine.mark_foreground = matrix(mFGcolors, 1, -1);
+        polyLine.mark_background = matrix(mBGcolors, 1, -1);
+        polyLine.mark_size = matrix(ceil(2*sqrt(msizes/%pi)),1,-1);
 
-    // set mark foreground and background color
-    if isempty(C) then
-        if markFg == -1 then
-            markFg = addcolor(name2rgb("blue")/255); // default
-        end
-        polyLine.mark_foreground = markFg;
-        if markBg == -1 then
-            markBg = markFg;
-        end
-        if fill == %T then
-            polyLine.mark_background = markBg;
-        else
-            polyLine.mark_background = 0; // transparent
-        end
-     else
-        if size(C) == [1 1] then
-            polyLine.mark_foreground = C;
-            if fill == %T then
-                polyLine.mark_background = C;
-            else
-                if markBg == -1 then
-                    polyLine.mark_background = 0; // transparent
-                else
-                    polyLine.mark_background = markBg;
-                end
-            end
-        else
-            if fill == %T then
-                if markFg == -1 then
-                    polyLine.mark_foreground = C; // transparent
-                else
-                    polyLine.mark_foreground = markFg;
-                end
-                polyLine.mark_background = C;
-            else
-                polyLine.mark_foreground = C;
-                if markBg == -1 then
-                    polyLine.mark_background = 0; // transparent
-                else
-                    polyLine.mark_background = markBg;
+        if datatips <> []
+            polyLine.datatip_display_mode = "mouseover";
+            dispSize = length(msizes) > 1
+            for i = matrix(datatips,1,-1)
+                kdat = datatipCreate(polyLine, i);
+                if dispSize
+                    kdat.user_data = msizes(i)
+                    kdat.text = [msprintf("size: %d",msizes(i)) ;
+                                 kdat.text ];
                 end
             end
+            polyLine.datatips.mark_size = 1;
+            // polyLine.datatips.mark_mode = "off";
+        end
+        if ~isempty(Z) then
+            isoview off
+            set(gca(),"grid",[1 1 1]);
         end
     end
 
+    f.immediate_drawing = old_drawing_mode;
+
+    if lhs > 0 then
+        varargout = list(polyLine)
+    end
 endfunction
diff --git a/scilab/modules/graphics/tests/nonreg_tests/bug_15481.tst b/scilab/modules/graphics/tests/nonreg_tests/bug_15481.tst
new file mode 100644 (file)
index 0000000..6162aa0
--- /dev/null
@@ -0,0 +1,26 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- TEST WITH GRAPHIC -->
+// <-- NO CHECK REF -->
+
+// <-- Non-regression test for bug 15481 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/15481
+//
+// <-- Short Description -->
+// scatter() and scatter3d() failed for only one point
+
+clf reset
+assert_checkequal(execstr("scatter(1,2);", "errcatch"), 0);
+assert_checkequal(execstr("scatter(1,2,100);", "errcatch"), 0);
+assert_checkequal(execstr("scatter(1,2,100, ""orange"");", "errcatch"), 0);
+
+assert_checkequal(execstr("scatter3d(1,2,3);", "errcatch"), 0);
+assert_checkequal(execstr("scatter3d(1,2,3,100);", "errcatch"), 0);
+assert_checkequal(execstr("scatter3d(1,2,3,100,""orange"");", "errcatch"), 0);
diff --git a/scilab/modules/graphics/tests/unit_tests/scatter.dia.ref b/scilab/modules/graphics/tests/unit_tests/scatter.dia.ref
deleted file mode 100644 (file)
index ad07c80..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-// =============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) Scilab Enterprises - 2015-2010 - Juergen Koch <juergen.koch@hs-esslingen.de>
-//
-// This file is distributed under the same license as the Scilab package.
-// =============================================================================
-// <-- TEST WITH GRAPHIC -->
-//
-// test data
-rand("seed",0);
-x = linspace(0,2,200);
-y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
-s = linspace(1,30,length(x));
-//
-// Test #1 Create 2D scatter plot 
-h = scf();
-p = scatter(x,y);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,2);
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #2 Vary marker size
-h = scf();
-p = scatter(x,y,s);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,2);
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #3 Vary marker size and color
-h = scf();
-set(gcf(),"color_map",coolcolormap(64))
-p = scatter(x,y,s,x);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,floor((64-1)*(x-min(x))/(max(x)-min(x))+1));
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #4 Fill the markers
-h = scf();
-p = scatter(x,y,s,y,"fill");
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,floor((32-1)*(y-min(y))/(max(y)-min(y))+1));
-assert_checkequal(p.mark_background,floor((32-1)*(y-min(y))/(max(y)-min(y))+1));
-close(h);
-//
-// Test #5 Specify subplot for scatter plot
-h = scf();
-subplot(2,1,1);
-p1 = scatter(gca(),x,y);
-assert_checkequal(p1.line_mode,"off");
-assert_checkequal(p1.fill_mode,"off");
-assert_checkequal(p1.thickness,1);
-assert_checkequal(p1.mark_mode,"on");
-assert_checkequal(p1.mark_style,9);
-assert_checkequal(p1.mark_size_unit,"point");
-assert_checkequal(p1.mark_size,7);
-assert_checkequal(p1.mark_foreground,2);
-assert_checkequal(p1.mark_background,0);
-subplot(2,1,2);
-p2 = scatter(gca(),x,y,"fill","s");
-assert_checkequal(p2.line_mode,"off");
-assert_checkequal(p2.fill_mode,"off");
-assert_checkequal(p2.thickness,1);
-assert_checkequal(p2.mark_mode,"on");
-assert_checkequal(p2.mark_style,11);
-assert_checkequal(p2.mark_size_unit,"point");
-assert_checkequal(p2.mark_size,7);
-assert_checkequal(p2.mark_foreground,2);
-assert_checkequal(p2.mark_background,2);
-close(h);
-//
-// test data
-rand("seed",0);
-x = rand(1,200);
-y = rand(1,200);
-//
-// Test #6 Specify marker symbol
-h = scf();
-p = scatter(x,y,"d");
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,5);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,2);
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #7 Change marker color and line width
-h = scf();
-p = scatter(x,y,"markerEdgeColor",[0 .4 .4],...
-                "markerFaceColor",[0 .8 .8],...
-                "linewidth",1.5);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1.5);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,color(0,.4*255,.4*255));
-assert_checkequal(p.mark_background,color(0,.8*255,.8*255));
-close(h);
-//
-// Test data
-t = linspace(0,25,200);
-x = t.*cos(t);
-y = t.*sin(t);
-//
-// Test #8 Modify scatter plot after creation
-h = scf();
-p = scatter(x,y,t);
-p.thickness = 0.5;
-p.mark_foreground = color("darkblue");
-p.mark_background = color("darkcyan");
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,0.5);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*t/%pi)));
-assert_checkequal(p.mark_foreground,color("darkblue"));
-assert_checkequal(p.mark_background,color("darkcyan"));
-close(h);
-//
-// Test #9 Testing graphics handle
-h = scf();
-p = scatter(gca(),x,y,t);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*t/%pi)));
-assert_checkequal(p.mark_foreground,2);
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test data
-x = 0.1:0.2:0.9;
-//
-// Test #10 Testing single color string specification
-h = scf();
-p = scatter(x,x,[],"red");
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,color("red"));
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #11 Testing color vector of strings specification
-h = scf();
-p = scatter(x,x,[],["red" "green" "blue" "grey" "black"]);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,[color("red") color("green") color("blue") color("grey") color("black")]);
-assert_checkequal(p.mark_background,0);
-close(h);
-//
-// Test #12 Testing color RGB matrix specification
-h = scf();
-RGB = [255   0   0
-         0 255   0
-         0   0 255
-       128 128 128
-         0   0   0];
-p = scatter(x,x,[],RGB/255);
-assert_checkequal(p.line_mode,"off");
-assert_checkequal(p.fill_mode,"off");
-assert_checkequal(p.thickness,1);
-assert_checkequal(p.mark_mode,"on");
-assert_checkequal(p.mark_style,9);
-assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,7);
-assert_checkequal(p.mark_foreground,...
-[color(RGB(1,1),RGB(1,2),RGB(1,3))...
- color(RGB(2,1),RGB(2,2),RGB(2,3))...
- color(RGB(3,1),RGB(3,2),RGB(3,3))...
- color(RGB(4,1),RGB(4,2),RGB(4,3))...
- color(RGB(5,1),RGB(5,2),RGB(5,3))]);
-assert_checkequal(p.mark_background,0);
-close(h);
index e6565dd..06499b7 100644 (file)
@@ -1,12 +1,14 @@
-// =============================================================================
+// ===================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) Scilab Enterprises - 2015-2010 - Juergen Koch <juergen.koch@hs-esslingen.de>
+// Copyright (C) 2015-2010 - Scilab Enterprises - Juergen Koch <juergen.koch@hs-esslingen.de>
+// Copyright (C) 2018-2020 - Samuel GOUGEON
 //
 // This file is distributed under the same license as the Scilab package.
-// =============================================================================
+// ===================================================================
 
 // <-- TEST WITH GRAPHIC -->
-
+// <-- NO CHECK REF -->
+// <-- ENGLISH IMPOSED -->
 //
 // test data
 rand("seed",0);
@@ -14,9 +16,10 @@ x = linspace(0,2,200);
 y = exp(-x).*cos(10*x) + 0.2*rand(1,length(x));
 s = linspace(1,30,length(x));
 
+clf reset
+
 //
-// Test #1 Create 2D scatter plot 
-h = scf();
+// Test #1 Create 2D scatter plot
 p = scatter(x,y);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -27,10 +30,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-close(h);
 //
 // Test #2 Vary marker size
-h = scf();
+clf
 p = scatter(x,y,s);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -41,10 +43,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-close(h);
 //
 // Test #3 Vary marker size and color
-h = scf();
+clf
 set(gcf(),"color_map",coolcolormap(64))
 p = scatter(x,y,s,x);
 assert_checkequal(p.line_mode,"off");
@@ -54,12 +55,11 @@ assert_checkequal(p.mark_mode,"on");
 assert_checkequal(p.mark_style,9);
 assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,floor((64-1)*(x-min(x))/(max(x)-min(x))+1));
-assert_checkequal(p.mark_background,0);
-close(h);
+assert_checkequal(p.mark_foreground, round((64-1)*(x-min(x))/(max(x)-min(x))+1));
+assert_checkequal(p.mark_background, 0);
 //
 // Test #4 Fill the markers
-h = scf();
+clf reset
 p = scatter(x,y,s,y,"fill");
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -68,12 +68,11 @@ assert_checkequal(p.mark_mode,"on");
 assert_checkequal(p.mark_style,9);
 assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,floor((32-1)*(y-min(y))/(max(y)-min(y))+1));
-assert_checkequal(p.mark_background,floor((32-1)*(y-min(y))/(max(y)-min(y))+1));
-close(h);
+assert_checkequal(p.mark_foreground, round((32-1)*(y-min(y))/(max(y)-min(y))+1));
+assert_checkequal(p.mark_background, round((32-1)*(y-min(y))/(max(y)-min(y))+1));
 //
 // Test #5 Specify subplot for scatter plot
-h = scf();
+clf
 subplot(2,1,1);
 p1 = scatter(gca(),x,y);
 assert_checkequal(p1.line_mode,"off");
@@ -86,7 +85,7 @@ assert_checkequal(p1.mark_size,7);
 assert_checkequal(p1.mark_foreground,2);
 assert_checkequal(p1.mark_background,0);
 subplot(2,1,2);
-p2 = scatter(gca(),x,y,"fill","s");
+p2 = scatter(gca(),x,y,"fill","s");  // msizes & mcolors are implicitly skipped !
 assert_checkequal(p2.line_mode,"off");
 assert_checkequal(p2.fill_mode,"off");
 assert_checkequal(p2.thickness,1);
@@ -96,7 +95,6 @@ assert_checkequal(p2.mark_size_unit,"point");
 assert_checkequal(p2.mark_size,7);
 assert_checkequal(p2.mark_foreground,2);
 assert_checkequal(p2.mark_background,2);
-close(h);
 
 //
 // test data
@@ -106,8 +104,8 @@ y = rand(1,200);
 
 //
 // Test #6 Specify marker symbol
-h = scf();
-p = scatter(x,y,"d");
+clf
+p = scatter(x,y,"d");   // msizes, mcolors and "fill" are implicitly skipped !
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
 assert_checkequal(p.thickness,1);
@@ -117,10 +115,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-close(h);
 //
 // Test #7 Change marker color and line width
-h = scf();
+clf
 p = scatter(x,y,"markerEdgeColor",[0 .4 .4],...
                 "markerFaceColor",[0 .8 .8],...
                 "linewidth",1.5);
@@ -133,7 +130,6 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,color(0,.4*255,.4*255));
 assert_checkequal(p.mark_background,color(0,.8*255,.8*255));
-close(h);
 
 //
 // Test data
@@ -143,7 +139,7 @@ y = t.*sin(t);
 
 //
 // Test #8 Modify scatter plot after creation
-h = scf();
+clf
 p = scatter(x,y,t);
 p.thickness = 0.5;
 p.mark_foreground = color("darkblue");
@@ -157,10 +153,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*t/%pi)));
 assert_checkequal(p.mark_foreground,color("darkblue"));
 assert_checkequal(p.mark_background,color("darkcyan"));
-close(h);
 //
 // Test #9 Testing graphics handle
-h = scf();
+clf
 p = scatter(gca(),x,y,t);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -171,7 +166,6 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*t/%pi)));
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-close(h);
 
 //
 // Test data
@@ -179,7 +173,7 @@ x = 0.1:0.2:0.9;
 
 //
 // Test #10 Testing single color string specification
-h = scf();
+clf
 p = scatter(x,x,[],"red");
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -190,10 +184,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,color("red"));
 assert_checkequal(p.mark_background,0);
-close(h);
 //
 // Test #11 Testing color vector of strings specification
-h = scf();
+clf
 p = scatter(x,x,[],["red" "green" "blue" "grey" "black"]);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -204,10 +197,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,[color("red") color("green") color("blue") color("grey") color("black")]);
 assert_checkequal(p.mark_background,0);
-close(h);
 //
 // Test #12 Testing color RGB matrix specification
-h = scf();
+clf
 RGB = [255   0   0
          0 255   0
          0   0 255
@@ -228,4 +220,88 @@ assert_checkequal(p.mark_foreground,...
  color(RGB(4,1),RGB(4,2),RGB(4,3))...
  color(RGB(5,1),RGB(5,2),RGB(5,3))]);
 assert_checkequal(p.mark_background,0);
-close(h);
+
+// ==============
+// Error messages
+// ==============
+msg = "scatter: Wrong number of input arguments: At least 2 expected.";
+assert_checkerror("scatter(1)", msg);
+msg = "scatter: Wrong number of input arguments: At least 3 expected.";
+assert_checkerror("scatter(gca(),1)", msg);
+msg = "scatter: Argument #1: Wrong type of graphic handle: ''Axes'' expected.";
+assert_checkerror("scatter(gcf(),1,2)", msg);
+msg = "scatter: Argument #1: Decimal number(s) expected.";
+assert_checkerror("scatter(int8(1),2)", msg);
+assert_checkerror("scatter(1+%i,2)", msg);
+msg = "scatter: Argument #2: Decimal number(s) expected.";
+assert_checkerror("scatter(1,int8(2))", msg);
+assert_checkerror("scatter(1,2-%i)", msg);
+assert_checkerror("scatter(1,%z)", msg);
+msg = "scatter: Arguments #1 and #2: Same numbers of elements expected.";
+assert_checkerror("scatter(1,[2 3])", msg);
+
+msg = "scatter: Argument #3: Decimal number(s) expected.";
+assert_checkerror("scatter(1,2,%i)", msg);
+msg = "scatter: Argument #3: Wrong value. Please check allowed syntaxes and values.";
+assert_checkerror("scatter(1,2,""A"")", msg);
+msg = "scatter: Arguments #1 and #3: Same numbers of elements expected.";
+assert_checkerror("scatter(1,2,[1 2])", msg);
+msg = "scatter: Argument #4: Wrong size: one or 1 colors expected.";
+assert_checkerror("scatter(1,2,3,[1 2])", msg);
+assert_checkerror("scatter(1,2,3,[""cyan"" ""red""])", msg);
+
+msg = "scatter: Argument #4: Decimal number(s) expected.";
+assert_checkerror("scatter(1,2,3,%i)", msg);
+
+// ==========
+// Properties
+// ==========
+// Marks styles (case insensitive)
+prop = ["marker" "MarKeR" "markerstyle"  "MARKSTYLE"];
+markersT = ["." "+" "x" "o" "o+" "circle plus" "d" "fd" "filled diamond" ..
+"d+" "diamond plus" "^" "v" ">" "<" "*" "*5" "p" "pentagram" "s" "square"];
+    // Markers Numerical codes styles (available)
+markersN = [ 0   1   2   9   3        3         5   4         4 ..
+  8       8          6   7   12  13  10  14  14      14      11    11];
+x = rand(1,20);
+y = rand(1,20);
+for p = prop
+    for v = markersT
+        assert_checkequal(execstr("clf, scatter(x,y,p,v);", "errcatch"), 0);
+        sleep(50)
+    end
+    for v = unique(markersN)
+        assert_checkequal(execstr("clf, scatter(x,y,p,v);", "errcatch"), 0);
+        sleep(50)
+    end
+end
+msg = "scatter: Argument #4: Wrong marker specification.";
+assert_checkerror("scatter(1,2,""marker"",""ab"")", msg);
+assert_checkerror("scatter(1,2,""marker"", 20)", msg);
+msg = "scatter: Argument #4: Scalar (1 element) expected.";
+assert_checkerror("scatter(1,2,""marker"",[1 2])", msg);
+msg = "scatter: Argument #5: Unknown property name ''A''.";
+assert_checkerror("scatter(1,2,10,4,""A"")", msg);
+
+msg = "scatter: Argument #4: Scalar (1 element) expected.";
+assert_checkerror("scatter(1,2,""linewidth"",[1 2])", msg);
+assert_checkerror("scatter(1,2,""thickness"",[1 2])", msg);
+msg = "scatter: Argument #4: Non-negative integers expected.";
+assert_checkerror("scatter(1,2,""linewidth"", -1)", msg);
+assert_checkerror("scatter(1,2,""thickness"", -1)", msg);
+assert_checkerror("scatter(1,2,""linewidth"", %i)", msg);
+assert_checkerror("scatter(1,2,""thickness"", %i)", msg);
+assert_checkerror("scatter(1,2,""linewidth"", %z)", msg);
+assert_checkerror("scatter(1,2,""thickness"", %z)", msg);
+
+prop = ["markeredgecolor" "markerforeground" ..
+        "markerfacecolor" "markerbackground"];
+for p = prop
+    assert_checkequal(execstr("clf, scatter(1,2, p,""orange"")", "errcatch"),0);
+    assert_checkequal(execstr("clf, scatter(1,2, p,""#00FF00"")", "errcatch"),0);
+    assert_checkequal(execstr("clf, scatter(1,2, p, color(""red""))", "errcatch"),0);
+end
+msg = "scatter: Argument #3: Value missing for the given property.";
+assert_checkerror("scatter(1,2,""marker"")", msg);
+msg = "scatter: Argument #3: Wrong value. Please check allowed syntaxes and values.";
+assert_checkerror("scatter(1,2,""orange"",""AbCd"",[1 2])", msg);
index ebc5e87..26e4050 100644 (file)
@@ -1,13 +1,14 @@
-// =============================================================================
+// ===================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) Scilab Enterprises - 2015-2010 - Juergen Koch <juergen.koch@hs-esslingen.de>
+// Copyright (C) 2010-2015 - Scilab Enterprises - Juergen Koch <juergen.koch@hs-esslingen.de>
+// Copyright (C) 2018-2020 - Samuel GOUGEON
 //
 // This file is distributed under the same license as the Scilab package.
-// =============================================================================
+// ===================================================================
 
 // <-- TEST WITH GRAPHIC -->
 // <-- NO CHECK REF -->
-
+// <-- ENGLISH IMPOSED -->
 //
 // Test data
 t = 1:200;
@@ -18,7 +19,7 @@ s = linspace(50,1,length(t));
 
 //
 // Test #1 Create 3D scatter plot
-h = scf();
+clf reset
 p = scatter3d(x,y,z);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -29,11 +30,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-set(gca(),"rotation_angles",[60,45]);
-close(h);
 //
 // Test #2 Vary marker size
-h = scf();
+clf reset
 p = scatter3d(x,y,z,s);
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -44,11 +43,9 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-set(gca(),"rotation_angles",[60,45]);
-close(h);
 //
 // Test #3 Vary marker size and color
-h = scf();
+clf reset
 set(gcf(),"color_map",coolcolormap(64));
 p = scatter3d(x,y,z,s,t);
 assert_checkequal(p.line_mode,"off");
@@ -57,11 +54,10 @@ assert_checkequal(p.thickness,1);
 assert_checkequal(p.mark_mode,"on");
 assert_checkequal(p.mark_style,9);
 assert_checkequal(p.mark_size_unit,"point");
-assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
-assert_checkequal(p.mark_foreground,floor((64-1)*(t-min(t))/(max(t)-min(t))+1));
+assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));  //
+assert_checkequal(p.mark_foreground, round((64-1)*(t-min(t))/(max(t)-min(t))+1)); //
 assert_checkequal(p.mark_background,0);
 set(gca(),"rotation_angles",[60,45]);
-close(h);
 
 //
 // Test data
@@ -71,7 +67,7 @@ y = z.*sin(z);
 
 //
 // Test #4 Fill the markers
-h = scf();
+clf reset
 p = scatter3d(x,y,z,"fill");
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -82,11 +78,10 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,2);
-set(gca(),"rotation_angles",[60,45]);
-close(h);
+
 //
 // Test #5 Specify marker symbol
-h = scf();
+clf reset
 p = scatter3d(x,y,z,"*");
 assert_checkequal(p.line_mode,"off");
 assert_checkequal(p.fill_mode,"off");
@@ -97,11 +92,10 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,2);
 assert_checkequal(p.mark_background,0);
-set(gca(),"rotation_angles",[60,45]);
-close(h);
+
 //
 // Test #6 Change marker edge and face color
-h = scf();
+clf reset
 p = scatter3d(x,y,z,...
          "markerEdgeColor","black",...
          "markerFaceColor",[0 .8 .8]);
@@ -114,11 +108,10 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,7);
 assert_checkequal(p.mark_foreground,color("black"));
 assert_checkequal(p.mark_background,color(0,.8*255,.8*255));
-set(gca(),"rotation_angles",[60,45]);
-close(h);
+
 //
 // Test #7 Specify subplot for scatter plot
-h = scf();
+clf reset
 [x,y] = meshgrid(linspace(-2,2,20));
 z = exp(-x.^2-y.^2);
 subplot(2,1,1);
@@ -132,7 +125,7 @@ assert_checkequal(p1.mark_size_unit,"point");
 assert_checkequal(p1.mark_size,7);
 assert_checkequal(p1.mark_foreground,2);
 assert_checkequal(p1.mark_background,0);
-set(gca(),"rotation_angles",[60,45]);
+
 subplot(2,1,2);
 p2 = scatter3d(gca(),x(:),y(:),z(:),"markerFaceColor",[0 .8 .8]);
 assert_checkequal(p2.line_mode,"off");
@@ -144,8 +137,6 @@ assert_checkequal(p2.mark_size_unit,"point");
 assert_checkequal(p2.mark_size,7);
 assert_checkequal(p2.mark_foreground,2);
 assert_checkequal(p2.mark_background,color(0,.8*255,.8*255));
-set(gca(),"rotation_angles",[60,45]);
-close(h);
 
 //
 // Test data
@@ -157,7 +148,7 @@ s = linspace(50,1,length(t));
 
 //
 // Test #8 Modify scatter plot after creation
-h = scf();
+clf reset
 p = scatter3d(x,y,z,s);
 p.mark_foreground = addcolor([0.5 0 0]);
 p.mark_background = addcolor([0.5 0.5 0]);
@@ -170,5 +161,85 @@ assert_checkequal(p.mark_size_unit,"point");
 assert_checkequal(p.mark_size,ceil(sqrt(4*s/%pi)));
 assert_checkequal(p.mark_foreground,color(0.5*255,0,0));
 assert_checkequal(p.mark_background,color(0.5*255,0.5*255,0));
-set(gca(),"rotation_angles",[60,45]);
-close(h);
+
+
+// ==============
+// Error messages
+// ==============
+msg = "scatter3d: Wrong number of input arguments: At least 3 expected.";
+assert_checkerror("scatter3d(1,2)", msg);
+msg = "scatter3d: Wrong number of input arguments: At least 4 expected.";
+assert_checkerror("scatter3d(gca(),1,2)", msg);
+msg = "scatter3d: Argument #1: Wrong type of graphic handle: ''Axes'' expected.";
+assert_checkerror("scatter3d(gcf(),1,2,3)", msg);
+msg = "scatter3d: Argument #1: Decimal number(s) expected.";
+assert_checkerror("scatter3d(int8(1),2,3)", msg);
+assert_checkerror("scatter3d(1+%i,2,3)", msg);
+msg = "scatter3d: Argument #2: Decimal number(s) expected.";
+assert_checkerror("scatter3d(1,int8(2),3)", msg);
+assert_checkerror("scatter3d(1,2-%i,3)", msg);
+msg = "scatter3d: Arguments #1 and #2: Same numbers of elements expected.";
+assert_checkerror("scatter3d(1,[2 3],3)", msg);
+msg = "scatter3d: Argument #3: Decimal number(s) expected.";
+assert_checkerror("scatter3d(1,2,int8(3))", msg);
+assert_checkerror("scatter3d(1,2,%i)", msg);
+assert_checkerror("scatter3d(1,2,%z)", msg);
+msg = "scatter3d: Arguments #1 and #3: Same numbers of elements expected.";
+assert_checkerror("scatter3d(1, 2, [2 3])", msg);
+
+msg = "scatter3d: Argument #4: Decimal number(s) expected.";
+assert_checkerror("scatter3d(1,2,3,%i)", msg);
+
+// ==========
+// Properties
+// ==========
+// Accepted / forbidden syntaxes or values
+// ---------------------------------------
+// Marks styles (case insensitive)
+prop = ["marker" "MarKeR" "markerstyle"  "MARKSTYLE"];
+markersT = ["." "+" "x" "o" "o+" "circle plus" "d" "fd" "filled diamond" ..
+"d+" "diamond plus" "^" "v" ">" "<" "*" "*5" "p" "pentagram" "s" "square"];
+    // Markers Numerical codes styles (available)
+markersN = [ 0   1   2   9   3        3         5   4         4 ..
+  8       8          6   7   12  13  10  14  14      14      11    11];
+x = rand(1,20);
+y = rand(1,20);
+z = rand(1,20);
+for p = prop
+    for v = markersT
+        assert_checkequal(execstr("clf, scatter3d(x,y,z,p,v);", "errcatch"), 0);
+        sleep(50)
+    end
+    for v = unique(markersN)
+        assert_checkequal(execstr("clf, scatter3d(x,y,z,p,v);", "errcatch"), 0);
+        sleep(50)
+    end
+end
+msg = "scatter3d: Argument #5: Wrong marker specification.";
+assert_checkerror("scatter3d(1,2,3,""marker"",""ab"")", msg);
+assert_checkerror("scatter3d(1,2,3,""marker"", 20)", msg);
+msg = "scatter3d: Argument #5: Scalar (1 element) expected.";
+assert_checkerror("scatter3d(1,2,3,""marker"",[1 2])", msg);
+
+msg = "scatter3d: Argument #5: Scalar (1 element) expected.";
+assert_checkerror("scatter3d(1,2,3,""linewidth"",[1 2])", msg);
+assert_checkerror("scatter3d(1,2,3,""thickness"",[1 2])", msg);
+msg = "scatter3d: Argument #5: Non-negative integers expected.";
+assert_checkerror("scatter3d(1,2,3,""linewidth"", -1)", msg);
+assert_checkerror("scatter3d(1,2,3,""thickness"", -1)", msg);
+assert_checkerror("scatter3d(1,2,3,""linewidth"", %i)", msg);
+assert_checkerror("scatter3d(1,2,3,""thickness"", %i)", msg);
+assert_checkerror("scatter3d(1,2,3,""linewidth"", %z)", msg);
+assert_checkerror("scatter3d(1,2,3,""thickness"", %z)", msg);
+
+prop = ["markeredgecolor" "markerforeground" ..
+        "markerfacecolor" "markerbackground"];
+for p = prop
+    assert_checkequal(execstr("clf, scatter3d(1,2,3, p,""orange"")", "errcatch"),0);
+    assert_checkequal(execstr("clf, scatter3d(1,2,3, p,""#00FF00"")", "errcatch"),0);
+    assert_checkequal(execstr("clf, scatter3d(1,2,3, p, color(""red""))", "errcatch"),0);
+end
+msg = "scatter3d: Argument #4: Value missing for the given property.";
+assert_checkerror("scatter3d(1,2,3,""marker"")", msg);
+msg = "scatter3d: Argument #4: Wrong value. Please check allowed syntaxes and values.";
+assert_checkerror("scatter3d(1,2,3,""orange"",""AbCd"",[1 2])", msg);
index b1206bc..23bd37b 100644 (file)
@@ -1029,20 +1029,20 @@ scatter3_6.png=1208c36176ce151609a9e8a028e2efec
 scatter3_7.png=7b4166df26aa032d619e763b5e3d5ffb
 scatter3_8.png=78c1739441d452b32803d9afe828b9a0
 scatter3_9.png=19492ab5f75f0fb62c39fcff53985cca
-scatter3d_1.png=773a66a41a14bbf889268db7a844147b
-scatter3d_2.png=d9e4519a4d98e2eb8645e0537dbc19e8
-scatter3d_3.png=24be254e2671c45fda9e40ed4b041288
-scatter3d_4.png=f8e9ae6d215b75563d29ff932023fbc4
+scatter3d_1.png=cbbdea1f404044cfe78f1117b80de4a4
+scatter3d_2.png=21d465cbdd78f8f77340374be02c90ee
+scatter3d_3.png=a9ba1468450ff0ffc2e2fd8d6431f8b7
+scatter3d_4.png=28d8d38163017d090d297fb2e4db5729
 scatter3d_5.png=19ee44a74c0965e982ad68330c679ca0
 scatter3d_6.png=108bf9fbffe8fb6027a5a8e4aa50c50b
 scatter3d_7.png=0972a23cc58462fbf97d7d77d1113b98
 scatter3d_8.png=4d67a4e5eafdfbe53b1ca3c6390f6c0f
 scatter3d_9.png=9fbc405d1cafead8558db57db93e0f9d
-scatter_1.png=4f9bcfe033f3f679978a95d46a1d1668
-scatter_2.png=237636079259daa7a0193f047c9b36f7
-scatter_3.png=f76e8578dcbe18c3b40ed66382632f10
-scatter_4.png=671bbf57009b525a69d0584db6bf9b36
-scatter_5.png=8851ea383bf3c8fbb108599bca6e29da
+scatter_1.png=58444c8064eb8a1e525b5f86ff1a752f
+scatter_2.png=83266e7cf79dd2348cc156f758034c30
+scatter_3.png=69656bd429e50cb1f1e8fb215f96a89e
+scatter_4.png=bc8b9d73f5a7ee31f4350b557ec2b740
+scatter_5.png=79aeb185f9626209bd196b3d7753d650
 scatter_6.png=38ce1594a221f1817c355adcf1e35cf5
 scatter_7.png=9e2bdcf2579bbbc0515268dcc7ebd4d1
 scatter_8.png=b7a40a8bbd7cf29b62b771e3be59b988
index 53694d4..0613a89 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter3d_1.png and b/scilab/modules/helptools/images/scatter3d_1.png differ
index 40b1d7b..539473d 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter3d_2.png and b/scilab/modules/helptools/images/scatter3d_2.png differ
index 02c912b..0522263 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter3d_3.png and b/scilab/modules/helptools/images/scatter3d_3.png differ
index 6a78e33..3988725 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter3d_4.png and b/scilab/modules/helptools/images/scatter3d_4.png differ
diff --git a/scilab/modules/helptools/images/scatter3d_5.png b/scilab/modules/helptools/images/scatter3d_5.png
deleted file mode 100644 (file)
index f211da4..0000000
Binary files a/scilab/modules/helptools/images/scatter3d_5.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter3d_6.png b/scilab/modules/helptools/images/scatter3d_6.png
deleted file mode 100644 (file)
index 4527fdf..0000000
Binary files a/scilab/modules/helptools/images/scatter3d_6.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter3d_7.png b/scilab/modules/helptools/images/scatter3d_7.png
deleted file mode 100644 (file)
index fd33f72..0000000
Binary files a/scilab/modules/helptools/images/scatter3d_7.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter3d_8.png b/scilab/modules/helptools/images/scatter3d_8.png
deleted file mode 100644 (file)
index 40b1d7b..0000000
Binary files a/scilab/modules/helptools/images/scatter3d_8.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter3d_9.png b/scilab/modules/helptools/images/scatter3d_9.png
deleted file mode 100644 (file)
index bf25210..0000000
Binary files a/scilab/modules/helptools/images/scatter3d_9.png and /dev/null differ
index f50dfac..61e505f 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter_1.png and b/scilab/modules/helptools/images/scatter_1.png differ
index 4a926a1..8e7abef 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter_2.png and b/scilab/modules/helptools/images/scatter_2.png differ
index da0feca..bb80aa4 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter_3.png and b/scilab/modules/helptools/images/scatter_3.png differ
index 8c70a21..96bf0c7 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter_4.png and b/scilab/modules/helptools/images/scatter_4.png differ
index ffe493d..fcb4710 100644 (file)
Binary files a/scilab/modules/helptools/images/scatter_5.png and b/scilab/modules/helptools/images/scatter_5.png differ
diff --git a/scilab/modules/helptools/images/scatter_6.png b/scilab/modules/helptools/images/scatter_6.png
deleted file mode 100644 (file)
index c4f4b3c..0000000
Binary files a/scilab/modules/helptools/images/scatter_6.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter_7.png b/scilab/modules/helptools/images/scatter_7.png
deleted file mode 100644 (file)
index 78d0f56..0000000
Binary files a/scilab/modules/helptools/images/scatter_7.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter_8.png b/scilab/modules/helptools/images/scatter_8.png
deleted file mode 100644 (file)
index 04d7014..0000000
Binary files a/scilab/modules/helptools/images/scatter_8.png and /dev/null differ
diff --git a/scilab/modules/helptools/images/scatter_9.png b/scilab/modules/helptools/images/scatter_9.png
deleted file mode 100644 (file)
index 45e0369..0000000
Binary files a/scilab/modules/helptools/images/scatter_9.png and /dev/null differ