TVMAP cheat sheet

From Geos-chem
Revision as of 19:08, 16 September 2022 by Bmy (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

GAMAP is now obsolete. We recommend using GCPy for analyzing output from recent GEOS-Chem versions. But we will preserve the GAMAP wiki documentation for reference.



This cheat sheet shows some of the most useful features of TVMAP that can be quickly tested at the command line (IDL prompt)... and used in your own programs.

Default behavior

Check:

DATA = DIST(30,20)
TVMAP, DATA
TVMAP, DATA, /SAMPLE, /CBAR

This is the same as (showing the implicit lon/lat range associated with the data):

DATA = DIST(30,20)
LON =-180. + findgen(30)*12 + 6. ; box center
LAT = -90. + findgen(20)* 9 + 4.5 ; box center
TVMAP, DATA, lon, lat

Zooming

To zoom, there is no need to cut the data to the window size, just use the LIMIT keyword. Compare:

TVMAP, DATA, LON, LAT, /GRID, /CONTINENTS
TVMAP, DATA, LON, LAT, /GRID, /CONTINENTS, LIMIT=[-10,0.,60.,25.]

Note that if you do not pass the LON and LAT associated to DATA, only the map is zoomed. Compare:

TVMAP, DATA, /GRID, /CONTINENTS, LIMIT=[-10,0.,60.,25.]
TVMAP, DATA, LON, LAT, /GRID, /CONTINENTS, LIMIT=[-10,0.,60.,25.]

It is strongly recommended to specify LON and LAT all the time.

LIMIT keyword tip

The following can be handy in a program, where you sometimes need to set the LIMIT. Setting LIMIT to 0 is the same as not setting it:

TVMAP, DATA, LIMIT=0

Out-Of-Range data and Colorbar

with a (default) white box

To indicate data below (above) a specific value, use MIN_VALID (MAX_VALID):

TVMAP, DATA, MIN_VALID=5., /SAMPLE, /CBAR

with a Triangle instead of a box

TVMAP, DATA, MIN_VALID=5., /TRIANGLE, /sample, /CBAR

with a non-white box

Use BotOutOfRange (TopOutOfRange) to specify the color for data below MIN_VALID (above MAX_VALID):

TVMAP, DATA, BOTOUTOFRANGE=!myct.gray50, MIN_VALID=5., /SAMPLE, /CBAR

with a non-white triangle

Combine Triangle and BotOutOfRange:

TVMAP, DATA, BOTOUTOFRANGE=2, MIN_VALID=5., /TRIANGLE, /CBAR

without any indication in the colorbar

Use a negative color index:

TVMAP, DATA, BOTOUTOFRANGE=-2, MIN_VALID=5., /SAMPLE, /CBAR

Tip: To denote out-of-range data with WHITE, but without a box or triangle in the colorbar, you must use the color index -17. White is available as index 0 and 17 with the standard set of colors of Gamap !MyCT.

TVMAP, DATA, BOTOUTOFRANGE=-17, MIN_VALID=5., /CBAR, /SAMPLE

Conditional insertion of triangles

Here is a wrapper that automatically add a triangle if, and only if, there is out of range data:

PRO WRAP_TVMAP, data, lon, lat, range, BOOR=BOORi, TOOR=TOORi, _extra=e

  ; Default values
  ; ---------------------------
  minvalid = range[0]  &   maxvalid = range[1]  &   triangle = 1
  BOOR = keyword_set( boori ) ? boori : !myct.bottom
  TOOR = keyword_set( toori ) ? toori : !myct.bottom+!myct.ncolors


  ; Check for out-of-range data
  ; ---------------------------
  cr  = range[sort(range)]
  nim = min(data, max=xam, /NaN)

  if ~ (nim lt cr[0] or xam gt cr[1]) then $
     UNDEFINE, minvalid, maxvalid, toor, boor, triangle
   

  ; Map plot
  ; ---------------------------
  TVMAP, data, LON,  LAT, /cbar, /continents, /sample,   $
         mindata=range[0],         maxdata=range[1],     $
         cbmin=range[0],           cbmax=range[1],       $
         
         ; denote out-of-range:
         BotOutOfRange = BOOR,   TopOutOfRange=TOOR,  Triangle=triangle, $
         min_valid=minvalid,     max_valid=maxvalid,     $
         
         _extra = e

  return
end

NaN data

To deal with NaN, you can set them to a very low or high value and use the MIN/MAX_VALID keywords. But you can also directly use the NAN_COLOR keyword (default to 0):

DATA[where(data gt 6)]=!values.f_nan

TVMAP, DATA, nan_color=!myct.orange

GRIDS

One or more GRID without DATA

If you just want to plot one grid, you can use the CTM_MAPGRID routine from GAMAP. For a more general approach, use MAP_GRID, like this (several tips at once!):

 ; no grid
 MAP_SET, /ORTHOGRAPHIC, 65., -15., 0., /isotropic, COLOR=!MYCT.BLACK
 
 ; 1st grid (not global)
 lats = -78  + findgen( 79 )*2
 lons = -180 + findgen( 121 )*3
 
 MAP_GRID, LATS=LATS, LONS=LONS, glinestyle=0, COLOR=!MYCT.black
 
 ; 2nd grid (automatic generation of LONS / LATS vectors from ranges
 ; and steps)
 lon=[-30, 30] & lat= [34, 70]
 dlon=1 & dlat=0.5
 
 lats = lat[0] + findgen( fix((lat[1]-lat[0])/dlat +1) )*dlat
 lons = lon[0] + findgen( (lon[1]-lon[0])/dlon +1 )*dlon
 
 MAP_GRID, LATS=LATS, LONS=LONS, glinestyle=1, COLOR=!MYCT.red, glinethick=2
 
 ; Continents
 MAP_CONTINENTS, /COAST, /COUNTRIES, COLOR=!myct.blue, MLINETHICK=2 

Control the GRID - (1) with /GRID

Setting /GRID, TVMAP will call MAP_GRID. Then you can pass keywords to MAP_GRID through the _EXTRA facility, like specifying the location of the grid lines (see MAP_GRID documentation for more on those keywords) or black/white box axes:

tvmap, data, /contin                                            ; no grid
tvmap, data, /contin, /grid                                     ; grid
tvmap, data, /contin, /grid, /BOX_AXES                          ; passsing MAP_GRID keywords
tvmap, data, /contin, /grid, LONS=-165., LATS=[-72.,-10,5,40]   ; passsing MAP_GRID keywords

But if the MAP_GRID keyword is also a MAP_SET keyword, then MAP_SET will trigger a second call to MAP_GRID, and you end up with two grids. So you cannot pass the following MAP_GRID keywords without having two grids (although the two grids may be identical, and you may not notice!). For example:

tvmap, data, /contin, /grid, glinestyle=2 ; two grids problem
; list of keywords common to MAP_SET and MAP_GRID (do not use them with TVMAP, /GRID):
 GLINESTYLE
 GLINETHICK
 LABEL
 LATALIGN
 LATDEL
 LATLAB
 LONALIGN
 LONDEL
 LONLAB

So, this method (grid keywords along /GRID) is useful but limited to keywords unknown to MAP_SET.

However, since v2.12 of GAMAP, you can use /GRID and specify the grid \emph{spacings} with DLON and DLAT keywords. The GXLABELS and GYLABELS can also be used to label every n-th gridlines (or none if zero). Compare the following to see how things work:

data=dist(40,40)
tvmap,data
tvmap,data, /grid
tvmap,data, /grid, dlat=8, dlon=10
tvmap,data, /grid, dlat=4, dlon=5, gxlabels=0, gylabels=0
tvmap,data, /grid, dlat=4, dlon=5, gxlabels=5, gylabels=4

Control the GRID - (2) with GRID=0

Not setting /GRID (or setting GRID=0), you can still trigger a call to MAP_GRID through MAP_SET, by using one of the grid keyword accepted by MAP_SET:

TVMAP, data, lon, lat, /contin, GLINESTYLE=0

To pass other grid keyword (those not accepted by MAP_SET), you must use the E_GRID keyword:

TVMAP, data, lon, lat, /contin, limit=[0,-160.,70,-30], latdel=8, londel=10, &
                       e_grid={box_axes:1}, nogxlabels=1, nogylabels=1

Note the use of NoGXLabel to leave control of the grid labels to MAP_GRID. This method gives you more control, since you can use all grid keywords, directly or with E_GRID.

Concrete example : plotting the GEOS-Chem grid box with TVMAP

You must pass the grid edges with LATS and LONS keywords to MAP_GRID. If the grid info structure associated with your data is called GridInfo, you will go with:

tvmap, data, xlon, ylat, /sample, &
       lats=gridinfo.yedge, lons=gridinfo.xedge, /grid

You can also improve the rendition with color:

tvmap, data, xlon, ylat, /sample, lats=gridinfo.yedge, lons=gridinfo.xedge, /grid, gcolor=!myct.gray15

However, if you want to modify other details of the grid, you must use the E_GRID keyword but not GRID. For example, the LINESTYLE of the grid:

tvmap, data, xlon, ylat, /sample, glinestyle=5, e_grid={lats:gridinfo.yedge, lons:gridinfo.xedge, color:=!myct.gray15}

What happens: there is no call to MAP_GRID in TVMAP (because we do not use /GRID), but instead a call to MAP_GRID triggered by MAP_SET (because we use GLINESTYLE).

FAQ : help, my plot has TWO grids!

   QUESTION: I try to modify some GRID features when calling TVMAP and end up with
   2 grids. What's happening?
   ANSWER: MAP_GRID can be triggered by :
    - TVMAP if /GRID is set
    - MAP_SET if grid related keywords accepted by MAP_SET are used.
     
   You used both /GRID and a grid keyword recognized by MAP_SET.
   Solution: do not use the /GRID keyword. See recommended method #2.

Control TVMAP settings from CTM_PLOT and/or GAMAP

Most of TVMAP keywords can be set when calling GAMAP or CTM_PLOT (thanks to the _extra facility of IDL):

gamap, file=ftest, 'anthsrce', dlon=2, dlat=2, lats=0.5, lons=-130.5,/usa, format='(f5.1)', &
       gylab=4,gxlab=10, min_valid=0.00000001

However, sometimes, a TVMAP keyword must be set with a different keyword in CTM_PLOT! For example, use YRANGE with CTM_PLOT to specify the MAXDATA passed to TVMAP:

YRANGE of CTM_PLOT <==> MAXDATA of TVMAP

Similarly, ON/OFF TVMAP keywords can be turn ON by default in CTM_PLOT or GAMAP, while they are OFF by default when calling TVMAP. You need to explicitly turn them OFF if you want them so. For example, by default, ISOTROPIC is off when calling TVMAP, but on when calling CTM_PLOT.

; unset default /isotropic 
CTM_PLOT, ....,  ISOTROPIC=0

Map projections

To get a list of ALL available map projections

Look into the IDL manual, or:

MAP_PROJ_INFO, PROJ_NAMES = NAMES
PRINT, TRANSPOSE(NAMES)

which opens programming possibilities.

Modifying TVMAP default map projection

You do not need to hack into TVMAP. Simply pass relevant MAP_SET keywords to TVMAP. You can overwrite MPARAM or/and LIMIT, or pass a new projection keyword like /LAMBERT.

DATA = DIST(30,20)
lon = -180. + findgen(30)*12 + 6.    ; box center
lat =  -90. + findgen(20)*9  + 4.5   ; box center
TVMAP, data, lon, lat, rectangle=0, GxLabels=0, /GOODES, /HORIZON

For a more elaborate projection, focusing on the USA,

Limit     = [40, -130, 45, -142, 40, -65, 24, -100]
ConUS_Y   = 37
ConUS_X   = -97
TVMAP, data, lon, lat, /CONTINENTS, MPARAM=[CONUS_Y, CONUS_X,0], LIMIT=LIMIT, /LAMBERT, /USA

or North America,

Limit     = [40, -140, 85, -142, 40, -50, 10, -100]
ConUS_Y   = 45
ConUS_X   = -97
TVMAP, data, lon, lat, MPARAM=[CONUS_Y, CONUS_X,0], LIMIT=LIMIT, /LAMBERT, /COUNTRIES, /CONTINENTS

or Europe:

Limit     = [40, -15, 75, 20, 40, 40, 30, 20]
ConUS_Y   = 57
ConUS_X   = 12
TVMAP, data, lon, lat, MPARAM=[CONUS_Y, CONUS_X,0], LIMIT=LIMIT, /LAMBERT, /COUNTRIES, /CONTINENTS

Using TVMAP and MULTIPANEL

simple way

Everything is handled automatically when only using TVMAP:

multipanel, 4
for k=0,3 do tvmap, data
multipanel,/off

But if it is combined with other type of plot, here is the procedure:

multipanel, 4

tvmap, data

multipanel, position=p
plot, findgen(12), color=!myct.black, position=p
multipanel, /advance, /noerase

tvmap,data
tvmap,data

multipanel,/off
   

advanced combination

Using /NOERASE and /ADVANCE in multiple calls to MULTIPANEL, let you arrange your plots however you like. Try something like this:

pro test

  data = dist(20,30)

  ; set a 2x2 panels
   multipanel, rows=2, cols=2

  ; set counterclockwise ordering
  !p.multi[4] = 1

  tvmap, data, title='plot 1'
  tvmap, data, title='plot 2'

  ; switch to 4x3 panels, and back to clockwise ordering
  multipanel, cols=4, rows=3,  /noerase
  !p.multi[4] = 0

  for k=3, 7, 2 do begin
     multipanel, /advance
     multipanel, /advance
     tvmap, data, title='plot ' + strtrim(k, 2)
     tvmap, data, title='plot ' + strtrim(k+1, 2)
  endfor

  ; reset
  multipanel, /off

  return
end

I let you figure out the unique colorbar (hint: use OMargin in the first call to MULTIPANEL).

Overplot lines or string

The active plot must be the last map projection, and not the next plot to come (which is the default). To stay on the map, use /NOADVANCE:

tvmap, dist(20, 20), /contin, /noadvance

LON=[-36., 54.] & LAT=[2., 74.]
plots, [LON[0], LON[1], LON[1], LON[0], LON[0]], &
       [LAT[0], LAT[0], LAT[1], LAT[1], LAT[0]], &
       color=!myct.black, thick=2,  _extra=e

Same story to use XYOutS for string.

About the SCALE keyword

Both MAP_SET and TVIMAGE accept the SCALE keyword. The IDL routine DEVICE (when using PS or PRINTER device) accepts the SCALE_FACTOR keyword. So be careful when using that _EXTRA facility! Note that TVMAP has two `scale' keyword for that purpose:

ScaleMapSet   to specify the MAP_SET SCALE keyword
ScaleMapImage to specify the TVIMAGE SCALE keyword

If you have any doubt try your keywords on this example, and add explicit keywords if needed:

pro my_routine, _extra=e

  open_device, _extra=e

  tvmap, dist(12,12), _extra=e

  close_device

end

Known Issue(s)

Bug with MAX_VALID

Try:

DATA = DIST(20,20)
Window,1 & TVMAP, DATA, MAX_VALID=20., /CBAR

This gives a wrong plot if X > MAX(DATA) and MAXDATA keyword is not used. The fix is to use both:

Window,2 & TVMAP, DATA, MAX_VALID=20., MAXDATA=20., /CBAR

--phs 13:14, 13 March 2012 (EDT)