Setting Color
Prev | Chapter 3. Advanced Use of PLplot | Next

## Setting Color

Normally, color is used for all drivers and devices that support it within PLplot subject to the condition that the user has the option of globally turning off the color (and subsequently turning it on again if so desired) using `plscolor`.

The PLplot color model allows the user to set the current color from a wide range of colors using two distinct color maps. Color map0 (discussed in the section called “Color Map0”) has discrete colors with no particular order and is most suited to coloring the background, axes, lines, and labels, and color map1 (discussed in the section called “Color Map1”) has continuously changing colors and is most suited to plots (see the section called “Contour and Shade Plots”) in which data values are represented by colors. Setting the background color is a special case that is handled exclusively by color map 0 (as discussed in the section called “Color Map0”). The user can change the current color (as opposed to the background color) at any point in the plot by selecting any of the colors from either color map 0 or 1 using calls to `plcol0` or `plcol1`. When the current color is changed all subsequent drawing actions will utilize the new color until it is changed again.

### Color Map0

Color map0 is most suited to coloring the background, axes, lines, and labels. Generally, the default color map0 palette of 16 colors is used. (`examples/c/x02c.c` illustrates these colors.) The default background color is taken from the index 0 color which is black by default. The default foreground color is red.

There are a number of options for changing the default red on black colors. The user may set the index 0 background color using the command-line `bg` parameter or by calling `plscolbg` (or `plscol0` with a 0 index) before `plinit`. During the course of the plot, the user can change the foreground color as often as desired using `plcol0` to select the index of the desired color.

For more advanced use it is possible to define an arbitrary map0 palette of colors. The user may set the number of colors in the map0 palette using the command-line `ncol0` parameter or by calling `plscmap0n`. `plscol0` sets the RGB value of the given index which must be less than the maximum number of colors (which is set by default, by command line, by `plscmap0n`, or even by `plscmap0`). Alternatively, `plscmap0` sets up the entire map0 color palette. For all these ways of defining the map0 palette any number of colors are allowed in any order, but it is not guaranteed that the individual drivers will actually be able to use more than 16 colors.

### Color Map1

Color map1 is most suited to plots (see the section called “Contour and Shade Plots”) in which data values are represented by colors. The data are scaled to the input map1 range of floating point numbers between 0. and 1. which in turn are mapped (using `plcol1`) to colors using a default or user-specified map1 color transformation. Thus, there are calls to `plcol1` from within the code for `plshade` (see `src/plshade.c`) and `plsurf3d` (see `src/plot3d.c`) to give a continuous range of color corresponding to the data being plotted. In addition `plcol1` can be used to specify the foreground color using the map1 continuous color palette (see the commented out section of `examples/c/x12c.c` which gives an example of this for a histogram), but normally `plcol0` is a better tool for this job (see the section called “Color Map0”) since discrete colors often give a better-looking result.

For more advanced use it is possible to define an arbitrary map1 palette of colors. The user may set the number of colors in this palette using the command-line `ncol1` parameter or by calling `plscmap1n`. Furthermore, `plscmap1l` can be used to set the map1 color palette using linear interpolation between control points specified in either RGB or HLS space.

There is a one-to-one correspondence between RGB and HLS color spaces. RGB space is characterized by three 8-bit unsigned integers corresponding to the intensity of the red, green, and blue colors. Thus, in hexadecimal notation with the 3 bytes concatenated together the RGB values of FF0000, FFFF00, 00FF00, 00FFFF, 0000FF, FF00FF, 000000, and FFFFFF correspond to red, yellow, green, cyan, blue, magenta, black, and white.

HLS (hue, lightness, and saturation) space is often conceptually easier to use than RGB space. One useful way to visualize HLS space is as a volume made up by two cones with their bases joined at the “equator”. A given RGB point corresponds to HLS point somewhere on or inside the double cones, and vice versa. The hue corresponds to the “longitude” of the point with 0, 60, 120, 180, 240, and 300 degrees corresponding to red, yellow, green, cyan, blue, and magenta. The lightness corresponds to the distance along the axis of the figure of a perpendicular dropped from the HLS point to the axis. This values ranges from 0 at the “south pole” to 1 at the “north pole”. The saturation corresponds to the distance of the HLS point from the axis with the on-axis value being 0 and the surface value being 1. Full saturation corresponds to full color while reducing the saturation (moving toward the axis of the HLS figure) mixes more gray into the color until at zero saturation on the axis of the figure you have only shades of gray with the variation of lightness along the axis corresponding to a gray scale.

