\documentclass[11pt,psfig,preprint]{aastex}
%\documentstyle[11pt,psfig,aaspp4]{article} 
\begin{document} 

\title{\bf ONE, TWO, AND THREE DIMENSIONAL COLOR IMAGES \\ \today}

\author{Carl Heiles}

\tableofcontents

	Before reading this, look at {\it BIDIDL}.  This discusses the
basics of image display. 

	This handout discusses the use of color in representing arrays
of data.  Normally we think of image display as just that---a way to
display an image.  However, you can combine more information into a
single image by the combined use of color and intensity.  Using color
for these purposes is great, but using it intelligently is not trivial. 
There are three basic uses for color, and below we discuss each in the
correspondingly-numbered section:

	{\bf (1)} Using a color table to represent a single quantity. 
Consider this as a {\it one-dimensional} mapping of the quantity into
color.  The most common example is the ordinary greyscale image, in
which the degree of whiteness or blackness represents the value of the
quantity represented in the image (such as light intensity).  Many
astronomers like to replace the simple greyscale with a colorscale
because it's easier to discern changes of color than small changes of
brightness.  However, this has its problems: firstly, 20\% of the human
population is at least partly colorblind; secondly, color reproductions
in printed journals are very expensive. 

	{\bf (2)} Using {\it color} to represent the value of a single
quantity, such as the mean velocity of a spectral line, and using the
{\it lightness} (brightness of the color: black is zero, full brightness
is maximum lightness) to represent a different quantity, such as
intensity of the spectral line.  You are using two visually orthogonal
qualities---color and lightness---to repesent two quantities, so this is
a {\it two-dimensional} mapping onto the image plane.  Here, one uses a
color table to represent one variable, as one sometimes does in
one-dimensional mapping, plus the addition of the change in lightness to
represent the second variable. 

	{\bf (3)} Using color to represent the values of three independent
quantities, with the lightness of each color proportional to its
quantity.  For example, using red for IR, green for optical, blue for
X-ray. This is a {\it three-dimensional} mapping onto the image plane.
You can't represent more than three dimensions in a color image because
the eye is responsive to only three independent colors.

	Finally, there are some related matters such as overplotting
onto images and calibration; we discuss these in later sections.


\section{A PRELIMINARY: DYNAMIC VERSUS STATIS COLORTABLES}

	Modern computers work in 24-bit color mode, meaning that each of
the three colors (R, G, B) can have 256 values and they are all
independent.  This means the total number of colors is $256^3$
(``millions of colors'').  With 24 bit colors there are two flavors, {\it
Truecolor} and {\it Directcolor}.  We discuss these color modes more
extensively in {\it BIDIDL}. 

	Truecolor doesn't have dynamic color tables.  This means that it
is impossible to interactively change the contrast of an image using the
cursor. Without this interactive behavior it is very difficult to
optimally tune
the image contrast.  If you run IDL
under (God Forbid!) Windows or Mac OSX, you'll find that Truecolor is
the only mode you've got. 

	Linux and Unix users can invoke Directcolor, which does have
dynamic color tables---one for each color.  In IDL, we Linux users
invoke \verb$ct_fiddle$) to interactively tune the image contrast and
color balance.  If you are dealing with images and don't run Linux, you
might want to persuade one of your Linux buddies to give up her machine
for image processing work. 

	Our startup file forces you to choose among various color modes.
If you don't use ours, you need to specify the mode before plotting
anything. For example, if you want to invoke Truecolor, then the first
thing you type in IDL should be

\noindent {\bf device, true\_color=24}

\noindent If you now type {\bf help, /device}, the display will tell you
that the Translation table is bypassed.  You have a full 256 levels of
intensity for each of the three colors; each color is represented by a
24-bit number. If instead you want a 256-color specification, called a
color table, type

\begin{verbatim}
device, decomposed=0
\end{verbatim}

\noindent You can do this at any time. You can convert back to the
$256^3$ method by typing \verb$device, /decomposed$.

\section{ONE-DIMENSIONAL COLOR: THE 8-BIT COLOR TABLE}

\subsection {The Basic Idea}

	{\it Never forget} that the idea is to turn the data array into
an image that convey informations to the brain.  The idea is {\it not}
to be so strictly quantitative that details of interest are obscured. 

	You want to bring out details of interest.  For example, for
