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 utilizes two color maps which can be used interchangeably. However, 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.

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 hexidecimal notation with the 3 bytes concatanated 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 pallette 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 pallette 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 carefult 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 pallette.

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