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

\begin{document}

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

\author{Carl Heiles and Tim Robishaw}

\tableofcontents

	It's easy to slap an image on your screen. But annotating it
with coordinates isn't so easy. Here's a quick tutorial.

	I'll also mention that we have some image generation procedures
that incorporate annotation.  However, they are under development and
not well documented.  You are welcome to try them out; they are located
in \verb$~heiles/idl/gen/image$.  If they don't work and you want to
talk about them with Carl, fine---but first read this memo! (Tim's too
busy with  his thesis to talk to you about these matters.)

	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.  This
is a several-step process.  

\section{PRELIMINARIES} \label{preliminaries}

	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. 
Suppose we allow an extra $10\%$ around the edge.  Let this fraction
equal $w$---i.e., for $10\%$, $w=0.1$; also define $f=(1.+2w)$. 

{\bf UPDATE AS OF 14 NOV 2006:} The positioning commands and window
commands that use $f$ and $w$, namely in the \verb$window$ command of \S
\ref{xwinprelims} and items (1) and (3) in \S \ref{afterprelims}, are
more generally replaced by the more flexible content of \S
\ref{colorbar}, which also offers an easy way to incorporate a colorbar.

\subsection{X Window preliminaries} \label{xwinprelims}

	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= 400) \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 {\it Note that we use} \verb$bytscl$! When writing an image,
it must be a byte array!

Then generate a $(f*400 \times f*400)$ window (numbered 7) with
the IDL command 

\noindent\verb$window, 7, xs=f*400, ys=f*400$. 

\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}

\subsubsection{Use TrueColor when makine a PS file!}

	Computer graphics cards can support multiple types of Visual
Classes: PseudoColor (Solaris), TrueColor (Solaris, Mac, Linux, Windows)
and DirectColor (Solaris, Linux) are the most common.  If you're using a
Mac or Windows, you can stop reading because you're limited to TrueColor
only.  

	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 colortable changes what's already been written on the
screen.  The process of annotating PS usually involves changing the
colortable.  If you use the same code for the X windows display that you
do for PS, your changing the colortable for the character writing will,
with a dynamic colortable, 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. 

\subsubsection{The mechanics of making a PS file}

	To make a PS plot on the file ``test.ps'', define the values of
$f$ and $w$ as above and open the ps file:

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

\noindent (to make an $8 \times 8$ inch image).  When opening a
PostScript file the \verb$color$ keyword is necessary if you are going
to use greyscale or color (and since you're making an image\dots).  (In
addition, before writing characters you need to use \verb$setcolors$ to
define PostScript's color table; see below).  See the \verb$psopen$
documentation for its huge selection of useful options.  {\it After
writing on the ps file}, you must have

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

\section{AFTER THE PRELIMINARIES} \label{afterprelims}

	Then perform the following steps: \begin{enumerate}

	\item Write the image. There are two cases: \begin{enumerate}

	\item If your image is in decomposed color
(meaning 256 colors in each of red, green, and blue---$256^3$ colors in
all) then you have three \verb$psi_b$ images, and you write them like
this: 

\begin{verbatim}  
tv, [ [[psi_b_red]], [[psi_b_grn]], [[psi_b_blu]] ] , $
        w/f, w/f, /norm, xsize=1./f, ysize=1./f
\end{verbatim}

	\item If your image is in combined color, which you earlier
invoked by typing \verb$device, decomposed=0$, then it has 256 colors
only, so you have only one image instead of 3 and you write it like this:

\begin{verbatim}  
tv, psi_b, w/f, w/f, /norm, xsize=1./f, ysize=1./f
\end{verbatim}

\end{enumerate}

\noindent Note that \verb$psi_b$ is a byte array, so we can use
\verb$tv$; if it weren't a byte array we could use \verb$tvscl$, but
this should be used only for quick-and-dirty applications.  We use {\it
normalized coordinates} (\verb$/norm$), meaning that our positioning
commands are in units of the window size (quantities run from 0 to 1);
this makes our plotting work on the ps file as well as on the X window. 
The \verb$w/f$ places the lower left-hand corner of the image away from
the window corner by the fraction $w \over f$ of the {\it window} size. 
That's the same as moving it the fraction $w$ of the {\it image} size;
for a $(400 \times 400)$ image, the offset is $(40, 40)$ pixels.  The
keywords \verb$xsize$ and \verb$ysize$ affect things only in PostScript
(PS); they reduce the image size relative to the plotting area by $1
\over f$.  So if you are only examining things on the Xterm, you don't
need to include those keywords. 

	\item Now we prepare PostScript's color table for writing
characters.  We do this {\it after} writing the image because we don't
want the character colortable to screw up the image.  To accomplish
this, use our home-grown

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

\noindent \verb$setcolors$ supports the following colors: !red, !green,
!blue, !cyan, !magenta, !yellow, !white, !black, !grey. 

	\item If 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=[w/f, w/f, 1.-w/f, 1.-w/f], $
	/xsty, /ysty, /norm, /noerase, /nodata...
\end{verbatim}

\noindent You can also specify the color, e.g.  \verb$color=!green$ . 
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 overwrite by doing

\begin{verbatim}
contour, psi_b, x_b, y_b, position=[w/f, w/f, 1.-w/f, 1.-w/f],  $
	/xsty, /ysty, /norm, /noerase, ...
\end{verbatim}

\noindent In either case, add whatever axis titles and other info you
want. The \verb$position$ keyword locates the corners of the plot on the
window or plotting area and thus forces the plotting area to occupy the
central $80\%$ of the $x$- and $y$-axes---the same area that the image
occupies. 

	\item 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. 

\end{enumerate}

\section{TWO IMPORTANT WRINKLES}

\subsection{Wrinkle number one}

	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}

