# Re: Trajectory With color Gradient

From: Jonathan Vigh <vigh_at_nyahnyahspammersnyahnyah>
Date: Wed, 16 Apr 2008 17:28:13 +0000

Santheesan corresponded with me offline with a problem he was having
with my modifications to his script. His issue was caused by me not
following the example quite right (see below). I've included my
troubleshooting 'trajectory' in case it is helpful for anyone who wants
to figure out what's going on when they have problems like this.

Satheesan wrote:

> Hi Jonathan,
>
> Thank you for your modifications and it helped me.
> I still have one doubt. "cosam12" has got 14 colors, but changing the
> value of 9 in fspan(200.0,3400.0,9) into any value greater than 9 gave
> the error of "Not enough colors in colormap for number of contour
> levels". Why it is not working for any value greater than 9 (and <14)?
>
> Thanks & Regards,
>
> Satheesan
>
> On Tue, Apr 15, 2008 at 11:18 PM, Jonathan Vigh
> <vigh_at_atmos.colostate.edu <mailto:vigh_at_atmos.colostate.edu>> wrote:
>
> Hi Santheesan,
> I modified your code and fixed the problems you were having.
> Two issues were fairly easy to spot, the third was more subtle:
>

Hi Satheesan,
I'm glad that I was able to help. These trajectories can be tricky
- it took me a long time to make that example that Dennis referred to -
and I had lots of help from Mary.

Regarding why any value of 9 doesn't work in your script when you have a
colormap with 14 colors - keep in mind that using a value of 9 in fspan
actually produces 10 values. The last argument given to fspan is the
number of equally-spaced points desired between /start/ and /finish/. So
counting the starting and finishing points, you actually have n+1
points. You can see this by printing out cnLevels - the index counts
from 0 to 9 (so 10 values).

Now according to the documentation for GetFillColor: "The leftmost
dimension must be one larger than /cnlevels/."
http://www.ncl.ucar.edu/Document/Functions/Contributed/GetFillColor.shtml

Now also notice that we're not using the first two colors of cmap. The
first colors are the foreground color (black) and the background color
(white). So we really only have 12 colors to work with. But this would
seem like it's still enough. So I wasn't sure why we were getting this
error mesage. Well, one method of troubleshooting a problem with an NCL
function is to go into the code and see what's going on. getFillColor is
a user-contributed function, so you can look it up by opening up the
file and searching for the function. You can open the file by typing

prompt> nedit \$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl

Searching the file for getFillColor finds:

;************************************************************
; Mark Stevens
; will choose a color to fill in a poly(line/gon/marker) based upon
; secondary scalar field.

undef("GetFillColor")
function GetFillColor(cnlvls[*]:numeric,cmap[*][3]:numeric,data:numeric)
local ncn, nclr, color, n
begin

ncn = dimsizes (cnlvls)
nclr = dimsizes (cmap(:,0))
color = new (3,"float",-1.0)

if (nclr-2 .lt. ncn+1) then
print ("Not enough colors in colormap for number of contour levels")
return (color)
end if

if (data .le. cnlvls(0)) then
color = cmap(2,:)
else
if (data .gt. cnlvls(ncn-1)) then
color = cmap(nclr-1,:)
else
do n = 1, ncn-1
if (data .le. cnlvls(n)) then
color = cmap(n+2,:)
break
end if
end do
end if
end if
return (color)
end

Notice that this function is already taking into account the background
and foreground colors by setting color = cmap(n+2,:). So my mistake was
in the line:
pres_at_gsLineColor = GetFillColor(cnLevels,cmap(2:,:),avg(
(/sst(j),sst(j+1)/)))

Change that to:
pres_at_gsLineColor = GetFillColor(cnLevels,cmap,avg( (/sst(j),sst(j+1)/)))

and your script should work. If you look at the function, you can also
see the specific condition which generates the warning message

if (nclr-2 .lt. ncn+1) then

If you're getting a warning message from a specific function or
procedure which isn't already built-in to NCL, you can always do a
search on the warning message to see the condition that generated it.

Finally, note that there is an alternative way to pick the colors for
the trajectory. Rather than retrieving the colormap and getting RGB
triplets, you could instead specify the index values of the color map:
cmapi = ispan(2,14,1) ; this creates an array from 2 to 14 which
correspond to the colors in "cosam12" - you could instead skip a color
or rearrange the colors if you wanted, like
cmapi = (/2,14,4,5,6,7,8,9,10,11,12,13,3) ; note we swapped 14 and 3
pres_at_gsLineColor = GetFillColorIndex(cnLevels,cmapi,avg(
(/sst(j),sst(j+1)/))) ; this assigns the colors based on the index
values:

So that approach might be a bit simpler for some, especially if you want
to use the colors in a predefined colormap, but not in the order they
show up in the color map.

One question I would ask of the developers is this - suppose we want to
"spread" the color map for the trajectory (like you can do for contours
or vectors). What would be the best way to do this?