pro shapelets_plot_image, image, $
FRAME=frame, $
SILENT=silent, $
COLBAR=colbar, $
CBAR=cbar, $
VBAR=vbar, $
CRANGE=crange, $
CLOG=clog, $
CSQRT=csqrt, $
CINVERT=cinvert, $
CTITLE=ctitle, $
CCHARSIZE=ccharsize, $
CTHICK=cthick, $
CTICKS=cticks, $
CTICK_GET=ctick_get, $
CTICKFORMAT=ctickformat, $
CTICKINTERVAL=ctickinterval, $
CTICKLAYOUT=cticklayout, $
CTICKLEN=cticklen, $
CTICKNAME=ctickname, $
CTICKUNITS=ctickunits, $
CTICKV=ctickv, $
CSIZE=csize, $
CFRACTION=cfraction, $
CGAP=cgap, $
COLOR=color, $
CNOZERO=cnozero, $
CONTOUR_LEVELS=contour_levels, $
CONTOUR_LINESTYLE=contour_linestyle,$
CONTOUR_THICK=contour_thick, $
CONTOUR_COLOUR=contour_colour, $
XRANGE=xrange, $
YRANGE=yrange, $
XSTYLE=xstyle, $
YSTYLE=ystyle, $
XTICKNAME=xtickname, $
YTICKNAME=ytickname, $
INVERSE=inverse, $
INVERT=invert, $
SCALABLE=scalable, $
NOERASE=noerase, $
POSITION=position, $
TRUE=true, $
ISOTROPIC=isotropic, _ref_extra = ex
;$Id: shapelets_plot_image.pro, v2$
;
; Copyright © 2005 Richard Massey and Alexandre Refregier.
;
; This file is a part of the Shapelets analysis code.
; www.astro.caltech.edu/~rjm/shapelets/
;
; The Shapelets code is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public Licence as published
; by the Free Software Foundation; either version 2 of the Licence, or
; (at your option) any later version.
;
; The Shapelets code is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public Licence for more details.
;
; You should have received a copy of the GNU General Public Licence
; along with the Shapelets code; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
;
;+
; NAME:
; SHAPELETS_PLOT_IMAGE
;
; PURPOSE:
; Draws a 2D pixellated image.
;
; CATEGORY:
; Plotting.
;
; PURPOSE:
; Plot a 2D bitmapped image.
;
; INPUTS:
; IMAGE - 2D monochrome image array
; OR 3D full colour image array (eg [[[r]],[[g]],[[b]]],true=3)
; OR Shapelets image/pstamp structure
;
; OPTIONAL INPUTS:
; Accepts usual graphics inputs, including [X,Y]TITLE, CHARSIZE, etc.,
; plus most prefixed with a "C" apply to the colour bar. For example:
; CTITLE - Title above colour bar.
; CRANGE - Range of a for colors. Exclude zero values with CNOZERO.
; DEFAULT: [min(a),max(a)]
; CSIZE - Vertical size of the colour bar [0-1].
; DEFAULT: 0.08
; CGAP - Gap between image and colour bar [can be -ve].
; DEFAULT: 0.08
; CFRACTION - Vertical fraction taken up by the colour bar [0-1].
; DEFAULT: CSIZE+CGAP
; POSITION - Device coordinates of edge of plotting region [L,B,R,T],
; overriding anything specified by the three options above.
; DEFAULT: [0,0,1,1]
;
; KEYWORD PARAMETERS:
; Accepts usual graphics keywords, including ISOTROPIC, SCALABLE, etc.
; ISOTROPIC - Force scales on x and y axes to be identical.
; CLOG - Make colour scale logarithmic.
; CBAR - Draw color bar. [1=horizontal on top, 2=vertical on right]
; A synonym for this is colbar, for backwards compatibility.
; VBAR - A synonym for cbar=2.
; CINVERT - Invert the color coding.
; FRAME - Draw a frame with pixel index limits;
; to supress frame but keep image within it, set FRAME=-1
; to change limits set frame=[x0,x1,y0,y1].
; The latter effect can also be achieved with [X,Y]RANGE.
; NOERASE - Supress erasing whatever was previously in the window.
; SCALABLE - Force the use of scalable pixels.
; DEFAULT: nonscalable used with xterm or win device,
; scalable used with postscript device.
;
; OUTPUTS:
; The image is drawn to STDOUT with, optionally, a frame and colour bar.
; Including a frame also sets up the coordinate system, which can be
; particularly useful for overplotting other things later.
;
; MODIFICATION HISTORY:
; Nov 11 - Default size and placing of colour bar improved by RM.
; Oct 11 - CONTOUR overplotting options added by RM.
; Jan 10 - SILENT keyword added by RM.
; Jan 08 - Bug where colour bar would advance to next page fixed by RM.
; Oct 07 - CNOZERO option added by RM.
; Aug 07 - Positioning of colour bar improved & VBAR option added by RM.
; Feb 07 - Multiple plots per page (via !p.multi) implemented by RM.
; Feb 07 - Colour bar size tweaked and minimum image dimension >=1 by RM.
; Aug 06 - Plotting keywords propagated to colour bar by RM.
; May 06 - POSITION keyword added by JB.
; Mar 06 - CINVERT keyword added by RM.
; Aug 05 - ISOTROPIC keyword perfected by RM.
; Apr 05 - Plotting of 1D arrays and logarithmic color scale added by RM.
; Mar 05 - Input generalised to include shapelet image structures by RM.
; Jul 04 - Automatic detection of device type (and adoption of scalable
; pixels where relevant) by RM.
; Nov 02 - ISOTROPIC keyword added by Richard Massey. Still temperamental!
; Aug 00 - Plotting over the full plotting region allowed by AR.
; 3 Sep 97 - Active changes for the color bar rangeadded by AR.
; 14 Oct 97 - Plotting of a color bar and flexible frame labels added by AR.
; 7 Jul 97 - Written by Alexandre Refregier.
;
; TO DO:
; Add CTOP option?
;-
ON_ERROR,2
;
; Memorise how graphics device was initially set up (to be returned to at end)
;
pregion=!p.region
if keyword_set(inverse) or keyword_set(invert) then cinvert=1B
;
; Decide whether or not (and what size) to draw a colour bar
;
if keyword_set(cbar) then begin
if cbar eq 1 then cbar_orient="horizontal" else cbar_orient="vertical"
endif else if keyword_set(vbar) then begin
cbar_orient="vertical"
endif else if keyword_set(colbar) then begin
cbar_orient="horizontal"
endif else cbar_orient="none"
if not keyword_set(cgap) then cgap=0.08
if not keyword_set(csize) then csize=0.08 & csize=csize<(1-cgap)
if keyword_set(cfraction) then cfraction=1(csize+cgap) else cfraction=csize+cgap
if keyword_set(clog) and not keyword_set(ctickformat) then begin
;ctickformat='("10!u",I0,"!n")'
;ctickinterval=1
endif
if keyword_set(csqrt) and not keyword_set(ctickformat) then begin
ctickformat='("!7S!X",A0)'
ctickinterval=1
endif
;
; Parse input image data
;
if not keyword_set(image) then message,"Usage: shapelets_plot_image,image"
if shapelets_structure_type(image,message=message,/silent) then begin
if image.type eq "image" or image.type eq "pstamp" then a=float(image.image) else message,"You need to input an image!"
endif else begin
a=float(image)
endelse
;
; Hack to get around the fact that tv can't handle 1D arrays
;
n_dimensions=size(a,/N_DIMENSIONS)
if n_dimensions eq 1 then begin
a=reform(a,n_elements(a),1)#[1,1]
n_dimensions=2
endif
;
; Cope with both monochrome and [r,g,b] full colour images
;
if n_dimensions eq 2 then begin
if keyword_set(xrange) then a=a[xrange[0]:xrange[1],*] ; Ugly: this can make it 1D again
if keyword_set(yrange) then a=a[*,yrange[0]:yrange[1]]
if n_elements(uniq(a)) eq 1 then message,"WARNING: All pixels in the image have the same value!",/info,NOPRINT=silent
nx=(size(a,/DIMENSIONS))[0]
ny=(size(a,/DIMENSIONS))[1]
endif else if n_dimensions eq 3 then begin
if not keyword_set(true) then begin
true_new=where(size(a,/DIMENSIONS) eq 3,n_three_elements)
if n_three_elements ne 1 then $
message,"Keyword TRUE is required to plot a colour image!"
endif else true_new=true
data_dimensions=where((indgen(3)+1) ne true_new)
nx=(size(a,/DIMENSIONS))[data_dimensions[0]]
ny=(size(a,/DIMENSIONS))[data_dimensions[1]]
endif else message,"Input variable is "+strtrim(string(n_dimensions),2)+"D!"
;
; Figure out what kind of plot we are making
; (if we're plotting to postscript, the pixels should be scalable)
;
if n_elements(scalable) eq 0 then $
if strupcase(!d.name) eq "PS" then scalable=1 else scalable=0
;
; Decide colour range
;
if not keyword_set(crange) then begin
; Exclude zero pixels (for example a border) from the calculation of the colour scale
if not keyword_set(cnozero) then anozero=a else begin
anozero=where(a ne 0,n_anozero)
if n_anozero gt 0 then anozero=a[anozero] else anozero=a
endelse
if keyword_set(clog) then begin
orders_of_magnitude=4
crange_lower=(alog10(abs(median(anozero)))-orders_of_magnitude/2)>min(alog10(abs(anozero)))
crange_upper=(alog10(abs(median(anozero)))+orders_of_magnitude/2)0)
message,"Plotting square root of image",/INFO,NOPRINT=silent
crange=sqrt(crange>0)
endif
; Map image to color indices
if not keyword_set(crange) then begin
; if keyword_set(inverse) then b=-a else $
b=a
b_ran=[min(b),max(b)]
b=(b-b_ran[0])/(b_ran[1]-b_ran[0])*(!d.table_size-1) ; this is equivalent to tvscl
endif else begin
if !d.table_size ge 256 then begin
b=((crange[0]>aa!p.region[0]
;!p.region[3]=!p.region[3]>!p.region[1]
; Take into account space for the colour bar
case cbar_orient of
"none": !p.region=position
"horizontal": !p.region=position-[0,0,0,cfraction*(position[3]-position[1])]
"vertical": !p.region=position-[0,0,cfraction*(position[2]-position[0]),0]
endcase
;
; Scale image to the frame size
;
; Set up the coordinate frame
plot,[0],[0],/nodata,xstyle=12,ystyle=12,noerase=noerase
if not keyword_set(scalable) then begin
;
; Non-scalable pixel case (to be used for xterm device)
;
if keyword_set(frame) then begin
px=!x.window[0]*!d.x_vsize ; position of window in device pixels
py=!y.window[0]*!d.y_vsize
sx=abs((!x.window[1]-!x.window[0])*!d.x_vsize+1) ; desired size of image in pixels
sy=abs((!y.window[1]-!y.window[0])*!d.y_vsize+1)
endif else begin
px=!x.region[0]*!d.x_vsize ; position of window in device pixels
py=!y.region[0]*!d.y_vsize
sx=abs((!x.region[1]-!x.region[0])*!d.x_vsize+1) ; desired size of image in pixels
sy=abs((!y.region[1]-!y.region[0])*!d.y_vsize+1)
endelse
if keyword_set(isotropic) then begin
sx=(((sx/nx)<(sy/ny))*nx)>1
sy=(((sx/nx)<(sy/ny))*ny)>1
frame_position=[!x.window[0],!y.window[0],$
(float(sx)*float(!d.y_vsize)/float(sy)/float(!d.x_vsize)*$
float(!y.window[1]-!y.window[0]+1/!d.y_vsize)+!x.window[0]-1/!d.x_vsize)!d.n_colors<512),FRAME=-1,TITLE=ctitle,NOERASE=noerase,CINVERT=cinvert,color=color
plot,[0],[0],/NODATA,/NOERASE,XRANGE=keyword_set(clog)?10^crange:crange,/XSTYLE,TITLE=ctitle,$
XTHICK=cthick,YTHICK=cthick,XLOG=clog,COLOR=color,$
XMINOR=cminor,YMINOR=1,YTICKS=1,YTICKNAME=[" "," "],XCHARSIZE=ccharsize,$
XTICK_GET=ctick_get,XTICKINTERVAL=ctickinterval,$
XTICKLAYOUT=cticklayout,TICKLEN=cticklen,XTICKNAME=ctickname,$
XTICKS=cticks,XTICKUNITS=ctickunits,XTICKV=ctickv,XTICKFORMAT=ctickformat
if n_elements(contour_levels) gt 0 then for i=0,n_elements(contour_levels)-1 do begin
if n_elements(contour_linestyle) gt i then contour_linestylei=contour_linestyle[i]
if n_elements(contour_colour) gt i then contour_colouri=contour_colour[i]
if n_elements(contour_thick) gt i then contour_thicki=contour_thick[i]
oplot,replicate(contour_levels[i],2),[0,1],psym=-3,$
linestyle=contour_linestylei,thick=contour_thicki,color=contour_colouri
endfor
!p.region=position-[0,0,0,cfraction*(position[3]-position[1])]
!x.margin=xmargin
!y.margin=[ymargin[0],0]
end
"vertical": begin
!x.margin[0]=0;=[0,0]
!y.margin[1]=0
!p.multi[0]=!p.multi[0]+1
!p.region[0]=frame_position[2]+cgap
!p.region[1]=position[1]
!p.region[2]=frame_position[2]+cgap+csize
!p.region[3]=frame_position[3]
;!p.region=position+[(1-csize)*(position[2]-position[0]),0,0,frame_position[3]-position[3]]
shapelets_plot_image,transpose(findgen(8>!d.n_colors<512)),FRAME=-1,TITLE=ctitle,NOERASE=noerase,CINVERT=cinvert,color=color
plot,[0],[0],/NODATA,/NOERASE,YRANGE=keyword_set(clog)?10^crange:crange,/YSTYLE,TITLE=ctitle,$
XTHICK=cthick,YTHICK=cthick,YLOG=clog,color=color,$
YMINOR=cminor,XMINOR=1,XTICKS=1,XTICKNAME=[" "," "],YCHARSIZE=ccharsize,$
YTICK_GET=ctick_get,YTICKINTERVAL=ctickinterval,$
YTICKLAYOUT=cticklayout,TICKLEN=cticklen,YTICKNAME=ctickname,$
YTICKS=cticks,YTICKUNITS=ctickunits,YTICKV=ctickv,YTICKFORMAT=ctickformat
if n_elements(contour_levels) gt 0 then for i=0,n_elements(contour_levels)-1 do begin
if n_elements(contour_linestyle) gt i then contour_linestylei=contour_linestyle[i]
if n_elements(contour_colour) gt i then contour_colouri=contour_colour[i]
if n_elements(contour_thick) gt i then contour_thicki=contour_thick[i]
oplot,[0,1],replicate(contour_levels[i],2),psym=-3,$
linestyle=contour_linestylei,thick=contour_thicki,color=contour_colouri
endfor
!p.region=position-[0,0,cfraction*(position[2]-position[0]),0]
!x.margin=[xmargin[0],0]
end
"none":
endcase
;
; Plot image
;
tv,b,px,py,xsize=sx,ysize=sy,true=true_new,$
device=1-keyword_set(scalable),normal=keyword_set(scalable)
;
; Overlay frame
;
;case cbar_orient of
; "none": !p.region=position
; "horizontal": !p.region=position-[0,0,0,cfraction*(position[3]-position[1])]
; "vertical": !p.region=position-[0,0,cfraction*(position[2]-position[0]),0]
;endcase
if n_elements(frame) eq 4 then begin
xrange_local=[frame[0],frame[1]] & yrange_local=[frame[2],frame[3]]
endif else begin
if keyword_set(xrange) then xrange_local=xrange else xrange_local=[0,nx]
if keyword_set(yrange) then yrange_local=yrange else yrange_local=[0,ny]
endelse
if keyword_set(xstyle) then xstyle_local=xstyle else xstyle_local=1
if keyword_set(ystyle) then ystyle_local=ystyle else ystyle_local=1
if keyword_set(frame) then if not (n_elements(frame) eq 1 and frame[0] eq -1) then begin
plot,[0],[0],/nodata,/noerase,position=frame_position,color=color, $
XSTYLE=xstyle_local,YSTYLE=ystyle_local,XRANGE=xrange_local,YRANGE=yrange_local, $
XTICKNAME=xtickname,YTICKNAME=ytickname, $
XTICKFORMAT=xtickformat,YTICKFORMAT=ytickformat, $
XTITLE=XTITLE,YTITLE=ytitle,_extra= ex
endif
!x.margin=xmargin
!y.margin=ymargin
;
; Overlay contours
;
if n_elements(contour_levels) gt 0 and nx
Return to the shapelets web page or the code help menu.
Last modified on 2nd Mar 2009 by
Richard Massey.