many images of the interstellar gas you want to emphasize weak structues
at the expense of the fidelity gained by a strict proportionality
between image brightness and data value.  To this end, choose a color
table and experiment with the image transfer function, using the
techniques discussed in {\it BIDIDL}.  At minimum, this involves
changing the span of the data valuies represented in the image and
raising the data values within that span to a power: a power less than
unity to emphasize weak features, larger than unity for strong ones. 
Using \verb$ct_fiddle$ makes this easy on direct color displays, which
have a dynamic color table; with the static color displays it's more
cumbersome. 

		Once you find the combination of stretch and gamma that makes
the image look good, we advise that you apply these to the {\it data}
and produce an image using stretch $0 \rightarrow 255$ and $gamma=1$. 
That way you will know for sure that your PS file will look very much
like what you have on the screen.  To generate PostScript files with
nice annotations and fonts, use the procedures in our other memos. 

\subsection{Considerations in Choosing a Color Table}

	For publication in journals, a greyscale color table is usually
best because color reproductions are very expensive.  However, for other
purposes, such as lecture slides, a color table is often preferred
because you can see more details. 

	I have, myself, not yet come upon the ideal color table. The
ideal color table would: \begin{enumerate}

	\item Have a monotonically and smoothly changing color with
intensity value.

	\item Have no visual ambiguity: a non-colorblind person would
never suffer any ambiguity about the relationship between color and
intensity.

	\item Have the most intense portions of the image be
represented by the physiologically brightest color in the colortable.

	\item Have the least intense portions of the image {\it not} be
represented by the physiologically dimmest color (which is blue),
because it will not clearly show weak features against the black
background of zero intensity.  \end{enumerate}

	Colortables in common use do not satisfy all these conditions. 
For example, the very popular colortable used by the VLA's AIPS uses red
for the most intense parts of the image; the physiologically brighter
white represents a lower intensity level.  Many other colortables that
people use are simply awful when considered from a logical perspective. 

	In my opinion, IDL provides four colortables that approach the
ideal.  Their names and numbers are: Hue Sat Lightness 1 and 2 (numbers
19 and 20); Hue Sat Value 1 and 2 (numbers 21 and 22).  (For both of
these, number 2 needs to be reversed because white is at the
low-intensity end of the range).  It also provides another colortable
which doesn't satisfy these criteria very well but its colors are so
striking that it is psycologically quite appealing (to me, at any rate);
it's Standard Gamma II (number 5).  You can load these colortables
either from \verb$xloadct$ or (preferably) using the IDL command
\verb$loadct, nr$ (where \verb$nr$ is the number of the colortable given
above). You can also make any colortable you choose and load it with
\verb$tvlct$; see \S \ref{oned}. 

\subsection{The Colorbar}

	There's nothing more annoying than seeing a nice one-dimensional
image without an indication of how the greyscale or color relates to
data value. You do this with a colorbar. Shame on you for even {\it
thinking} of generating a 1-d image without a colorbar! See \S
\ref{colorbar}.



\section{TWO-DIMENSIONAL COLOR: AN 8-BIT COLOR TABLE WITH 24-BIT COLOR}

\begin{figure}[h!]
\begin{center}
\includegraphics[scale=.7]{allvelrjrlog.ps}
\end{center}
\caption{Example of a two-dimensional color image in which red, green,
and blue represent different datasets. Obviously (we hope!), this image
makes little sense with a black/white printer! \label{allvelrjr}}
\end{figure}

	Here, the idea is to use color to represent the value of a
single quantity, such as the mean velocity of a spectral line, and use
the lightness (apparent brightness of the color: black is zero, full
brightness is maximum lightness) to represent a different quantity, such
as the integrated intensity of the spectral line.  This is a {\it
two-dimensional} mapping onto the image plane.  Figure \ref{allvelrjr}
shows an example. The image is H$\alpha$ data from
the WHAM survey; color represents mean velocity, lightness represents
the logarithm of the line brightness. 

	The goal is to take two images, one of velocity and one of
integrated brightness, and combine them into a single image in which
color represnts one image and intensity the other. Let's call these two
images \verb$velimg$ (units are km/s) and \verb$brtimg$ (units are
K-km/s).

