\documentclass[preprint]{aastex}
\usepackage{graphicx}

\begin{document}

\title{\bf MAKING ANNOTATED IMAGES (WITH COLORBARS TOO!) \\ \today} 

\author{Carl Heiles and Tim Robishaw}

\tableofcontents


This is the second in our series of four tutorials on images. Before
starting this one you should read our introductory overview on these four
tutorials, which is entitled {\bf FOUR TUTORIALS ON IMAGES: NOVICE
$\rightarrow$ EXPERT}; and also the first in the series, {\bf BIDIDL\dots}.

	It's easy to slap an image on your screen. But annotating it
with coordinates isn't quite so easy.  Suppose you have a single two-d
array and want to make an image (that's one-dimensional color).  The $x$
and $y$ axes have meaningful values and you want the image to
incorporate those on a plot scale.  And perhaps you want to make a
contour plot that overlies the image.  Here's a quick tutorial.

\section{PRODUCING A WINDOW HAVING IMAGE BORDERS AND ROOM FOR A COLORBAR}

	You are writing either to an X window or PostScript file; we
refer to either as the ``window''.  In either case, you need to make the
window larger than the image so that there's room for the annotation
and/or the colorbar.  You usually don't want equal margins on all sides
of an image. This wastes some space because you need to provide margin
space for coordinate labels, which usually appear on only the left and
bottom, so these two margins need to be wider than the right and
top. Also, you might wish to include a colorbar, usually on on the top
or the right-hand side, and that complicates the calculation of
margins.

So your first task is to think about aesthetics and practicality and
decide how much space you want or need for the borders. You then use
IDL to {\it implement} your decision. Here we make
the implementation easier and we also provide a
straightforward way to generate a colorbar in \S \ref{cbar}.

\subsection{Defining Those Margins} \label{posns}

Our procedure \verb$img_cbar_posns$ calculates positional information
given your specification of margin widths. Here, the word ``maargin''
means the white space surrounding the image and, also, the colorbar if
there is one. The inputs are:
\begin{enumerate}

\item \verb$w_left$, the distance from the left-hand edge of the image
  to the left-hand edge of the plotting device, {\it in units of the width of
  the image}. This is the width of the left-hand margin, within which
  labels will go and, also, some blank space around the image. A
  reasonable value is 0.1, which leaves some room for the vertical axis
  labelling. 

\item \verb$w_right$, the width of the right-hand margin. Often you
  don't need room for labelling on the right, so you could use a small
  value like 0.05.

\item \verb$w_bot$, the width of the bottom margin in units of the
  height of the image. A
  reasonable value is 0.1, which leaves some room for the vertical axis
  labelling. 

\item \verb$w_top$, the width of the top margin. Often you don't need
  room for labelling on the top, so you could use a small value like
  0.05.

\item \verb$space$, the distance between the image and the colorbar in
  units of the image size (vertical size for a horizontal colorbar on
  top, horizontal size for a vertical colorbar on right hand side). If
  there is no labelling on top of the image, this can be small
  (e.g. 0.03). If you don't have a colorbar, set \verb$space=0$

\item \verb$width$, the width of the colorbar in units of the image
  size, as with \verb$space$. A value of 0.1 often looks good. If you
  don't have a colorbar, set \verb$width=0$

\end{enumerate}

\noindent There are four outputs, which are used as the inputs to other
procedures. The outputs are: \begin{enumerate}

\item \verb$imgposn$, the 4-element vector for image corner positions,
       normalized coordinates

\item \verb$cbarposn$, the 4-element vector for colorbar corner positions,
       normalized coordinates

\item \verb$f_hor$, the horizontal window size in units of the
  horizontal image size

\item \verb$f_ver$, the vertical window size in units of the
  vertical image size
\end{enumerate}

\noindent For no colorbar, the procedure call would be

\noindent {\tt img\_cbar\_posns, 0.1, 0.05, 0.1, 0.05, 0, 0, imgposn,
  charposn, f\_hor, f\_ver}

\subsection{Creating the Window} \label{windowcreate}

You use these outputs as follows. First, you need to open a window. You
do this differently for your computer screen (X window, or X) and
PostScript (PS): \begin{enumerate}

\item For your {\it computer screen}, you
need to generate an X-window of the proper size---with the borders and
all. Suppose your image is $500 \times 400$ pixels ($X \times Y$). Then
you need to generate the larger window so you have borders,
which you do with the \verb$window$ command:

\begin{verbatim}
loadct, 0
window, 7, xs=f_hor*500, ys=f_ver*400
\end{verbatim}

\noindent (The {\tt loadct,0} is a precaution, needed only if you
had been using exotic color tables; it ensures that the window
background is black.)

\item If you want to create a PostScript (PS) image, make sure you are
  using Truecolor visual class\footnote{Alternatively, if you are on a
  Sun machine, you can use GrayScale or PseudoColor with 256
  entries.}. For your PS window, you don't need to do anything except
  open it. We strongly recommend our \verb$psopen$ procedure, which we
  discuss in the third tutorial (called {\bf MAKING, PRINTING, AND
  POWERPOINTING POSTSCRIPT FILES OF GRAPHS AND IMAGES)}. If you want the
  PS window to be $8 \times 5$ inches, then it's

\begin{verbatim}
psopen, 'test.ps', xsize=8., ysize=5., /inch, /color, /times, /bold, /isolatin1
\end{verbatim}

\noindent When opening a
PostScript file for an image, the \verb$color$ keyword is necessary if you are going
to use grayscale or color (and---after all---you {\it are} making an
image\dots). Here we also have specified a particularly nice font to use
on the PS image with the last three keywords; you might wish something
different (and you could even revert to the somewhat clumsy Hershey
fonts by eliminating all font-related keywords). 

\end{enumerate}

\section {WRITING THE IMAGE ONTO THE WINDOW} \label{writeimage}

This is straightforward: you use the \verb$tv$ command with appropriate
keywords that define the sizes. Assume your image is a byte array named
\verb$psi_b$. Then for nondecomposed color you enter

\begin{verbatim}  
tv, psi_b, imgposn[0], imgposn[1], /norm, xsize=1./f_hor, ysize=1./f_ver
tvlct, r,g,b,/get & colrt= [ [r], [g], [b] ]
\end{verbatim}

\noindent Alternatively, if you are using decomposed color, then you
have three images---the red, green, and blue versions of
\verb$psi_b$---and you enter

\begin{verbatim}  
tv, [ [[psi_b_red]], [[psi_b_grn]], [[psi_b_blu]] ] , true=3, $
imgposn[0], imgposn[1], /norm, xsize=1./f_hor, ysize=1./f_ver
tvlct, r,g,b,/get & colrt= [ [r], [g], [b] ]
\end{verbatim}

\noindent If you will want a colorbar, you need to use the {\tt tvlct}
command to retreive the color table used in making the image and, also,
to define the array {\tt colort} for later use. If you
won't make a colorbar, you don't need these commands. 

\section {WRITING THE ANNOTATION ONTO THE WINDOW}

\subsection{Preliminaries: Defining the Character Color Table}
\label{definecolortable}

You may have written your image in vibrant color, so
that each element of your 256-element color table is good for
representing the {\it image}; or you may have written a set of three
RGB images into your decomposed color PS window. Either way, you
probably want a {\it different} set of colors for your characters
and plotted lines. One way is to load a new color table and choose chracter
colors from that. 

Much easier: if you're using our startup file, then for either X or PS,
just enter

\begin{verbatim}
setcolors, /system_variables
loadct, 0
\end{verbatim}

\noindent (or \verb$setcolors, /sys$ for short). \verb$setcolors$
provides the default colors. These include, first, the primary colors
and their complements: !red, !green, !blue, !cyan, !magenta, !yellow,
!white, !black; and four more nonprimary colors: !orange, !forest,
!purple, !gray.  

\subsection{Now Annotate!}

For this you use the ordinary commands you're familiar with:
\verb$plot$, \verb$xyouts$, etc. Suppose you just want axes and no
plotting or contouring, then overwrite the axes on the image by doing

\begin{verbatim}
plot, x_b, y_b, position=imgposn, color=!green, $
	/xsty, /ysty, /norm, /noerase, /nodata...
\end{verbatim}

\noindent Note that we specify the color: {\it You'd better! See \S
\ref{sobsob}\ \footnote{Normally, you want white axes on your screen and
  black ones on PostScript.}.} The \verb$/noerase$ keyword writes over the image without
erasing it and the \verb$/nodata$ keyword means ``don't plot the data,
just put on the axes''. If you want contours instead, then enter

\begin{verbatim}
contour, psi_b, x_b, y_b, position=imgposn, color=!white, $
	/xsty, /ysty, /norm, /noerase, ...
\end{verbatim}

\noindent In either case, add whatever axis titles and other info you
want---these procedures have {\it lots} of options. 

	At this point you might want to use IDL's \verb$plots$
procedure to plot one or more symbols somewhere on the image or
\verb$xyouts$ to write a label.  When you use these you should use
either {\it data} or {\it normalized} coordinates, {\it not device}
coordinates, because device coordinates are not defined for PostScript. 
For example,  if you want to write a green ``X''
in the center of the display window, you'd enter 

\noindent\verb$xyouts, 0.5, 0.5, /norm, color=!green$

\subsection{{\it SOB, SOB\dots} My Axes Don't Come Out Black on PS!}
\label{sobsob}

If you are doing esoteric things with color in PostScript, you might find that the
{\tt plot} or {\tt contour} axes don't come out black! {\it Sob, sob,
  sob\dots} The solution: explicitly state the color in the call to {\tt
  plot} or {\tt contour} (by setting the keyword: {\tt
  color=!black})\footnote{Again, for your screen you usally want white
  instead of black.}. 

{\it Why} does this happen? In PS, the default color for the axes is at
the beginning of the color table, index 0. For most color tables, the
first element is black---most images go from black to white with
increasing intensity. But your color table might not do this. A good
example is the {\tt pseudo} color table, discussed in our memo {\bf ONE,
  TWO, AND THREE DIMENSIONAL COLOR IMAGES}: the first element is
red, so the axes come out magenta unless you explicitly state
black. 

\section{NOW FOR THE COLORBAR!} \label{cbar}

If you want a colorbar, you can use {\it Robishaw's} \verb$colorbar$ as
illustrated here; you get it automatically if you use our recommended
IDL startup file. There's another colorbar procedure out there from Fanning;
it's different and if you use it you are on your own (you can check by
typing \verb+doc_library, 'colorbar'+). The command for
Robishaw's \verb$colorbar$ is

\begin{verbatim}
tvlct, r,g,b,/get & colrt= [ [r], [g], [b] ]
loadct, 0
setcolors, /system_variables
colorbar, pos=cbarposn, rgb=colrt, crange=[14., 37.3], $
   irange=[0,5.5], gamma=0.55, ytitle='Tb, K', $ 
   xtit='Velocity, Km/s', font=ps-1 ...
\end{verbatim}

\noindent The first line retreives the ({\tt r, g, b}) (red, green, blue)
color table you used in making the image and loads it into the $256
\times 3$ {\tt colrt} array. The time to define {\tt colrt} is {\it
  before} doing the annotation, because the process of annotation
changes the colortable; we insert the command here as a reminder that
you {\it should have done it earlier!} (see \S \ref{writeimage}). 
{\tt cbarposn} is an output from {\tt
img\_cbar\_posns} (\S \ref{posns}). and \verb$crange$ is the data range
represented by the image (i.e., data value 14 gives black and data value
37.3 gives white). \verb$colorbar$ is very flexible and has lots of
other keywords; it also lets you do a 2-d colorbar [see our handout {\bf
ONE, TWO, AND THREE DIMENSIONAL COLOR IMAGES}
(\verb$dimensionalcolor.ps$)].

Similarly, the second and third lines should have been done before (see
\S \ref{definecolortable}).

The second line of this call to {\tt colorbar}, which contains the
  optional inputs {\tt irange, gamma, ytitle}, applies only for a 2-d
  color image, in which lightness (intensity of the image) depicts one
  quanity and color the other; {\tt irange} is the data range
  represented by the intensity part of the image, and \verb$gamma$ is
  the power to which the image values are raised (as in {\bf BIDIDL}).

\section{YOU'RE DONE!}

You're all done! Just one thing to remember: if you're in PS, the file
is empty until you close it. So after you're finished, enter

\begin{verbatim}
psclose
setcolors, /system_variables
\end{verbatim}

\section{SOME DETAILS}

\subsection{PS versus X: White versus Black Background}

	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.  X uses white text on a black
background; this white text on PS's white background won't show.  During
the process of 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 with

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

As is made clear in the documentation for \verb+bgfill+, you've just
painted the window with a background color; in order to put a plot on top
of this background you {\it must} use the \verb+/noerase+ keyword when you
call \verb+plot+ (or \verb+contour+) or you'll just overwrite the colored
background (or, for PS, your plot will end up on page 2 and your colored
background will be on page 1).

\subsection{X Window Preliminaries: Resizing Images} \label{xwinprelims}

	Suppose you have a two-d array called \verb$psi$, say $(50 \times
40)$, in which the $(x,y)$-coordinates are defined by (50,40)-long
vectors, respectively. You need to generate a conveniently sized image
for display purposes. Recall that your screen has something like $1024
\times 768$ pixels, maybe more, so the $50 \times 40$ image
will occupy only a tiny area; you might (or might not) want your full
image to occupy most of the screen. So perhaps you want to resize your
original image to $(xsize= 500) \times (ysize=400)$. To resize, you can use
either \verb$congrid$ (which works when resizing by non-integral factors)

\begin{verbatim}
psi_b = bytscl( congrid( psi, xsize, ysize, /interp, /minus_one))
x_b= congrid( x, xsize, /interp, /minus_one)
y_b= congrid( y, ysize, /interp, /minus_one)
\end{verbatim}

\noindent or \verb$rebin$ (which works only with integral factors)

\begin{verbatim}
psi_b = bytscl( rebin( psi, xsize, ysize))
x_b= rebin( x, xsize)
y_b= rebin( y, ysize)
\end{verbatim}

\noindent Now go to \S \ref{windowcreate}.

\noindent {\it Comments:} \begin{enumerate}

	\item Do as we do above: be sure to treat the image and the
coordinates identically!

	\item With \verb$rebin$, the expansion or reduction factors have
to be integers. 

	\item With \verb$congrid$, it's important to understand those
last two keywords; look at \verb$congrid$'s documentation and experiment
with a 1-d array to see their effect. \verb$/interp$ makes the result
smooth, while not using it retains your original pixels;
\verb$/minus_one$ affects the interpolation details. 

	{\it Caution:}  using \verb$congrid$ for downsizing an array loses
signal/noise.

\end{enumerate}
 
\subsection{PostScript preliminaries: Use TrueColor!}

As discussed in {\bf BIDIDL}, computer graphics cards can support
multiple types of visual classes. If you're using Solaris or Linux,
you'll want to always start IDL in TrueColor when making PS images; the
reasons are beyond the scope of this document.  Suffice it to say you
will find oddities with your displayed images if you change a color
table using either PseudoColor or DirectColor visual classes because
they are {\it dynamic}, meaning that changing the color table changes
what's already been written on the screen.  The process of annotating PS
usually involves changing the color table.  If you use the same code for
the X windows display that you do for PS, your changing the color table
for the character writing will, with a dynamic color table, change the
appearance of the image on the screen.

So, until you're a blackbelt and understand this little subtlety, when
you are annotating images that you'll write to PS use the TrueColor
visual class. 

\end{document}

\end