\subsection{Wrinkle number two}

	One more wrinkle: You normally print ps files.  For greyscale
printed images, it's often better to have black on a white background,
i.e.\ a ``negative'' image: it saves ink and the overall quality is
higher.  For example, most printers don't do so well at making a uniformly
black area.  So you might want to invert the grey scale image colors. 
If your image is a byte array, you can do this by typing 
\verb$tv, not(image)$ instead of \verb$tv, image$.  
({\it Of course...}this works
only if \verb$image$ is a byte array!)

\section{A MORE FLEXIBLE POSITIONING APPROACH---INCLUDING POSSIBILITY OF
  COLORBARS} \label{colorbar}

Regarding positioning of an image within a plotting window, our
discussion above assumes equal margins on all sides. This wastes some
space because you need to provide margin space for coordinate labels,
which usually appeear 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, and that complicates the calculation of margins. So we make
the process of positioning easier (\S \ref{posns}) and we also provide a
straightforward colorbar-generating procedure (\S \ref{cbar}).

\subsection{Doing those margins} \label{posns}

Our procedure \verb$img_cbar_posns$ calculates positional information
given your specification of margins widths. 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, 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. This is
  equivalent to our $w$ in \S \ref{preliminaries}. A reasonable value is 
  is 0.1.

\item \verb$w_right$, the width of the right-hand margin. 

\item \verb$w_bot$, the width of the bottom margin in units of the
  height of the image.

\item \verb$w_top$, the width of the top margin.

\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
  you don't have a colorbar, set \verb$space=0$

\item \verb$width$, the width of the colorbar. If you don't have a
  colorbar, set \verb$width=0$

\end{enumerate}

\noindent There are four outputs: \begin{enumerate}

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

\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_hor$, the vertical window size in units of the
  vertical image size
\end{enumerate}

You use these outputs as follows (replacing the commands listed in above
sections):

\noindent\verb$window, 7, xs=f_hor*400, ys=f_ver*400$. 

\begin{verbatim}  
tv, psi_b, imgposn[0], imgposn[1], /norm, xsize=1./f_hor, ysize=1./f_ver
\end{verbatim}

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

\subsection{Now for the colorbar} \label{cbar}

If you want a colorbar, you can use {\it Robishaw's} \verb$colorbar$ as
illustrated. There's another colorbar procedure out there from Fanning;
it's different and if you use it you are on your own. The command for
Robishaw's \verb$colorbar$ is

\begin{verbatim}
colorbar, pos=cbarposn, crange=[14., maxi], gamma=0.55, 
   xtit='Brightness Temp, Kelvins', font=ps-1, /negative ...
\end{verbatim}

\noindent Here \verb$crange$ is the data range represented by the
image, \verb$gamma$ is the power to which the image values are raised,
and the keyword \verb$/negative$ says to reverse the colortable (which
is usually what you want to when transferring greyscale images to ps or
paper). \verb$colorbar$ is very flexible and has lots of other keywords;
it also lets you do a 2-d colorbar [see our handout ``One, Two, and
Three Dimensional Color Images'' (\verb$dimensionalcolor.ps$)]. 

\end{document}

\end