\subsection{Choosing a color table for the first dimension} \label{oned}

	Suppose you are representing the mean velocity of a spectral line by
color. To do this, you should generate a 256 entry color table in which
each color represents velocity. You might think that a natural choice
would be the spectrum, from red to blue, representing positive to
negative velocities. 

	However, this is an exceedingly poor choice because you wish to
have a second dimension, namely to represent the line intensity by the
color's {\it lightness}, which is apparent brightness of the color.  And
the human visual system has a very low sensitivity to blue light. 
Therefore, the brain will perceive all negative velocities, represented
by blue, as less intense than the corresponding positive velocities,
even though the line intensities are the same or larger. 

	In other words, you need to account for human physiology in the
choice of the color table.  There has been lots of research on this
topic and IDL provides three procedures that are tailored to meet these
needs; see IDL's {\bf ?pseudo} help.  Tim Robishaw and I have found that
a slight revision to this pure concept (namely, removing a bit of red
to make more green) gives a very good colortable.  The idl commands
are:

\begin{verbatim}
pseudo, 100, 100, 100, 100, 22.5, 0.68, colr
colr[*,0]= bytscl( colr[*,0], min=100,max=255)
r_orig = colr[*,0] & g_orig = colr[*,1] & b_orig=colr[*,2]
r_curr = r_orig & g_curr = g_orig & b_curr = b_orig
tvlct,r_orig,g_orig,b_orig
\end{verbatim}

\noindent The {\bf pseudo} procedure creates a color table (here called
\verb$colr$) based on {\it lightness} (apparent brightness), {\it
saturation} (degree of color purity: more white mixed in means a less
pure color, one that looks more nearly pastel), and hue (color).  {\bf
pseudo} loads the color table, firstly into the 2-d integer array {\it
colr[256,3]} (values range from 0 to 255); and secondly into the color
table of IDL's {\it colors} common block \verb$(r_curr, g_curr, b_curr)$
and \verb$(r_orig, g_orig, b_orig)$.  We modify \verb$colr$ a bit and
then reload it into IDL, as \verb$pseudo$ did, first by redefining
\verb$r_orig$, \verb$r_curr$, and the corresponding green and blue
variables, and then using \verb$tvlct$. 

	This color table runs from red to yellow to green to pale blue
to magenta.  The array {\it colr} has 256 elements in its first
dimension, corresponding to 256 velocities.  The second dimension
contains three elements, corresponding to the three colors red, green,
blue.  Suppose, for example, that in a particular pixel the velocity is
such that this first index is 86.  Then {\it colr[86,0]} is the
intensity of red, {\it colr[86,1]} that of green, and {\it colr[86,2]}
that of blue for that particular velocity.  The velocity 86, being about
$1 \over 3$ the way from magenta to red, corresponds to roughly pale
blue.  These colors all appear to be roughly the same intensity to the
average human. 

\subsection{ Generating the color image}

	Having defined the color table, generating the color image is
easy if you have the image of velocities; the velocities range between
two extremes. The velocities of interest have a smaller extent, from
\verb$vmin$ to \verb$vmax$. You need to make this range correspond to
the range of color indices, 0 to 255. You accomplish this with the
\verb$bytscl$ function:

\begin{verbatim} 
colimg= bytscl( velimg, min=vmin, max=vmax) 
\end{verbatim}

\noindent Note: a common mistake is to make \verb$vmin$ and \verb$vmax$
too far apart, so you're not gaining the full range of colors on the
image. Be sure to experiment with these values!

	If the line brightness were everywhere the same, equal to its
maximum value, the three RGB images would be

\begin{verbatim}
redimg= colr[ colimg, 0]
grnimg= colr[ colimg, 1]
bluimg= colr[ colimg, 2]
\end{verbatim}

\noindent One more thing: colimg is 2d while 
\verb$(redimg, grnimg, bluimg)$ will (probably) be 1d. 
You might need to reform them to 2d. For
example, if the original dimensions of colimg are $480 \times 240$,
you'd do

\begin{verbatim}
redimg= reform( redimg, 480, 240)
\end{verbatim}

\noindent etc.

\subsection{Changing the lightness for the second dimension}

	For any pixel, the color is given by the mixture of red, green,
