- PLOT:
Plotting in IDL is very simple using the PLOT procedure: PLOT,[X,]Y[,options].
The x-axis array is optional and if omitted will default to array index
number. So for a simple plot:
Y=[0,3,7,9,12]
PLOT,Y
or
Y=findgen(100)*.3+20
PLOT,Y
Say you want to read in a FITS file and plot it with the correct
x-axis scale:
FITS_READ,'M7.fits',flux
x=findgen(13992)*0.5+500
PLOT,x,flux
Any subset of an array can be plotted just as it can be used
anywhere else: PLOT,x[500:700],flux[500:700].
- Log Plots:
To get linear/log or log/log plots, use the XLOG and YLOG keywords with PLOT.
For instance to plot a linear x scale and a log y scale:
PLOT,x,flux,/YLOG
To use log scales on both axes:
PLOT,x,flux,/XLOG,/YLOG
- Titles:
Other options that can be specified include titling the plot with the
keywords TITLE=string, XTITLE=string, YTITLE=string, ZTITLE=string, and
SUBTITLE=string:
plot,x,flux,title="Flux vs. Wavelength Plot",xtitle="Wavelength",ytitle="Flux"
To create special characters (Greek letters or Symbols), you simply need
to change character sets. Character formatting commands can be found starting
on p.3949 of the IDL guide in ? or just look for character sets in the index.
Characters are formatted by embedded ! commands in the string. For instance:
'H!7b!3' would display H beta. !7 is the Greek character set and !3 is the
standard character set. !I makes the following characters subscript, !E
superscript, and !N shifts back to normal.
- PSYM:
| PSYM value |
Plotting Symbol | |
| 1 | Plus + |
| 2 | Asterisk * |
| 3 | Period . |
| 4 | Diamond |
| 5 | Triangle |
| 6 | Square |
| 7 | X |
| 8 | USERSYM |
| 10 | Histogram Mode |
The keyword PSYM specifies the plotting symbol to be used. The default value
is 0, in which case data points are connected by lines and no symbols are
drawn to mark the individual points.
If PSYM is set to a positive value, there is no line connecting data points
and the individual points are represented by the symbol listed in the table.
If PSYM is set to a negative value, there IS a line drawn to connect the
data points and the points are represented by the corresponding symbol. For
instance PSYM=-5 would represent points as diamonds and connect them with
a line. PSYM=10 uses histogram mode to plot, and PSYM=8 uses a user defined
symbol.
Users can define their own symbol using
USERSYM,X[,Y][,COLOR=value][,/FILL][,THICK=value].
X and Y are arrays containg the X and Y coordinates of the verticies of the
symbol. For instance to draw your own diamonds:
USERSYM,[0,1,0,-1,1],[1,0,-1,0,1]
PLOT,x,flux,PSYM=8
The size of the symbol is controlled with the optional keyword SYMSIZE = value
(default = 1).
- Linestyle:
You can specify the type of line you want with the optional LINESTYLE = value
keyword. By default, all lines are drawn solid (LINESTYLE=0). 1 = dotted,
2 = dashed, 3 = dash dot, 4 = dash dot dot, and 5 = long dashes.
- Color:
You can specify the color of the plot with the keyword COLOR = value. Note
that when you use this keyword with PLOT, the axes and labels will be drawn
in the specified color as well as the data. If you want your axes to be
the normal white, use the PLOT command with the keyword /NODATA and then
use OPLOT to plot your data with the COLOR keyword set (see OPLOT below).
The value to set for COLOR can be tricky in true color systems so I have
written a function that only requires you to enter the red, green, and
blue (RGB) values you want just like in HTML. The function is
value=get_color(R,G,B) so for instance to create a bright blue-green plot:
plot,x,color=get_color(0,240,240)
RGB values can range from 0
to 255.
- Position:
You can use the POSITION=[X0,Y0,X1,Y1] keyword to specify the position of
the plot in the window. X0,Y0 is the lower left corner of the axis and
X1,Y1 is the top right corner. It is in normalized units so
POSITION=[0.,0.,1.,1.] will fill the entire window (leaving no room for
titles). If you want to add a legend to you plot, you can make it smaller:
POSITION=[.05,.05,.95,.8] will leave room for titles all around and extra
space at the top for a legend. Legends can be created by then adding text
to the plot using XYOUTS (see below).
- Charsize:
Set the keyword CHARSIZE=value to change the size of the characters on the
plot. CHARSIZE=1 is the default so 2 will double the size and 0.5 will half
the size.
- XRANGE, YRANGE:
The keywords XRANGE and YRANGE both take a vector argument, [min,max]. They
allow you to choose the range for each axis. It should be noted that IDL
may still modify this range, so to force IDL to use exactly your range, you
must also specify XSTYLE=1 and/or YSTYLE=1. To zoom in on the y range of
3 to 5:
plot,x,yrange=[3,5],ystyle=1
- There are many other graphics keywords that PLOT accepts that can
aesthetically alter it in almost any way imaginable. You can control the
number of tick marks on each axis, major and minor, which ones are labeled,
what values they are at, and what they are labeled with, if anything
(a little trick is to use XTICKNAME=[' ',' ',' ',' ',' '] to not label any
tickmarks. Use as many elements as you have XTICKS). Look at the handout
for PLOT from ? in IDL and most of the graphics keywords are somewhat
self explanatory. If you want to figure out how to use them, simply look
them up in ?. It should be easy enough to follow.
- GatorPlot:
GatorPlot (currently v4.4) is an interactive plotting package that I have
written in IDL. Access it by typing gatorplot at an IDL prompt. It allows
you to interactively plot one or more files at once, dynamically change
options and labels, smooth plots, perform math operations, integrate flux,
estimate the FWHM of emission lines, perform many types of fits, and more.
- Overplotting:
You can overplot data with the OPLOT procedure. The only differences between
it and plot are 1) it does not generate a new axis, but uses the scaling
previously established by PLOT and does not erase anything and 2) it has
less options accordingly. The form is OPLOT,[X,]Y[,options]. It will accept
options such as PSYM, LINESTYLE, COLOR, MAX_VALUE, and MIN_VALUE, but not
many others (see OPLOT in ? for full details). You can OPLOT as many times
as you want on a single PLOT and new data is continually overlayed on top
of the existing plot.
- Multiple Plots:
You can put multiple plots on a page by setting the !p.multi system variable
before creating your plots. !p.multi is a one dimensional array (or vector)
of length 5. Set the first element almost always to 0. It controls the
number of remaining empty sectors on a page, so 0 starts a new plot. The
2nd and 3rd elements contain then number of columns and rows respectively. The
4th column contains the number of plots stacked in the Z dimension and the
fifth element controls the order in which the plots are drawn. 0 is the
default (left to right). Set this to 1 if you want the order to be top to
bottom (row major). Omitting any element is the same as setting it equal to
0, so usually just the first 3 elements are set. For example: to create a
6 panel plot with 3 columns and 2 rows:
!p.multi=[0,3,2]
Once you have set !p.multi, use the PLOT procedure as you normally would.
Each time the PLOT procedure is called, a new plot will be created in a new
sector of the page. This is especially useful in FOR loops:
!p.multi=[0,3,2]
for j=0,5 do begin
plot,x,y[j,*],title=t[j]
endfor
Note that using the OPLOT procedure will NOT move the plot to the next sector.
You can OPLOT as many times as you want on the first sector, then use PLOT to
move to the next sector.
- Margins:
When you are creating multiple plots on a page, it is sometimes useful to
set the XMARGIN=[left,right] and YMARGIN=[bottom,top] keywords. The default
values are XMARGIN=[10,3] and YMARGIN=[4,2]. Changing these values (by
either setting the keywords in PLOT or the system variables !X.MARGIN and
!Y.MARGIN) can make the individual plots bigger or smaller. Setting them
both to [0,0] will result in the borders of a plot touching those of its
neighbors.
- Annotating with XYOUTS:
Sometimes it is very useful to add text to the plot. Text can be added
anywhere in the plot by the XYOUTS procedure: XYOUTS,[X,Y,]String. The X
and Y coordinates can be either given in data coordinates (/DATA keyword) or
normalized coordinates (/NORMAL). Data coordinates are useful when you want
to place a label at a particular point that depends on your data values. Say
you want to label an emission line at 1549 Angstroms, and flux of 5 on the
y-axis:
XYOUTS,1549,5,'C IV',/data
Normalized coordinates are very useful in loops, and when you want to place
text in say the top left corner of each plot. The plots are going to have
different data values, so instead of bothering to find out each one, you can
use a formula to include XYOUTS in your loop. Normalized coordinates go from
0.0 (bottom left) to 1.0 (top right) in both the X and Y directions. Adding
the following line in the for loop shown above for the 6-panel plot will label
the top left corner of each plot with the text contained in the string array
label:
XYOUTS,.05+.333*(j MOD 3),.95-(j/2),label[j],/normal
Remember that since j is an integer, j/2 will also be an integer and drop the
remainder. XYOUTS has several other optional parameters that can be set:
CHARSIZE=value, CHARTHICK=value, ALIGNMENT={0.0 to 1.0}, COLOR=value, and
ORIENTATION=value are 5 of the most common ones. An alignment of 0.0 aligns
the left edge of the text with the given coordinate, 0.5 centers it, and 1.0
is right justified. Orientation should be set to the number of degrees
counterclockwise from horizontal that you want the text to be rotated.
- Other types of Plots:
There are of course many other types of plots possible in IDL besides regular
X vs. Y plots. Many 3-dimensional plots are available as well. I will just
touch on some of these, as there are again a lot of things you can do with
each one.
- Wireframe plots:
3-D wireframe plots are available using the SURFACE procedure:
SURFACE,Z[,X,Y][,AX=degrees][,AZ=degrees][,options]. Z is a two-dimensional
array representing a function F(X,Y). If X and Y are specified, they will
be used to label the X and Y axes (similar to X in PLOT). Otherwise, array
index number will be used. The optional keywords AX and AZ specify the angle
of rotation about the X and Z axes. They both default to +30 degrees. Of
course, SURFACE accepts the keywords /XLOG, /YLOG, and /ZLOG for logarithmic
scaling. It accepts all graphics keywords accepted by PLOT except for PSYM
and SYMSIZE.
z=dist(30)
surface,z
Note that dist(30) produces a 30x30 array in which each element value is
proportional to its frequency (i.e. X[15,15] is the highest value being at
the center).
- 3-D Bar Graph:
By specifying the /LEGO keyword in SURFACE, you can produce a stacked
histogram-style plot:
z=sin(findgen(20,10)/10.)
surface,x,/lego
- Shaded Surfaces:
The procedure SHADE_SURF,Z[,X,Y][,AX=degrees][,AZ=degrees][,options] creates
a shaded-surface from a two-dimensional array. It takes the same arguments
and has many of the same options as SURFACE.
- Contour plots:
Contour plots can be created by the procedure CONTOUR,Z[,X,Y][,options].
Z is again a 2-dimensional array F(X,Y). There are many options that can
be set in CONTOUR, taking array arguments, that allow a lot of flexibility
with drawing and labeling the contours. For instance, LEVELS=vector allows
you to specify the values you want contours drawn at. The corresponding
keywords C_LABELS and C_LINESTYLE both take vectors allowing you to decide
which of the drawn contours to label and which linestyle to use when drawing
each one:
z=dist(30)
CONTOUR,z,levels=[4,8,12,16,20],c_labels=[1,1,0,1,0],c_linestyle=[0,1,0,1,0]
In this example, contours are drawn at 4, 8, 12, 16, and 20. Those
drawn at 4, 8, and 16 are labeled and every other contour (8,16) is drawn
with a dotted line instead of solid. Here is a list of some of the options
that take vectors (see CONTOUR in ? for more info): C_LABELS, C_LINESTYLE,
C_ANNOTATION, C_THICK, LEVELS. In addition, the /FILL keyword can be set
to fill in the space between the contours with colors.
- SHOW3:
SHOW3,Z[,X,Y] combines an image, a surface plot, and a contour plot into
a single tri-level display. Z can either be an image or a 2-dimensional
array F(X,Y):
show3,z
- Outputting to Postscript Files:
Outputting a plot to a postscript file is very easy. You just tell IDL before
you make the plot to send it to the postscript device instead of the screen.
This is done with 2 commands before you plot.
set_plot,'ps'
device,filename='file.ps'
Enter these two lines before you use PLOT, and after you are finished plotting
(as well as using OPLOT and XYOUTS), enter the command
device,/close
to close and finalize the .ps file. You must remember the
device,/close command or your .ps files will not come out right. If you want
to then make plots to the screen you must tell IDL to send plots to the screen
again by the command:
set_plot,'x'
The keyword device can take many options when you set the filename. These
include specifying the size of the plot in inches as well as the margins:
device,filename='file.ps',xs=7.0,ys=8.0,xoff=1.0,yoff=1.5,/INCHES
Make sure the /inches keyword is included. Other keywords that can be set
include /ENCAPSULATED to create a .eps file and /LANDSCAPE to make a
landscape file.
- Color postscript files:
IDL does not support exporting color plots to .ps files but does support
exporting color images. I exploited this to write a procedure that generates
a color .ps file from a plot on the screen. Use the procedure:
colorps,'file.ps'[,/encapsulated]
First, make your plot on the screen and do any annotating or overplotting you
want. Then call colorps. This can also be useful when making plots from the
command line, to quickly generate a postscript file, even if there aren't
any colors in it. To generate an eps file, specify the optional keyword
/encapsulated. Example:
plot,x
oplot,y,color=get_color(0,255,0)
xyouts,0.05,0.95,'Some text',/normal
colorps,'plot.ps'
- Graphics:
There are a lot of graphics and image processing tools available with IDL so
again, I will just cover the basics because I haven't done too much with
graphics.
- Window:
The WINDOW procedure creates a window for the display of graphics or text.
It is only necessary to use WINDOW if more than one simultaneous window
or a special window size is desired. The default size is 640x512. The
syntax is WINDOW,[index][,XSIZE=pixels][,YSIZE=pixels]. Index is any number,
generally 0 is preferred for the first Window, 1 for the 2nd, and so on.
You can use the WSET command to specify which window is active if there are
multiple windows open: WSET,index. Only 1 window can be active at a time,
and all plots, graphics, and text will be sent to that active window.
- Reading JPEG images:
JPEG images can be read with the procedure READ_JPEG. JPEG is a standardized
compression method for images. You will commonly see JPEG images on the
Internet because they retain good image quality while having low file sizes
due to the "lossy" compression that JPEG uses. The syntax is
READ_JPEG,filename,image[,options]. You will probably not have to use any
of the options. image is an array for the image to be read into. It will
be a 2 or 3 dimensional BYTE array. A greyscale image will be read into a
2-dimensional BYTE array with 1 entry for each pixel in the image. The
array entry will contain an 8-bit intensity level from 0 to 255. True color
images will be read into a 3-dimensional array (3x640x400 for instance).
image[0,*,*] will contain a red intensity for each pixel, image[1,*,*] a
green intensity, and image[2,*,*] a blue intensity. Combining these RGB
frames produces a true color image. Many other formats can be read with
similar procedures: READ_TIFF for .tiff files and so on. I will not go
into detail about them since JPEG is the most common file format. You can
perform any standard array operations on the BYTE array containing the image
and thus perform many image manipulation tasks. For instance, to create
thumbnail images, you may want to write a routine that reads a JPEG file and
takes the average of each group of 4 pixels to be 1 pixel in a new BYTE array
that is 1/4 the size (half the size in each dimension).
- Writing JPEG images:
As you may expect, JPEG images can be witten by the routine WRITE_JPEG.
The syntax is WRITE_JPEG,filename,image[,options] where again, image is
a 2 or 3 dimensional BYTE array.
- Displaying JPEG images:
Now, you can read and write images, so it may interest you to actually be able
to display them. This can be done with the TV command: TV,image[,X,Y].
This will display the image in the active window. You may want to open a
window of the same size in pixels as your image before calling this routine.
X and Y specify the coordinates for the lower left corner of the image if
included. Say you want to display a 640x400 image:
READ_JPEG,'file.jpg',a
window,0,xsize=640,ysize=400
tv,a
You will quickly notice that this does not work for true color images. For
those (3-dimensional arrays), you must also specify the keyword TRUE=1:
tv,a,true=1
- TVSCL:
TV displays an image "as is". TVSCL on the other hand, performs the same
function but scales the intensity values of the image based on the maximum
and minimum intensities of the image. So if you have a narrow range of
intensities in a picture, this will bring out detail much more clearly.
TVSCL,image,[X,Y][,TRUE=1]
- Reading an image from a window:
Now that you can display images, how do you go the other way and read images
from windows? The TVRD function will do this:
result=TVRD([X0,Y0,Nx,Ny,TRUE=1]). X0 and Y0 are the coordinates of the
lower left corner where you want to start reading data. Nx and Ny are the
number of pixels in the X and Y directions you want to read. If you want
to read a true color image, of course specify TRUE=1. For example, to
simply read in an image of a plot you created:
plot,x
a=tvrd()
will read the whole window into a 640x512 BYTE array that can
be saved as a JPEG image with WRITE_JPEG. Since it is a B/W plot, there
is no need to specify TRUE=1 in this case. If it is a color plot:
plot,x,color=get_color(0,255,0)
a=tvrd(TRUE=1)
- Fitting:
IDL has many routines for least squares fitting of varying degrees of ease
of use and applicability.
- LINFIT:
LINFIT is the simplest of the fitting routines, and is very applicable to many
things. As implied by the name, LINFIT will compute a linear y = A + Bx fit
to a data set by minimizing chi-square. The form is
result=LINFIT(X,Y[,options]). X and Y are vectors containing the X and Y
values for each datapoint. result will be a two element array containing
the fit: [A, B]. Among the options that can be specified are
MEASURE_ERRORS=vector, which takes a vector containing the standard
measurement errors for each point Y[i]. Setting the option CHISQ=var
will return the chi-square value of the fit to the specified variable.
Say you want to fit a dataset then plot the fit:
fit=LINFIT(X,Y)
yfit=fit[0]+fit[1]*X
plot,x,y,psym=4 ;plot the data as symbols
oplot,x,yfit,linestyle=1 ;overplot the fit as a dotted line
- GAUSSFIT:
GAUSSFIT fits a gaussian to data. The form is
fit=GAUSSFIT(X,Y[,A][,NTERMS=3 to 6][,options]). fit will be an array that
contains the y-values that result from the fit, y=f(x). If the optional A
is specified, that variable will be returned as an array containing the
coefficients of the fit. NTERMS can be from 3 to 6 and is the number of
coefficients to be used in the fit. 3 is a true Gaussian, 4 adds a constant
term, 5 adds a linear term too, and 6 also adds a quadratic term.
- POLY_FIT and SFIT:
POLY_FIT and SFIT both fit polynomials to data but I have never used either
one. If you want to use them, look them up in ? and their format should be
similar to either LINFIT or GAUSSFIT.
- CURVEFIT:
CURVEFIT is the most flexible of the fitting routines. It allows you to fit
any user defined function. The syntax is:
fit=CURVEFIT(X,Y,Weights,A,FUNCTION_NAME=string[,options]). fit returns as
an array of values for the dependent variable, as fitted by the function
Y = F(X). X and Y contain the X and Y values for each datapoint. Weights
is an array of the same length as X and Y containing the weighting for
each point. For Poisson weighting, Weights = 1.0/Y[i]. A is a vector
that contains the initial estimates for each parameter of the user defined
function. On return, A contains the fitted parameters. FUNCTION_NAME
specifies the name of the function to fit. This should be a procedure
written by a user, and it should already be compiled. The procedure must
accept values of X and A and return F (the functions value at X) and
PDER (a 2-D array of partial derivatives). As an example, say you want to fit
data with a powerlaw. I wrote a procedure, plaw.pro that contains the
powerlaw function F(X) = A*X^B.
PRO plaw, X, A, F, pder
F = A[0]*X^A[1]
IF N_PARAMS() GE 4 then pder=[[X^A[1]] ,[A[0]*X^A[1]*alog(X)]]
END
I can now use this procedure with curvefit to fit a powerlaw to my data:
w=1./y
a=[500.,-0.5] ;initial guesses
fit=curvefit(x,y,w,a,function_name='plaw')
a now contains the final coefficients [A,B] and fit contains the fitted
y-values.