On Jan 5, 2005, at 7:41 AM, Randy Heiland wrote:
> Apologies, but as usual, I'm under a bit of pressure to display a
> pcolor
> using a custom colormap and it's not intuitively obvious how to do it
> (but
> I'll keep looking). If there's a kind soul out there who can quickly
> point
> me/show me how, I'd appreciate it. In my simple example, I want to
> have
> just 4 bands of color: 2 shades of blue for all negative scalar
> values and
> 2 shades of red for all positive values.
>
> thanks, Randy
>
I responded to this off list (through a separate request). I did want to
point out that the data structure used to create linear segmented
colormaps
does provide the capability for easily defining constant color bands.
There
is a simple, but not very general, means of just restricting the number
of
points in the color map. By making this a small number, one will just
have
that many distinct colors available (by default it is set to 256, which
generally makes it hard to distinguish the distinct levels). This is
only
useful if you wish the thresholds for the constant levels to be
uniformly
spaced between 0 and 1 after normalizing the data values to that
interval.
In this particular case choosing N to be small (7) didn't align 0 with
one
of these thresholds and thus wasn't useful for this purpose.
The more general means of setting arbitrary constant color bands is to
take
advantage of the fact that the definition of the linear segments allows
for
discontinuities at each threshold. Two examples are shown below. The
first
is a continuous colormap and the second illustrates use of constant
color
bands.
The data structure is simply dictionary that has entries for each of
the 3
colors. Each of these is set a tuple of tuples. Each of the interior
tuples
represents the color value(s) at a normalized data value (i.e., values
ranging
from 0 to 1). The first value is the normalized data value for which the
color intensities apply. Two color intensities are required to allow for
discontinuities. So the second value of the tuple is the color intensity
just below the data value, and the third the value is the value just
above.
If the color map is to be continuous at that point, these two values
should
be the same. The tuples should be monotonic in data values and should
start
with 0. and end with 1. The color intensities are linearly interpolated
between the specified data points. (Actually, color lookup tables are
generated
instead and simple value lookup is used. As mentioned, the default
number of
entries in the lookup tables is 256. This can be overridden by
specifying
how many levels are desired) The following examples illustrate two
simple cases.
mycmdata1 = {
'red' : ((0., 0., 0.), (0.5, 0.9, 0.9), (1., 1., 1.)),
'green': ((0., 0., 0.), (1., 0., 0.)),
'blue' : ((0., 0., 0.), (1., 0., 0.))
}
mycm1 = LinearSegmentedColormap('mycm', mycmdata1)
This color map is intended to show only red with values between 0 and
0.5 using
90% of the red color range, values running from 0.5 to 1.0 only result
in a
minor increase of the red intensity from 0.9 to 1.0.
mycmdata2 = {
'red' : ((0., 1., 1.), (0.1, 1., 0.), (1., 0., 0.)),
'green': ((0., 0., 0.), (0.1, 0., 1.), (0.9, 1., 0.), (1., 0.,
0.)),
'blue' : ((0., 0., 0.), (0.9, 0., 1.), (1., 1., 1.))
}
mycm2 = LinearSegmentedColormap('mycm', mycmdata2)
For this color map, value between 0. and 0.1 will be full red, values
between
0.1 and 0.9 will be full green, and values between 0.9 and 1. will be
full blue.
Note that in this case the difference in the 2nd and 3rd values in the
tuples
at the changes in color. Color values are interpolated between the
normalized
data values and since they are the same over the interval, they are
constant.
Randy's case is a bit unusual in that one needs to figure out where 0
in the
original data maps to the normalized data, and then construct a
colormap that
used that "normalized" 0 value as a threshold. So one must construct a
colormap
for each such image (admittedly a bit clumsy).
Perry
|