and blue specified by \verb$(redimg, grnimg, bluimg)$. We add the line
brightness information by intensity-scaling the three color images
appropriately. The line-brightness array is \verb$brtimg$; the
brightness lies between two extremes. Suppose that we wish to display a
narrower range within these extremes bounded by  \verb$bmin$ and
\verb$bmax$, and that we want to apply a contrast power-law
\verb$gamma$. Then define the new integrated-intensity image as

\begin{verbatim}
newimg = ( ( ((brtimg - bmin)/(bmax - bmin)) > 0. < 1. )^gamma) ,
\end{verbatim} 

\noindent which is a float array lying between 0 and 1. We need to
generate the three R,G,B images by scaling 
\verb$(redimg, grnimg, bluimg)$ all by the same factor for each pixel. 
We accomplish this by

\begin{verbatim}
r_img= byte ( (round( newimg * redimg ) > 0 < 255))
g_img= byte ( (round( newimg * grnimg ) > 0 < 255))
b_img= byte ( (round( newimg * bluimg ) > 0 < 255)) ,
\end{verbatim}

\noindent The portions \verb$ > 0 < 255$ are not necessary in principle,
but we add them just to make sure roundoff error doesn't produce values
outside the allowable range for bytes. 


\subsection{Writing the image to the display}

	You write the image to the display using {\bf tv} ({\it not}
{\bf tvscl}: you want to preserve brightness ratios!).  You have to write
three images, one for each color. 

	For the screen there are two ways to do this.  You can use the
convenient form, which works {\it only for X}

\begin{verbatim}
tv, r_img, channel=1
tv, g_img, channel=2
tv, b_img, channel=3
\end{verbatim}

\noindent The other way, which works on both X and PostScript, is

\begin{verbatim}
tv, [[[r_img]], [[g_img]], [[b_img]]], /normal, true=3, 
        ybotm, xbarleft, ysize=xbarsize, xsize=yplotsize}
\end{verbatim}

\noindent where on the second line we've included some extra keywords to
position and size the image; you should look at the documentation for
\verb$tv$. The \verb$normal$ means that positions are specified in
normalized coordinates, which is always a good idea when you will end up
making a PostScript file; see {\it Making, Printing, and Powerpointing
Postscript Files of Graphs and Images}.

\subsection{Experimenting with adjusting the image parameters}

	The colors span a range of line velocity, and you need to choose
this range.  Similarly, the lightnesses span a range of line intensity,
and you need to choose this properly and, in addition, possibly need to
change the contrast (the ``gamma factor'').  To do this perfectly in
this two-dimensional color mode, you need to change the parameters and
rewrite the image to the screen.  An easy way to do it roughly is with
\verb$ct_fiddle$; it operates on all three colors identically, which
isn't exactly what you want, but it's not bad.  If you want to do it
perfectly, then you need to write some software that allows you to use
the cursor to interactively change the ranges while you look at the
image so that you can judge what ranges are best.  I have some
poorly-documented software that I might be willing to share with you if
you bribe me with a nice enough treat. 

\section{THREE-DIMENSIONAL COLOR: WITH 24-BIT COLOR}

\begin{figure}[h!]
\begin{center}
\includegraphics[scale=.7]{itp1.ps}
\end{center}
\caption{Example of a three-dimensional color image in which red, green,
and blue represent different datasets. Obviously (we hope!), this image
makes little sense with a black/white printer! \label{itp1}}
\end{figure}

	Here you want to represent three independent quantities by three
independent, orthogonal-to-the-eye colors.  Figure \ref{itp1}
shows an example. Red represents the H$\alpha$ line intensity, green the
21-cm line intensity, and blue the XM band X-ray intensity.

	You can use two color schemes.  One is the obvious red, green,
blue; these correspond directly to the three cones of sensitivity in the
eye.  Alternatively, you can use their complements: cyan, magenta, and
yellow.  Recall that $white=(red+blue+green)$, so you can generate a
second set of eye-orthogonal colors as $cyan=(green+blue)$,
$magenta=(red+blue)$, $yellow=(red+green)$.  The former scheme is
susceptible to the poor blue-sensitivity of the human visual system, but
sometimes this is an advantage when one of the images is less important. 
Experiment for each individual case!

\subsection{Directcolor and {\it ct\_fiddle}: adjusting the image parameters}

	This is the ideal application for {\it Directcolor}.  In
