; docformat = 'rst' ; ; NAME: ; cgColorbar ; ; PURPOSE: ; The purpose of this routine is to add a color bar to the current graphics window. ; ;******************************************************************************************; ; ; ; Copyright (c) 2011, by Fanning Software Consulting, Inc. All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; ; ;+ ; The purpose of this routine is to add a color bar to the current graphics window. ; ; .. image:: cgcolorbar2.png ; ; .. image:: cgcolorbar4.png ; ; .. image:: cgcolorbar1.png ; ; .. image:: cgcolorbar5.png ; ; The program requires the `Coyote Library ` ; to be installed on your machine. ; ; :Categories: ; Graphics ; ; :Keywords: ; addcmd: in, optional, type=boolean, default=0 ; Set this keyword to add the command to the resizeable graphics window cgWindow. ; annotatecolor: in, optional, type=string, default="opposite" ; The name of the "annotation color" to use. The names are those for ; cgCOLOR. If this keyword is used, the annotation color is loaded after ; the color bar is displayed. This keyword is provided to maintain backward ; compatibility, but also to solve the potential problem of an extra line showing up ; in the color bar when the COLOR keyword is used in indexed color mode. In other words, ; use ANNOTATECOLOR in place of COLOR for complete color model independent results. ; bottom: in, optional, type=integer, default=0 ; The lowest color index of the colors to be loaded in the color bar. ; brewer: in, optional, type=boolean, default=0 ; This keyword is used only if the `CTIndex` keyword is used to select a color table number. ; Setting this keyword allows Brewer color tables to be used. ; charpercent: in, optional, type=float, default=0.85 ; A value from 0.0 go 1.0 that is multiplied by the CHARSIZE to produce ; the character size for the color bar. This value is only used if CHARSIZE is ; undefined. This keyword is primarily useful for using color bars in resizeable ; graphics windows (cgWindow). ; charsize: in, optional, type=float ; The character size of the color bar annotations. Default is cgDefCharsize()*charPercent. ; clamp: in, optional, type=float ; A two-element array in data units. The color bar is clamped to these ; two values. This is mostly of interest if you are "window-leveling" ; an image. The clamp is set to the "window" of the color bar. ; Normally, when you are doing this, you would like the colors outside ; the "window" to be set to a neutral color. Use the NEUTRALINDEX keyword ; to set the netural color index in the color bar. (See the Examples section ; for more information.) ; color: in, optional, type=string ; The name of the color to use for color bar annotations. Ignored unless passed ; the name of a cgColor color. The default value is to use the ANNOTATECOLOR. ; ctindex: in, optional, type=integer ; The index number of a color table. The `Brewer` and `Reverse` keywords will be checked ; to see how to load the color table into the `Palette` keyword. This keyword will take ; precidence over any colors that are loaded with the `Palette` keyword. ; discrete: in, optional, type=boolean, default=0 ; Set this keyword to configure certain properties of the color bar to make ; discrete color blocks for the color bar. This works best if you are using ; a handful of colors in the color bar (e.g, 8-16). ; divisions: in, optional, type=integer, default=0 ; The number of divisions to divide the bar into. There will be (divisions + 1) annotations. ; When set to 0 (the default), the IDL Plot command detemines the number of divisions used. ; fit: in, optional, type=boolean, default=0 ; If this keyword is set, the colorbar "fits" itself to the normalized ; coordinates of the last graphics command executed. In other words, for ; a horizontal color bar, postition[[0,2]] = !X.Window, and for a vertical ; color bar, position[[1,3]] = !Y.Window. Other positions are adjusted ; to put the colorbar "reasonably" close to the plot. The fit many not always ; be accurate. If you are fitting to an image, be sure to set the SAVE keyword ; on cgImage to establish a data coordinate system. ; font: in, optional, type=integer, default=!P.Font ; Sets the font of the annotation. Hershey: -1, Hardware:0, True-Type: 1. ; format: in, optional, type=string, default="" ; The format of the color bar annotations. The dfault is to let the IDL Plot command ; determine how the color bar labels are formatted. ; invertcolors: in, optional, type=boolean, default=0 ; Setting this keyword inverts the colors in the color bar. ; maxrange: in, optional ; The maximum data value for the color bar annotation. Default is NCOLORS. ; minrange: in, optional, type=float, default=0.0 ; The minimum data value for the bar annotation. ; minor: in, optional, type=integer, default=2 ; The number of minor tick divisions. ; ncolors: in, optional, type=integer, default=256 ; This is the number of colors in the color bar. ; neutralindex: in, optional, type=integer ; This is the color index to use for color bar values outside the ; clamping range when clamping the color bar with the CLAMP keyword. ; If this keyword is absent, the highest color table value is used ; for low range values and the lowest color table value is used ; for high range values, in order to provide contrast with the ; clamped region. (See the Examples section for more information.) ; nodisplay: in, optional ; This keyword is obsolete and is no longer used. ; oob_factor: in, optional, type=float, default=1.0 ; The default is to make the length of the out-of-bounds triangle the ; same distance as the height (or width, in the case of a vertical ; color bar) of the color bar. If you would prefer a shorted triangle length, ; set this keyword to a value less than zero (e.g., 0.5). If you prefer a ; longer length, set this keyword to a value greater than zero. The "standard" ; length will be multiplied by this value. ; oob_high: in, optional, type=string ; The name of an out-of-bounds high color. This color will be represented ; by a triangle on the right or top of the color bar. If the color is ; a string byte value (e.g., "215"), then this color in the current color ; table is used. The color can also be a three-element color triple ; (e.g., [240, 200, 65]). Note, you can CANNOT use a long integer as ; a color table index number with this keyword. If you want to use a ; color table index number, be sure the number is a short integer, byte ; value, or a string (e.g, OOB_HIGH=200S, OOB_HIGH=200B, or OOB_HIGH='200'). ; oob_low: in, optional, type=string ; The name of an out-of-bounds low color. This color will be represented ; by a triangle on the left or bottom of the color bar. If the color is ; a string byte value (e.g., "215"), then this color in the current color ; table is used. The color can also be a three-element color triple ; (e.g., [240, 200, 65]). Note, you can CANNOT use a long integer as ; a color table index number with this keyword. If you want to use a ; color table index number, be sure the number is a short integer, byte ; value, or a string (e.g, OOB_HIGH=200S, OOB_HIGH=200B, or OOB_HIGH='200'). ; palette: in, optional, type=byte ; A color palette containing the RGB color vectors to use for the color ; bar. The program will sample NCOLORS from the color palette. ; position: in, optional, type=float ; A four-element array of normalized coordinates in the same ; form as the POSITION keyword on a plot. Default is[0.88, 0.10, 0.95, 0.90] ; for a vertical bar and [0.10, 0.88, 0.90, 0.95] for a horizontal bar. ; See the FIT keyword, also. ; range: in, optional, type=float ; A two-element vector of the form [min, max]. Provides an alternative ; and faster way way of setting the MINRANGE and MAXRANGE keywords. ; reverse: in, optional, type=boolean, default=0 ; An alternative keyword name (one I can actually remember!) for the INVERTCOLORS keyword. ; It reverses the colors in the color bar. ; right: in, optional, type=boolean, default=0 ; This puts the labels on the right-hand side of a vertical color bar. It applies ; only to vertical color bars. ; tickinterval: in, optional, type=float ; Set this keyword to the interval spacing of major tick marks. Use this keyword in ; place of XTickInterval or YTickInterval keywords. ; ticklen: in, optional, type=float, default=0.25 ; Set this keyword to the major tick length desired. Default is 0.25. Setting this ; keyword to a value greater than or equal to 0.5 will result in major tick marks ; extending the width of the color bar. Note that setting this keyword to 0.3 or ; greater will result in minor tick mark lengths being set to 0.01, which is almost ; too small to be seen. All direct graphics tick marks act in this (strange!) way. ; ticknames: in, optional, type=string ; A string array of names or values for the color bar tick marks. There should be ; `divisions` + 1 tick names in the array. ; title: in, optional, type=string, default="" ; This is title for the color bar. The default is to have no title. ; tcharsize: in, optional, type=float ; The title size. By default, the same as `Charsize`. Note that this keyword is ; ignored for vertical color bars unless the title location (`TLocation`) is on ; the opposite side of the color bar from the color bar labels. This is a consequence ; of being upable to determine the length of color bar labels programmatically in this ; orientation. ; textthick: in, optional, type=float, default=1.0 ; Sets the thickness of the textual annotations on the color bar. ; tlocation: in, optional, type=string ; The title location, which allows the user to set the title location independently ; of the colorbar labels. May be "TOP" or "BOTTOM" for horizontal color bars, and ; "LEFT" or "RIGHT" for vertical color bars. ; top: in, optional, type=boolean, default=0 ; This puts the labels on top of the bar rather than under it. The keyword only ; applies if a horizontal color bar is rendered. ; vertical: in, optional, type=boolean, default=0 ; Setting this keyword give a vertical color bar. The default is a horizontal color bar. ; window: in, optional, type=boolean, default=0 ; Set this keyword to display the plot in a resizeable graphics window (cgWindow). ; xlog: in, optional, type=boolean, default=0 ; Set this keyword to use logarithmic scaling for the colorbar data range. ; xtickinterval: in, optional, type=float ; This keyword is trapped, but unused. Please use the`TickInterval` keyword instead. ; xticklayout: in, optional, type=integer, default=0 ; See the Plot graphics kewyords for an example. Used here only to track this keyword. ; xtitle: in, optional, type=string ; This keyword is ignored. Use the `Title` keyword to set a title for the color bar. ; ylog: in, optional, type=boolean, default=0 ; Set this keyword to use logarithmic scaling for the colorbar data range. ; ytickinterval: in, optional, type=float ; This keyword is trapped, but unused. Please use the`TickInterval` keyword instead. ; yticklayout: in, optional, type=integer, default=0 ; See the Plot graphics kewyords for an example. Used here only to track this keyword. ; ytitle: in, optional, type=string ; This keyword is ignored. Use the `Title` keyword to set a title for the color bar. ; _ref_extra: in, optional ; Any keyword appropriate for the PLOT and AXIS commands is also accepted by keyword ; inheritance. ; ; :Examples: ; To display a horizontal color bar above a contour plot, type:: ; ; cgLOADCT, 5, NCOLORS=100 ; cgCONTOUR, DIST(31,41), POSITION=[0.15, 0.15, 0.95, 0.75], $ ; C_COLORS=INDGEN(25)*4, NLEVELS=25 ; cgCOLORBAR, NCOLORS=100, POSITION=[0.15, 0.85, 0.95, 0.90] ; ; Example using the `Clamp` and `NeutralIndex` keywords:: ; ; cgLOADCT, 33, NCOLORS=254 ; TVLCT, cgCOLOR('gray', /TRIPLE), 255 ; cgCOLORBAR, NCOLORS=254, NEUTRALINDEX=255, RANGE=[0,1500], $ ; DIVISIONS=8, CLAMP=[400, 800] ; ; Additional examples can be found in the article `Adding a Color Bar `. ; ; :Author: ; FANNING SOFTWARE CONSULTING:: ; David W. Fanning ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com ; ; :History: ; Change History:: ; Written by: David W. Fanning, 4 February 2011, as a direct descendant of cgColorbar. ; Program developement stopped on cgColorbar as of this date, and this program has ; become a part of the Coyote Graphics System. ; Added FIT keyword. 28 Feb 2011. DWF ; Made default character size cgDefCharsize*0.85. 28 Feb 2011. DWF. ; Modified error handler to restore the entry decomposition state if there is an error. 17 March 2011. DWF ; Added CHARPERCENT keyword 18 March 2011. DWF. ; Added XTITLE and YTITLE keywords, which do nothing except prevent these keywords ; from being used inadvertently. 27 May 2011. DWF. ; Fixed a problem with assigning the color with the ANNOTATECOLOR keyword in the ; Z-graphics buffer. 30 Aug 2011. DWF. ; Changed the default DIVISIONS to 0 and the default FORMAT to "". 2 Sept 2011. DWF. ; Added code that will force MINRANGE and MAXRANGE values to be scalars. 5 Sept 2011. DWF. ; Problem with division by zero when FORMAT is not default value. Now, if format ; is the default value, then default is DIVISIONS=0, else DIVISIONS=6. ; Documented the TICKLEN keyword and set the default tick length to 0.25. 3 Oct 2011. DWF. ; Added the OOB_FACTOR, OOB_HIGH and OOB_LOW keywords. 5 Dec 2011. DWF. ; Added DISCRETE keyword. 7 Dec 2011. DWF. ; Changed the way the top axis was drawn, and had a problem with EXTRA keywords. Fixed. 20 Dec 2011. DWF. ; Modified to use cgDefaultColor for default color selection. 24 Dec 2011. DWF. ; Fixed a problem with color palettes by defining NCOLORS according to the number of colors ; in the palette. 19 March 2012. DWF. ; Set the maximum number of divisions at 59 to recognize the IDL plot limit for tick marks. 19 March 2012. DWF. ; Modifications to the FIT algorithm to make sure the color bar is completely inside ; the graphics window. Also fixed mis-spelled variable name. 20 March 2012. DWF. ; Added TickInterval, XTickInterval and YTickInterval keywords to accommodate interval ; spacing of major tick marks. 21 July 2012. DWF. ; Added the ability to use escape characters in plot titles to specify cgSymbol symbols. 27 July 2012. DWF. ; Added TLOCATION and TCHARSIZE keywords. 20 September 2012. DWF. ; Implemented a fix that will allow the user to specify a tick formatting function name ; with the FORMAT keyword. 21 September 2012. DWF. ; Fixed a problem in which setting the RANGE keyword gave different results, depending upon whether ; a FORMAT keyword was used or not. This change will affect the default color bar labeling ; *if* the user specifies a range. If you prefer the old labeling behavior, simiply set ; the `Divisions` keyword to 0. 16 Oct 2012. DWF. ; Added CTINDEX, and BREWER keywords to make loading a color table palette easier. 20 October 2012. DWF. ; Fixed a strange interaction between TickInterval and the Format keywords. 5 Nov 2012. DWF. ; Changes to support a tick formatting function when a log axis is used. 7 February 2013. DWF. ; Added XTICKLAYOUT and YTICKLAYOUT keywords. 8 February 2013. DWF. ; Somehow the default AnnotateColor had gotten changed from "opposite". Restored. 18 Feb 2013. DWF. ; Greatly simplified the code and turned over the responsibility of doing tick formatting and setting ; the number of divisions, etc. to the PLOT command. I do this with some trepidation, because it ; is a big change, but I think it will lead to better results in the long run and won't affect ; current IDL programs much, if at all. 27 Feb 2013. DWF. ; Added TEXTTHICK keyword to change the thickness of the textual annotations. 28 Feb 2013. DWF. ; Added more error handling for bad POSITION values. 26 July 2013. DWF. ; Modified the code so that the original input POSITION values are not changed by the ; program code. 8 August 2013. DWF. ; The check for a valid position is now done before the colorbar is drawn so that ; a colorbar sans axes is not left dangling on the display. 25 September 2013. Matthew Argall ; The TextThick keyword value was not being applied correctly when the text was written on the right ; of a vertical colorbar or at the top of a horizontal colorbar. 27 March 2015. DWF. ; ; :Copyright: ; Copyright (c) 2008-2015, Fanning Software Consulting, Inc. ;- PRO cgColorbar, $ ADDCMD=addcmd, $ ANNOTATECOLOR=annotatecolor, $ BOTTOM=bottom, $ BREWER=brewer, $ CHARPERCENT=charpercent, $ CHARSIZE=charsize, $ CLAMP=clamp, $ COLOR=color, $ CTINDEX=ctindex, $ DISCRETE=discrete, $ DIVISIONS=divisions, $ FIT=fit, $ FONT=font, $ FORMAT=format, $ INVERTCOLORS=invertcolors, $ MAXRANGE=maxrange, $ MINOR=minor, $ MINRANGE=minrange, $ NCOLORS=ncolors, $ NEUTRALINDEX=neutralIndex, $ NODISPLAY=nodisplay, $ OOB_FACTOR=oob_factor, $ OOB_HIGH=oob_high, $ OOB_LOW=oob_low, $ PALETTE=palette, $ POSITION=origpos, $ RANGE=range, $ REVERSE=reverse, $ RIGHT=right, $ TCHARSIZE=tcharsize, $ TEXTTHICK=textthick, $ TLOCATION=tlocation, $ TICKINTERVAL=tickinterval, $ TICKLEN=ticklen, $ TICKNAMES=ticknames, $ TITLE=title, $ TOP=top, $ VERTICAL=vertical, $ XLOG=xlog, $ XTICKINTERVAL=xtickinterval, $ XTICKLAYOUT=xticklayout, $ XTITLE=xtitle, $ ; Ignored. YLOG=ylog, $ YTICKINTERVAL=ytickinterval, $ YTICKLAYOUT=yticklayout, $ YTITLE=ytitle, $ ; Ignored WINDOW=window, $ _REF_EXTRA=extra Compile_Opt idl2 ; Catch the error. Catch, theError IF theError NE 0 THEN BEGIN Catch, /CANCEL void = cgErrorMsg() IF N_Elements(currentState) NE 0 THEN cgSetColorState, currentState RETURN ENDIF ; Should this be added to a resizeable graphics window? IF (Keyword_Set(window) OR Keyword_Set(addcmd)) AND ((!D.Flags AND 256) NE 0) THEN BEGIN IF Keyword_Set(addcmd) THEN window = 0 void = cgQuery(COUNT=wincnt) IF wincnt EQ 0 THEN cgWindow cgWindow, 'cgColorbar', $ ANNOTATECOLOR=annotatecolor, $ BOTTOM=bottom, $ BREWER=brewer, $ CHARPERCENT=charpercent, $ CHARSIZE=charsize, $ CLAMP=clamp, $ COLOR=color, $ CTINDEX=ctindex, $ DISCRETE=discrete, $ DIVISIONS=divisions, $ FIT=fit, $ FONT=font, $ FORMAT=format, $ INVERTCOLORS=invertcolors, $ MAXRANGE=maxrange, $ MINOR=minor, $ MINRANGE=minrange, $ NCOLORS=ncolors, $ NEUTRALINDEX=neutralIndex, $ NODISPLAY=nodisplay, $ OOB_FACTOR=oob_factor, $ OOB_HIGH=oob_high, $ OOB_LOW=oob_low, $ PALETTE=palette, $ POSITION=origpos, $ RANGE=range, $ REVERSE=reverse, $ RIGHT=right, $ TCHARSIZE=tcharsize, $ TEXTTHICK=textthick, $ TLOCATION=tlocation, $ TICKINTERVAL=tickinterval, $ XTICKLAYOUT=xticklayout, $ TICKLEN=ticklen, $ TICKNAMES=ticknames, $ TITLE=title, $ TOP=top, $ VERTICAL=vertical, $ XLOG=xlog, $ XTICKINTERVAL=xtickinterval, $ XTITLE=xtitle, $ ; Ignored. YLOG=ylog, $ YTICKINTERVAL=ytickinterval, $ YTICKLAYOUT=yticklayout, $ YTITLE=ytitle, $ REPLACECMD=Keyword_Set(window), $ ADDCMD=Keyword_Set(addcmd), $ _EXTRA=extra RETURN ENDIF ; Do you have an original position vector? If so, copy it here to avoid ; changing the original input position in the code below. IF (N_Elements(origpos) NE 0) THEN position = origpos ; Get the current color table vectors. TVLCT, r, g, b, /GET ; Default values. IF (N_Elements(charPercent) EQ 0) $ THEN charPercent = 0.85 $ ELSE charPercent = 0.0 > charPercent < 1.0 ; Did you specify a color table index? IF N_Elements(ctindex) NE 0 THEN BEGIN cgLoadCT, ctindex, Brewer=brewer, RGB_TABLE=palette ENDIF ; If you have a palette, load the colors now. Otherwise whatever colors ; are in the current color table will be used. IF N_Elements(palette) NE 0 THEN BEGIN IF Size(palette, /N_DIMENSIONS) NE 2 THEN Message, 'Color palette is not a 3xN array.' dims = Size(palette, /DIMENSIONS) threeIndex = Where(dims EQ 3) IF ((threeIndex)[0] LT 0) THEN Message, 'Color palette is not a 3xN array.' IF threeIndex[0] EQ 0 THEN BEGIN palette = Transpose(palette) npalColors = dims[1] ENDIF ELSE npalColors = dims[0] IF N_Elements(ncolors) EQ 0 THEN ncolors = npalColors TVLCT, palette TVLCT, rr, gg, bb, /Get ENDIF ; Set up PostScript device for working with colors. IF !D.Name EQ 'PS' THEN Device, COLOR=1, BITS_PER_PIXEL=8 ; Save the current plot state. bang_p = !P bang_x = !X bang_Y = !Y bang_Z = !Z bang_Map = !Map ; Are scalable pixels available on the device? IF (!D.Flags AND 1) NE 0 THEN scalablePixels = 1 ELSE scalablePixels = 0 ; Which release of IDL is this? thisRelease = Float(!Version.Release) ; Check and define keywords. SetDefaultValue, ncolors, 256 SetDefaultValue, divisions, 0 ; Let the PLOT command decide. SetDefaultValue, bottom, 0B SetDefaultValue, charsize, cgDefCharsize() * charPercent SetDefaultValue, tcharsize, charsize SetDefaultValue, textthick, 1.0 SetDefaultValue, format, "" ; Let the PLOT command decide. IF N_Elements(nodisplay) EQ 0 THEN nodisplay = 1 minrange = (N_ELEMENTS(minrange) EQ 0) ? 0. : Float(minrange[0]) maxrange = (N_ELEMENTS(maxrange) EQ 0) ? Float(ncolors) : Float(maxrange[0]) SetDefaultValue, ticklen, 0.25 SetDefaultValue, minor, 2 IF N_ELEMENTS(range) NE 0 THEN BEGIN minrange = Float(range[0]) maxrange = Float(range[1]) ENDIF SetDefaultValue, font, !P.Font SetDefaultValue, title, "" IF N_Elements(title) NE "" THEN title = cgCheckForSymbols(title) SetDefaultValue, oob_factor, 1.0 xlog = Keyword_Set(xlog) ylog = Keyword_Set(ylog) ; Deal with tick intervals, if you have them. IF Keyword_Set(vertical) THEN BEGIN IF (N_Elements(tlocation) EQ 0) THEN tlocation = Keyword_Set(right) ? 'RIGHT' : 'LEFT' IF (N_Elements(yTickInterval) NE 0) && (ylog EQ 0) THEN BEGIN IF N_Elements(tickInterval) EQ 0 THEN tickInterval = yTickInterval ENDIF ENDIF ELSE BEGIN IF (N_Elements(tlocation) EQ 0) THEN tlocation = Keyword_Set(top) ? 'TOP' : 'BOTTOM' IF (N_Elements(xTickInterval) NE 0) && (xlog EQ 0) THEN BEGIN IF N_Elements(tickInterval) EQ 0 THEN tickInterval = xTickInterval ENDIF ENDELSE ; A plot command limitation restricts the number of divisions to 59. divisions = divisions < 59 ; If needed create a window first, so the drawing ; colors are correct for the window you want to draw into. IF ((!D.Flags AND 256) NE 0) && (!D.Window LT 0) THEN cgDisplay ; If the user asked for discrete colors, set some keywords appropriately. ; This really should not be used for more than 16 or colors, but I don't ; want to limit it for the user. The maximum value is 59. IF Keyword_Set(discrete) THEN BEGIN divisions = ncolors < 59 ticklen = 1.0 minor = 0 ENDIF ; You can't have a format set *and* use ticknames. IF N_ELEMENTS(ticknames) NE 0 THEN format = "" ; Determine the position of the color bar in the window. IF KEYWORD_SET(vertical) THEN BEGIN bar = REPLICATE(1B,20) # BINDGEN(ncolors) IF Keyword_Set(invertcolors) THEN bar = Reverse(bar, 2) IF N_ELEMENTS(position) EQ 0 THEN BEGIN IF Keyword_Set(right) THEN BEGIN position = [0.83, 0.125, 0.90, 0.9] ENDIF ELSE BEGIN position = [0.88, 0.125, 0.95, 0.9] ENDELSE ENDIF ELSE BEGIN IF position[2]-position[0] GT position[3]-position[1] THEN BEGIN position = [position[1], position[0], position[3], position[2]] ENDIF ENDELSE IF Keyword_Set(fit) THEN BEGIN position[[1,3]] = !Y.Window distance = position[2] - position[0] IF Keyword_Set(right) THEN BEGIN position[0] = !X.Window[1] + ((4*!D.X_CH_SIZE*charsize) / !D.X_Size) ENDIF ELSE BEGIN position[0] = !X.Window[1] + ((10*!D.X_CH_SIZE*charsize) / !D.X_Size) ENDELSE position[2] = position[0] + distance IF position[2] GT 1.0 THEN BEGIN diff = position[2]-1.0 position[2] = 1.0 - 0.015 IF (position[2] - position[0]) LT 0.015 THEN position[0] = (position[2] < position[0])-0.015 ENDIF ENDIF ENDIF ELSE BEGIN bar = BINDGEN(ncolors) # REPLICATE(1B, 20) IF Keyword_Set(invertcolors) THEN bar = Reverse(bar, 1) IF N_ELEMENTS(position) EQ 0 THEN BEGIN IF Keyword_Set(top) THEN BEGIN position = [0.125, 0.82, 0.925, 0.90] ENDIF ELSE BEGIN position = [0.125, 0.88, 0.925, 0.95] ENDELSE ENDIF ELSE BEGIN IF position[3]-position[1] GT position[2]-position[0] THEN BEGIN position = [position[1], position[0], position[3], position[2]] ENDIF ENDELSE IF Keyword_Set(fit) THEN BEGIN position[[0,2]] = !X.Window distance = (position[3] - position[1]) position[1] = !Y.Window[1] + ((4*!D.Y_CH_SIZE*charsize) / !D.Y_Size) position[3] = position[1] + distance IF position[3] GT 1.0 THEN BEGIN diff = position[3]-1.0 position[3] = 1.0 - 0.015 IF (position[3] - position[1]) LT 0.015 THEN position[1] = (position[3] < position[1])-0.015 ENDIF ENDIF ENDELSE ; Adjust the positions if you have OOB colors. IF (N_Elements(oob_high) NE 0) || (N_Elements(oob_low) NE 0) THEN BEGIN IF Keyword_Set(vertical) THEN BEGIN length = (position[2]-position[0]) * oob_factor IF (N_Elements(oob_high) NE 0) THEN position[3] = position[3] - length IF (N_Elements(oob_low) NE 0) THEN position[1] = position[1] + length ENDIF ELSE BEGIN length = (position[3]-position[1]) * oob_factor IF (N_Elements(oob_high) NE 0) THEN position[2] = position[2] - length IF (N_Elements(oob_low) NE 0) THEN position[0] = position[0] + length ENDELSE ENDIF ; If the POSITION is screwed up, the user can get a weird error message from AXIS about a ; "data coordinate system not established". Check the position here to make sure it is right. IF position[0] GE position[2] THEN Message, 'The X POSITION coordinates cannot be reconciled.' IF position[1] GE position[3] THEN Message, 'The Y POSITION coordinates cannot be reconciled.' IF (position[0] LT 0) || (position[2] GT 1) THEN Message, 'The X POSITION cooordinates must be in the range 0 to 1.' IF (position[1] LT 0) || (position[3] GT 1) THEN Message, 'The Y POSITION cooordinates must be in the range 0 to 1.' ; Scale the color bar. IF N_Elements(clamp) NE 0 THEN BEGIN IF N_Elements(clamp) NE 2 THEN Message, 'The CLAMP keyword must be a two-element array.' byterange = BytScl(clamp, minrange, maxrange) tempbar = BytScl(bar, TOP=(ncolors-1) < (255-bottom)) + bottom bar = BytScl(bar, TOP=(ncolors-1) < (255-bottom), MIN=byterange[0], MAX=byterange[1]) + bottom IF N_Elements(neutralIndex) EQ 0 THEN BEGIN neutralBottom = (ncolors-1) < (255-bottom) neutralTop = bottom ENDIF ELSE BEGIN neutralBottom = neutralIndex neutralTop = neutralIndex ENDELSE i = Where(tempbar LT byterange[0], count) IF count GT 0 THEN bar[i] = neutralBottom i = Where(tempbar GT byterange[1], count) IF count GT 0 THEN bar[i] = neutralTop ENDIF ELSE BEGIN bar = BytScl(bar, TOP=(ncolors-1) < (255-bottom)) + bottom ENDELSE IF Keyword_Set(reverse) THEN BEGIN IF Keyword_Set(vertical) THEN bar = Reverse(bar,2) ELSE bar = Reverse(bar,1) ENDIF ; Get starting locations in NORMAL coordinates. xstart = position[0] ystart = position[1] ; Get the size of the bar in NORMAL coordinates. xsize = (position[2] - position[0]) ysize = (position[3] - position[1]) ; Let's do this in decomposed color, if possible. cgSetColorState, 1, CURRENTSTATE=currentState ; Display the color bar in the window. Sizing is ; different for PostScript and regular display. IF scalablePixels THEN BEGIN ; Display the color bar. cgSetColorState, 0 TV, bar, xstart, ystart, XSIZE=xsize, YSIZE=ysize, /Normal cgSetColorState, 1 ENDIF ELSE BEGIN bar = CONGRID(bar, CEIL(xsize*!D.X_VSize), CEIL(ysize*!D.Y_VSize)) ; Display the color bar. cgSetColorState, 0 TV, bar, xstart, ystart, /Normal cgSetColorState, 1 ENDELSE ; Get the current colortable. TVLCT, rr, gg, bb, /GET ; You can't specify both DIVISIONS and a tick interval, so fix that here. IF N_Elements(tickInterval) NE 0 THEN divisions = 0 ; Annotate the color bar. annotateColor = cgDefaultColor(annotateColor, DEFAULT='opposite') ; If color is undefined, use the annotate color. color = cgDefaultColor(color, DEFAULT=annotateColor) IF Size(annotateColor, /TNAME) EQ 'STRING' THEN annotateColor = cgColor(annotateColor) IF Size(color, /TNAME) EQ 'STRING' THEN color = cgColor(color) IF KEYWORD_SET(vertical) THEN BEGIN IF KEYWORD_SET(right) THEN BEGIN IF StrUpCase(tlocation) EQ 'LEFT' THEN BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=1, $ YTICKS=divisions, XSTYLE=1, YSTYLE=9, XTITLE="", YTITLE="", $ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ XTICKFORMAT='(A1)', YTICKFORMAT='(A1)', YMINOR=minor, _STRICT_EXTRA=extra, $ YTICKNAME=ticknames, FONT=font, YLOG=ylog, YTICKINTERVAL=tickinterval, $ YTICKLAYOUT=yticklayout, XTICKLAYOUT=xticklayout, CHARTHICK=textthick AXIS, YAXIS=1, YRANGE=[minrange, maxrange], YTICKFORMAT=format, YTICKS=divisions, $ YTICKLEN=ticklen, YSTYLE=1, COLOR=color, CHARSIZE=charsize, XTITLE="", $ FONT=font, YTITLE="", _STRICT_EXTRA=extra, YMINOR=minor, YTICKNAME=ticknames, $ YLOG=ylog, YTICKINTERVAL=tickinterval, YTICK_GET=ticks, YTICKLAYOUT=yticklayout truecharsize = Float(!D.X_CH_SIZE * tcharsize) / !D.X_SIZE yloc = (position[3] - position[1]) / 2.0 + position[1] xloc = position[0] - (1.5 * truecharsize) XYOUTS, xloc, yloc, title, /NORMAL, COLOR=color, CHARTHICK=textthick, $ ALIGNMENT=0.5, FONT=font, CHARSIZE=tcharsize, ORIENTATION=-270 ENDIF ELSE BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=1, $ YTICKS=divisions, XSTYLE=1, YSTYLE=9, XTITLE="", YTITLE="", $ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ XTICKFORMAT='(A1)', YTICKFORMAT='(A1)', YMINOR=minor, _STRICT_EXTRA=extra, $ YTICKNAME=ticknames, FONT=font, YLOG=ylog, YTICKINTERVAL=tickinterval, $ YTICKLAYOUT=yticklayout, XTICKLAYOUT=xticklayout, CHARTHICK=textthick AXIS, YAXIS=1, YRANGE=[minrange, maxrange], YTICKFORMAT=format, YTICKS=divisions, $ YTICKLEN=ticklen, YSTYLE=1, COLOR=color, CHARSIZE=charsize, XTITLE="", $ FONT=font, YTITLE=title, _STRICT_EXTRA=extra, YMINOR=minor, YTICKNAME=ticknames, $ YLOG=ylog, YTICKINTERVAL=tickinterval, YTICK_GET=ticks, YTICKLAYOUT=yticklayout, $ CHARTHICK=textThick ENDELSE ENDIF ELSE BEGIN IF StrUpCase(tlocation) EQ 'RIGHT' THEN BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=1, $ YTICKS=divisions, YSTYLE=9, XSTYLE=1, YTITLE="", CHARTHICK=textthick, $ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ XTICKFORMAT='(A1)', YTICKFORMAT=format, YMinor=minor, _STRICT_EXTRA=extra, $ YTICKNAME=ticknames, YLOG=ylog, YTICKLEN=ticklen, FONT=font, XTITLE="", $ YTICKINTERVAL=tickinterval, YTICKLAYOUT=yticklayout, XTICKLAYOUT=xticklayout AXIS, YAXIS=1, YRANGE=[minrange, maxrange], YTICKFORMAT='(A1)', YTICKS=divisions, $ YTICKLEN=0.001, YSTYLE=1, COLOR=color, CHARSIZE=charsize, XTITLE="", $ FONT=font, YTITLE="", _STRICT_EXTRA=extra, YMINOR=minor, YTICKNAME="", YLOG=ylog, $ YTICKINTERVAL=tickinterval, YTICKLAYOUT=yticklayout truecharsize = Float(!D.X_CH_SIZE * tcharsize) / !D.X_SIZE yloc = (position[3] - position[1]) / 2.0 + position[1] xloc = position[2] + (2.0 * truecharsize) XYOUTS, xloc, yloc, title, /NORMAL, COLOR=color, CHARTHICK=textthick, $ ALIGNMENT=0.5, FONT=font, CHARSIZE=tcharsize, ORIENTATION=-270 ENDIF ELSE BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=1, $ YTICKS=divisions, YSTYLE=9, XSTYLE=1, YTITLE=title, CHARTHICK=textthick, $$ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ XTICKFORMAT='(A1)', YTICKFORMAT=format, YMinor=minor, _STRICT_EXTRA=extra, $ YTICKNAME=ticknames, YLOG=ylog, YTICKLEN=ticklen, FONT=font, XTITLE="", $ YTICKINTERVAL=tickinterval, YTICKLAYOUT=yticklayout, XTICKLAYOUT=xticklayout AXIS, YAXIS=1, YRANGE=[minrange, maxrange], YTICKFORMAT='(A1)', YTICKS=divisions, $ YTICKLEN=0.001, YSTYLE=1, COLOR=color, CHARSIZE=charsize, XTITLE="", $ FONT=font, YTITLE="", _STRICT_EXTRA=extra, YMINOR=minor, YTICKNAME="", YLOG=ylog, $ YTICKINTERVAL=tickinterval, YTICKLAYOUT=yticklayout ENDELSE ENDELSE ENDIF ELSE BEGIN IF KEYWORD_SET(top) THEN BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=divisions, $ YTICKS=1, XSTYLE=9, YSTYLE=1, CHARTHICK=textthick, $ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ YTICKFORMAT='(A1)', XTICKFORMAT='(A1)', XTICKLEN=0.01, $ XRANGE=[minrange, maxrange], FONT=font, XMINOR=minor, _STRICT_EXTRA=extra, $ XTICKNAME=ticknames, XLOG=xlog, XTITLE="", YTITLE="", XTICKINTERVAL=tickInterval, $ XTICKLAYOUT=xticklayout, YTICKLAYOUT=yticklayout AXIS, XTICKS=divisions, XSTYLE=1, COLOR=color, CHARSIZE=charsize, $ XTICKFORMAT=format, XTICKLEN=ticklen, XRANGE=[minrange, maxrange], XAXIS=1, $ FONT=font, XTITLE="", _STRICT_EXTRA=extra, XMINOR=minor, $ XTICKNAME=ticknames, XLOG=xlog, YTITLE="", XTICKINTERVAL=tickInterval, $ XTICKLAYOUT=xticklayout, CHARTHICK=textThick IF title NE "" THEN BEGIN xloc = (position[2] - position[0]) / 2.0 + position[0] CASE StrUpCase(tlocation) OF 'TOP': BEGIN truecharsize = Float(!D.Y_CH_SIZE * charsize) / !D.Y_SIZE yloc = position[3] + (2.25 * truecharsize) END 'BOTTOM': BEGIN truecharsize = Float(!D.Y_CH_SIZE * tcharsize) / !D.Y_SIZE yloc = position[1] - (1.5 * truecharsize) END 'RIGHT': Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) 'LEFT': Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) ELSE: Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) ENDCASE XYOUTS, xloc, yloc, title, /NORMAL, COLOR=color, CHARTHICK=textthick, $ ALIGNMENT=0.5, FONT=font, CHARSIZE=tcharsize ENDIF ENDIF ELSE BEGIN PLOT, [minrange,maxrange], [minrange,maxrange], /NODATA, XTICKS=divisions, $ YTICKS=1, XSTYLE=9, YSTYLE=1, TITLE="", CHARTHICK=textthick, $ POSITION=position, COLOR=color, CHARSIZE=charsize, /NOERASE, $ YTICKFORMAT='(A1)', XTICKFORMAT=format, XTICKLEN=ticklen, $ XRANGE=[minrange, maxrange], FONT=font, XMinor=minor, _STRICT_EXTRA=extra, $ XTICKNAME=ticknames, XLOG=xlog, XTITLE="", YTITLE="", $ XTICKINTERVAL=tickInterval, XTICKLAYOUT=xticklayout, YTICKLAYOUT=yticklayout AXIS, XTICKS=divisions, XSTYLE=1, COLOR=color, CHARSIZE=charsize, $ XTICKFORMAT='(A1)', XTICKLEN=0.001, XRANGE=[minrange, maxrange], XAXIS=1, $ FONT=font, XTITLE="", XCHARSIZE=charsize, XMINOR=minor, $ XTICKNAME="", XLOG=xlog, YTITLE="", XTICKINTERVAL=tickInterval, XTICKLAYOUT=xticklayout IF title NE "" THEN BEGIN xloc = (position[2] - position[0]) / 2.0 + position[0] CASE StrUpCase(tlocation) OF 'TOP': BEGIN truecharsize = Float(!D.Y_CH_SIZE * charsize) / !D.Y_SIZE yloc = position[3] + (0.75 * truecharsize) END 'BOTTOM': BEGIN truecharsize = Float(!D.Y_CH_SIZE * charsize) / !D.Y_SIZE yloc = position[1] - (2.00 * truecharsize) - $ (Float(!D.Y_CH_SIZE * tcharsize) / !D.Y_SIZE) END 'RIGHT': Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) 'LEFT': Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) ELSE: Message, 'Illegal specification for title position: ' + StrUpCase(tlocation) ENDCASE XYOUTS, xloc, yloc, title, /NORMAL, COLOR=color, CHARTHICK=textthick, $ ALIGNMENT=0.5, FONT=font, CHARSIZE=tcharsize ENDIF ENDELSE ENDELSE ; If you have OOB colors, draw them now. IF (N_Elements(oob_high) NE 0) || (N_Elements(oob_low) NE 0) THEN BEGIN p = position IF Keyword_Set(vertical) THEN BEGIN IF (N_Elements(oob_high) NE 0) THEN BEGIN phalf = (p[2]-p[0])/2.0 + p[0] pdist = (p[2]-p[0]) * oob_factor PolyFill, [p[0], phalf, p[2], p[0]], $ [p[3], pdist+p[3], p[3], p[3]], /Normal, Color=cgColor(oob_high) PlotS, [p[0], phalf, p[2], p[0]], $ [p[3], pdist+p[3], p[3], p[3]], /Normal, Color=color ENDIF IF (N_Elements(oob_low) NE 0) THEN BEGIN phalf = (p[2]-p[0])/2.0 + p[0] pdist = (p[2]-p[0]) * oob_factor PolyFill, [p[0], phalf, p[2], p[0]], $ [p[1], p[1]-pdist, p[1], p[1]], /Normal, Color=cgColor(oob_low) PlotS, [p[0], phalf, p[2], p[0]], $ [p[1], p[1]-pdist, p[1], p[1]], /Normal, Color=color END ENDIF ELSE BEGIN IF (N_Elements(oob_high) NE 0) THEN BEGIN phalf = (p[3]-p[1])/2.0 + p[1] pdist = (p[3]-p[1]) * oob_factor PolyFill, [p[2], p[2]+pdist, p[2], p[2]], $ [p[1], phalf, p[3], p[1]], /Normal, Color=cgColor(oob_high) PlotS, [p[2], p[2]+pdist, p[2], p[2]], $ [p[1], +phalf, p[3], p[1]], /Normal, Color=color ENDIF IF (N_Elements(oob_low) NE 0) THEN BEGIN phalf = (p[3]-p[1])/2.0 + p[1] pdist = (p[3]-p[1]) * oob_factor PolyFill, [p[0], p[0]-pdist, p[0], p[0]], $ [p[1], phalf, p[3], p[1]], /Normal, Color=cgColor(oob_low) PlotS, [p[0], p[0]-pdist, p[0], p[0]], $ [p[1], +phalf, p[3], p[1]], /Normal, Color=color END ENDELSE ENDIF ; Restore the color state. cgSetColorState, currentState ; Restore the previous plot and map system variables. !P = bang_p !X = bang_x !Y = bang_y !Z = bang_z !Map = bang_map ; Set the current colors back. IF !D.Name NE 'Z' THEN TVLCT, r, g, b END