Here are some C-code fragments which use `plscmap1l` to set the map1 color palette. This first example illustrates how to set up a gray-scale palette using linear interpolation in RGB space.

        i[0] = 0.;
          i[1] = 1.;
          /* RGB are rescaled to the range from 0 to 1. for input to plscmap1l.*/
          r[0] = 0.;
          r[1] = 1.;
          g[0] = 0.;
          g[1] = 1.;
          b[0] = 0.;
          b[1] = 1.;
          plscmap1l(1, 2, i, r, g, b, NULL);

This second example illustrates doing the same thing in HLS space.

        i[0] = 0.;
          i[1] = 1.;
          /* Hue does not matter for zero saturation.*/
          h[0] = 0.;
          h[1] = 0.;
          /* Lightness varies through its full range.*/
          l[0] = 0.;
          l[1] = 1.;
          /* Saturation is zero for a gray scale.*/
          s[0] = 0.;
          s[1] = 0.;
          /* Note the first argument which specifies HLS space.*/
          plscmap1l(0, 2, i, h, l, s, NULL);

This final example using `plscmap1l` illustrates how the default map1 color palette is set with just 4 control points (taken from `src/plctrl.c`).

    /*--------------------------------------------------------------------------*\
          * plcmap1_def()
          *
          * Initializes color map 1.
          *
          * The default initialization uses 4 control points in HLS space, the two
          * inner ones being very close to one of the vertices of the HLS double
          * cone.  The vertex used (black or white) is chosen to be the closer to
          * the background color.  If you don't like these settings you can always
          * initialize it yourself.
          \*--------------------------------------------------------------------------*/

          static void
          plcmap1_def(void)
          {
          PLFLT i[4], h[4], l[4], s[4], vertex = 0.;

          /* Positions of control points */

          i[0] = 0;		/* left boundary */
          i[1] = 0.45;	/* just before center */
          i[2] = 0.55;	/* just after center */
          i[3] = 1;		/* right boundary */

          /* For center control points, pick black or white, whichever is closer to bg */
          /* Be careful to pick just short of top or bottom else hue info is lost */

          if (plsc->cmap0 != NULL)
          vertex = ((float) plsc->cmap0[0].r +
          (float) plsc->cmap0[0].g +
          (float) plsc->cmap0[0].b) / 3. / 255.;

          if (vertex < 0.5)
          vertex = 0.01;
          else
          vertex = 0.99;

          /* Set hue */

          h[0] = 260;		/* low: blue-violet */
          h[1] = 260;		/* only change as we go over vertex */
          h[2] = 0;		/* high: red */
          h[3] = 0;		/* keep fixed */

          /* Set lightness */

          l[0] = 0.5;		/* low */
          l[1] = vertex;	/* bg */
          l[2] = vertex;	/* bg */
          l[3] = 0.5;		/* high */

          /* Set saturation -- keep at maximum */

          s[0] = 1;
          s[1] = 1;
          s[2] = 1;
          s[3] = 1;

          c_plscmap1l(0, 4, i, h, l, s, NULL);
          }

Finally, `plscmap1` is an additional method of setting the map1 color palette directly using RGB space. No interpolation is used with `plscmap1` so it is the programmer's responsibility to make sure that the colors vary smoothly. Here is an example of the method taken from `examples/c/x08c.c` which sets (yet again) the gray-scale color palette.

        for (i=0;i<n_col;i++)
          rr[i] = gg[i] = bb[i] = i*256/n_col;
          plscmap1(rr,gg,bb,n_col);

Prev | Up | Next
Setting the Area Fill Pattern | Home | Setting Character Attributes