Directcolor, each color has its own colortable and you can manipulate
them independently using Tim Robishaw's procedure \verb$ct_fiddle$.
Therefore, you can independently change one image relative to the others
and achieve the best balance.  If your machine doesn't have Directcolor
and you are doing three-dimensional color, you'll save lots of time by
going to a different machine that has Directcolor. 

	\verb$ct_fiddle$ can work on any combination of colors.  For example,
to change the red image alone, type \verb$ct_fiddle, 'r'$; to change the
cyan ({\it green + blue}) image, type \verb$ct_fiddle, 'gb'$; to change all three, type either
\verb$ct_fiddle, 'rgb'$ or just \verb$ct_fiddle$ (because all three colors is
the default). 

	In Directcolor, IDL takes control over all of the colortables.
In other words, IDL forces a private colortable. This means you'll get
the ``flashing'' when the cursor moves on and off of IDL's display
windows; see {\it BIDIDL}.

\section{COLORBARS} \label{colorbar}

	The first thing you learned in kindergarten should have been:
``When you make a plot, label and quantify the axes''.  What are the
scientific images we've been discussing except plots of one, two, or
three variables---except that the plots are in 2-d space.  And the first
thing you learned in kindergarten {\it still applies}.  This means that
you need to quantify the meaning of the intensity, or colors.  You do
this with a {\it colorbar}. 

	There is nothing more infuriating than an image in a so-called
scientific journal whose intensities or colors are not quantified. 

	You do this calibration with a colorbar, which is a bar along
which the color, or intensity, changes from one extreme to the other;
labels quantify the colors.  You can make your own colorbar using {\bf
tv} with the {\bf X, Y} arguments to position the subwindow and the {\bf
xsize, ysize} keywords to set its size (except that, on the X window,
the size is set by defining the number of pixels in the array displayed
by {\bf tv}).  See, for example, Fanning page 234, or the {\it colorbar}
procedure in his website {\it http://www.dfanning.com/}. Note that his
\verb$colorbar$ is completely different from ours in \S \ref{homegrown}. 

	The above colorbars are fine for one-dimensional color. For
two-dimensional color, you need to also include a change in intensity in
the orthogonal direction. For this, you need to make your own. Our \verb$colorbar$ procedure
will do this. It is documented, but not very well; it's a work in
progress. Experiment! And if you need to, ask!

	Three-dimensional color needs more than a single colorbar, which
can represent only two dimensions.  I have attacked this with the scheme
shown in our example Figure \ref{itp1}.  Here, a
bar across the top of the image is divided into eight squares.  The
three leftmost squares give the characteristic curves for red, green,
and blue, and are labeled with the quantity depicted.  The five
rightmost squares exhibit how the colors mix when combined.  In each
square, blue has a different intensity, constant within the whole
square, running from 0, 0.25 \dots 1.0 of full intensity.  Within each
square, red is zero at the left and maximum at the right; green is zero
at the bottom and maximum at the top.  So the top right corner of each
of these five squares is full red and green: the first square, with no
blue, shows yellow and the last, with full blue, white. Try our
not-well-documented procedure \verb$rgbimg.pro$; if you need to, ask!

\section{ EXISTING HOME-GROWN IDL PROCEDURES} \label{homegrown}

	We have some home-grown IDL procedures for these three types of
images. They are not well documented, but the work. They are still under
development. You can find them in \verb$~heiles/idl/gen/image$ and they
include the following:

\begin{verbatim}
colorbar.pro -- generates a colorbar for 2d images 
display.pro -- generates a 1-d image with some annotation. for 
	documentation, see the comments under 'pro display'
display2par.pro -- 2d image generation with some annotation
dsply2d.pro -- a slightly modified version of display2par.pro. dsply2d
        is probably preferable.
rgbimg.pro -- 3d image generation with some annotation
\end{verbatim}

\section{MORE}

\subsection{Overplotting a coordinate grid}

	Often you wish to annotate or overplot an image, for example to
make a coordinate grid or place a point to label an object.  Our memo
{\it Making Annotated Images} tells how to do this. 

	But there's a wrinkle: if the labels of the plot extend outside
the image, then you have to be careful with the labels' colors: on the
screen they are written on the screen's {\it black background}, but on
the ps device they are written on a {\it white background}. 

	Let's reiterate that point. The default background for X is
black, while that for PS is white. When you are making a pretty picture
to publish, you might find it useful to give the X window a white
background so that it looks like the PS background. You can do this
(assuming you want white) either with

\begin{verbatim}
bgfill, !white
\end{verbatim}

	After you make your image overplotted with a plotting grid, you
can use {\bf plots} to plot a single symbol somewhere or {\bf xyouts} to
write a label.  However, when you use these you should use either {\it
data} or {\it normalized} coordinates, not {\it device} coordinates,
because if you use the same code to generate a PostScript file the
device coordinates are meaningless. 

	For more details see {\it Making Annotated Images}.

\subsection{Annotating with color in truecolor and directcolor}

	When you annotate, for example with the {\bf plot} or {\bf
xyouts} commands, you can make colored characters and plot colored lines
 using the {\bf color} keyword. {\bf Unfortunately, the definition of
color for vector graphics (characters, coordinate axes) differs greatly
between X and PS}.

	{\bf IMPORTANT:} You can deal with this definition issue the
hard way, by reading what's below, or the easy way.  The easy, seamless
way\footnote{Thanks to Tim Robishaw!!}: use the combination
\verb$psopen$ and \verb$setcolors, /system_variables$ as discussed in
our handouts {\it Making Annotated Images} and {\it Making, Printing,
and PowerPointing PostScript Files of Graphs and Images}. 

	If you insist on doing it yourself, read on. If you use our
\verb$psopen$, skip the rest of this section.


\subsubsection{Annotating with color in X}

	In 24-bit color X, the color is specified by a 24-bit (3-byte)
word.  This is true both for the image and for characters written by,
say, {\bf xyouts}.  The least significant byte is red, the next one
green, and the most significant blue.  Thus, pure red is 255; pure green
is 255*256; pure blue is 255*256*256.  White is $red+green+blue$,
magenta is $red+blue$, etc.  So if you want to annotate with green
letters centered at data coordinates (5,6) you type 

\begin{verbatim}
xyouts, 5, 6, 'This is written as green', color=!green, /data, align=0.5
\end{verbatim}

where ${\bf green} = 255*256$.

\subsubsection{Annotating with color in PS}

	Unfortunately, PS uses a different scheme. In PS you {\it must}
specify the color of {\it text} with a {\it colortable}, whose length is
limited to 256 elements. This is, of course, completely different from
the way colored {\it images} are written. Here's a simple example of
such a colortable that consists of just five colors: black, red, green,
blue, and white. This is a 5-element colortable; you can have as many as
256.

	First, generate the red, green, and blue intensities of the 5
colors:
\begin{verbatim}
red = 255 * [0, 1, 0, 0, 1]
grn = 255 * [0, 0, 1, 0, 1]
blu = 255 * [0, 0, 0, 1, 1]
\end{verbatim}

\noindent which correspond to the colors black, red, green, blue, white.

\noindent and then load them into IDL's internal color tables
\begin{verbatim}
tvlct, red, grn, blu
\end{verbatim}
	
	Now you're ready to roll! You'd annotate with green characters
using {\bf xyouts, 5, 6, 'This is written as green!!', color=2, /data}. 

	This necessity to use different color schemes in X and PS is a
royal pain.{\footnote{Two exclamation points are required after
``green'' because one exclamation point promps IDL for a font change.} 

\subsection{Making PostScript files}

	See {\it Making, Printing, and Powerpointing 
Postscript Files of Graphs and Images}.

	For pseudocolor and directcolor follow this, the voice of
experience.  In principle, you can apply a colortable to the
three-dimensional color images using \verb$ct_fiddle$ and then this
colortable could apply to the ps image as well.  But I don't recommend
this technique.  Rather, write a {\it new byte array} that is based on
the parameters you obtain from \verb$ct_fiddle$ and display it with a linear
color table---equivalent to using Truecolor.  Then there is absolutely
no possibility for screwup when transferring the data to PostScript. 
X-windows and PostScript seem to work a bit differently, in my
experience, and I've never understood why. 
	
\acknowledgements It is a pleasure to thank Tim Robishaw for
teaching me a lot, providing software, and constructive comments.

\enddocument
\end



