1 /* cmap.i
2 * Large enhancement to palette function, including dozens of additional
3 * pre-defined palette choices: ColorBrewer, Matplotlib (python), Gnuplot,
4 * and GMT palettes included.
5 */
6 /* Copyright (c) 2013, David H. Munro.
7 * All rights reserved.
8 * This file is part of yorick (http://yorick.sourceforge.net).
9 * Read the accompanying LICENSE file for details.
10 */
11
12 func cmap(p, n, hist=, hsv=, hsl=, rev=, gamma=, lgamma=, usehue=, nmax=)
13 /* DOCUMENT cmap, p, n
14 * or rgb = cmap(p, n)
15 * returns a list of colors 0xrrggbb corresponding to the colormap
16 * defined by parameters P. The N argument is optional; it is the
17 * the number of colors you want in the palette. N defaults to the
18 * number of colors in the palette for the current window (usually 200).
19 * If you specify N<0, that many colors will be appended to the
20 * existing palette, enabling you to stack multiple shortened palettes.
21 * Called as a subroutine, actually sets the palette; called as a
22 * function, returns [r,g,b] as Nx3 char array.
23 *
24 * Recommendations: Read http://www.sandia.gov/~kmorel/documents/ColorMaps/
25 * Most color maps here are rather poor choices. Some reasonably good ones
26 * are: "gray", "coolwarm", "bone", "copper", and most of the ColorBrewer
27 * maps, such as "Blues" or "PuOr". The function cmap_test makes a
28 * picture you can use to test palettes. The "dblue", "dred", and "dgreen"
29 * maps are a matched set designed to be distinguishable by colorblind
30 * people. Use them if you need multiple maps in one picture.
31 *
32 * Keywords:
33 * hist=1 if P is a simple list of colors, creates a stepped
34 * palette instead of interpolating between colors
35 * hist=2 like hist=1, but the first and last colors get only a
36 * single map index instead of a full width step
37 * rev=1 reverses order of the colors (also "_r" when P is name)
38 * hsv=1 interpret P values as hue, saturation, value, not rgb
39 * hsl=1 interpret P values as hue, saturation, lightness, not rgb
40 * gamma= adjust the value (after transforming to HSV) by V^gamma
41 * gamma=1 does nothing, gamma>1 darkens the colors, and
42 * gamma<1 brightens the colors
43 * lgamma= adjust the lightness (after transforming to HSL) by L^gamma
44 * gamma=1 does nothing, gamma>1 darkens the colors, and
45 * gamma<1 lightens the colors
46 * usehue=1 if P is a simple list of colors, interpolates in hsv
47 * instead of rgb, sometimes a nicer option (try with "accent")
48 *
49 * Specifiy the rev=, gamma=, or lgamma= keywords with no other parameters
50 * to adjust the existing palette. In the case of gamma corrections,
51 * cmap remembers the initial rgb values, so that you can accurately
52 * apply multiple gamma corrections interactively. The total gamma is
53 * kept in the external variable _cm_gamma (the product of all the
54 * applied gammas). Hence, a sequence of cmap,gamma=.8 commands (say)
55 * can be used to brighten the colors preogressively, and a sequence of
56 * cmap,gamma=1.25 commands will darken it.
57 *
58 * P can be:
59 * name
60 * a scalar string naming a named palette
61 * append "_r" to name to reverse it, "_N" to name, where N is a
62 * number, to select a map of that name with the specified number
63 * of colors and select hist=N
64 * [rgb1, rgb2, ...]
65 * a list of equally spaced colors as 0xrrggbb; all three components
66 * will be linearly interpolated between these given colors
67 * [[x1,rgb1], [x2,rgb2], ..., [xN,rgbN]]
68 * a list of unequally spaced colors as 0xrrggbb; all three components
69 * will be linearly interpolated between these given colors, The
70 * x values are linearly scaled so that x1 is mapped to the first
71 * returned color and xN is mapped to the last returned color.
72 * [[r1,g1,b1], [r2,g2,b2], ...]
73 * equally spaced colors as rgb triples, range 0.0 to 1.0 if real,
74 * 0 to 255 if integers
75 * [[x1,r1,g1,b1], [x2,r2,g2,b2], ...]
76 * unequally spaced colors as rgb triples, range 0.0 to 1.0 if real,
77 * 0 to 255 if integers
78 * [&[[xr1,r1], [xr2,r2], ...], &[[xg1,g1], [xg2,g2], ...],
79 * &[[xb1,b1], [xb2,b2], ...]]
80 * a list of unequally spaced color components rN, gN, bN, which are
81 * in the range from 0.0 to 1.0 inclusive (mapped to 0 and 255 as char
82 * color component values for the returned palette). Again, the
83 * xrN, xgN, and xbN values are linearly scaled so that the first color
84 * in the returned list gets the first value in the list and the last
85 * color gets the last value. Matplotlib calls this a "linearly
86 * segmented color map".
87 * [[rindex, gindex, bindex]]
88 * gnuplot function indices for each component, 0 to 36 inclusive
89 * trailing 1-length dimension distinguishes from [rgb1, rgb2, ...].
90 * [[[p1, p2, p3, p4]]]
91 * cmap_nonlin function parameterizing a few power laws and trig
92 * functions:
93 * p1*sin((p2*x+p3)*pi) + p4 but
94 * abs(p1*sin((p2*x+p3)*pi) + p4) if p1<0 and p2<0
95 * p1*x^p3 + p4 if p2==0
96 * [r, g, b]
97 * sets palette directly, ignoring n parameter unless hist=1, but
98 * accepting hsv=, hsl=, and rev= keywords. (r, g, b must have more
99 * than 4 colors, but no more than 240.)
100 * save(p=params,hist=hist,...)
101 * an object containing cmap parameters and keywords permits any
102 * input to cmap (except n) to be return value of another function
103 *
104 * Available named color maps are the yorick palette names (less ".gp"),
105 * the ColorBrewer color maps (help, cb_choices), Matplotlib (python)
106 * color maps, and GMT (Generic Mapping Tools) color maps. Some of the
107 * names conflict; you can use the functions gistct, mplct, and gmtct
108 * to break any conflicts (the ColorBrewer names are all unique). Also
109 * featured are several of the diverging color maps devised by Kenneth
110 * Moreland. See help,mshct for more on those. Finally, a sequential
111 * map design tool I invented, seqct, is available.
112 *
113 * The Gnuplot and IDL programs use a scheme of indexed palettes; the
114 * functions gplct and idlct allow you to set those palettes. Some of
115 * the Gnuplot palettes are named Matplotlib palettes, including all
116 * the ones mentioned in the Gnuplot user manual. The cubehelix function
117 * lets you set palettes by parameters; you can get the default parameters
118 * with cmap, "cubehelix".
119 *
120 * SEE ALSO: mshct, seqct, gplct, mplct, gmtct, gistct, idlct, cubehelix,
121 * cb_choices, cmap_rd, cmap_test
122 */
123 {
124 if (!is_void(lgamma)) { gamma = lgamma; lgamma = 1; }
125 if (is_void(p)) {
126 local r, g, b;
127 palette, query=1, r, g, b;
128 if (!numberof(r)) return [];
129 p = transpose([r, g, b]);
130 if (!rev && !gamma && !n) return p;
131 if (is_void(n)) n = numberof(r);
132 }
133 if (is_obj(p)) {
134 if (is_void(hist)) hist = p.hist;
135 if (is_void(usehue)) usehue = p.usehue;
136 if (is_void(rev)) rev = 0;
137 rev = (rev!=0) ^ (p.rev!=0);
138 hsv = p.hsv;
139 hsl = p.hsl;
140 p = p.p;
141 }
142 if (!is_void(n) && (n<2 || n>240))
143 error, "illegal number of colors for palette, must be between 2 and 240";
144 n0 = n;
145 if (structof(p) == string) { /* name */
146 name = p = cmap_name(p, n, rev);
147 if (is_func(cmap_user_map)) p = cmap_user_map(name, n);
148 else p = [];
149 if (!is_void(cmap_alias)) {
150 list = where(name == cmap_alias(1,));
151 if (numberof(list)) name = cmap_alias(2,list(1));
152 }
153 if (is_void(p) && name=="cubehelix") {
154 rgb = cubehelix(n);
155 if (rev) rgb = rgb(::-1,);
156 if (am_subroutine()) palette, rgb(,1), rgb(,2), rgb(,3);
157 return rgb;
158 }
159 if (is_void(p)) {
160 local type;
161 p = cb_map(name, ((n && n<13)?n:[]), type);
162 if (!is_void(p)) {
163 if ((n != n0) && is_void(hist)) hist = 1;
164 n = n0;
165 if (is_void(hist) && type==3) hist = 1;
166 }
167 }
168 if (is_void(p)) {
169 i = mshct(name, , n0);
170 if (numberof(i)) p = transpose(i);
171 }
172 if (is_void(p)) {
173 i = seqct(name, n0);
174 if (numberof(i)) p = transpose(i);
175 }
176 if (is_void(p)) {
177 i = where(mpl_names == name);
178 if (numberof(i)) p = *mpl_maps(i(1));
179 }
180 if (is_void(p)) {
181 i = where(gmt_names == name);
182 if (numberof(i)) {
183 p = *gmt_maps(i(1));
184 flags = gmt_flags(i(1));
185 if (flags == 1) hist = 1;
186 else if (flags == 2) hsv = 1;
187 }
188 }
189 if (is_void(p)) {
190 i = where(gist_names == name);
191 if (numberof(i)) {
192 p = *gist_maps(i(1));
193 if (name == "earth") hsv = 1;
194 }
195 }
196 if (is_void(p)) error, "unrecognized palette name "+name;
197 }
198 if (is_void(n)) {
199 n = cmap_ncolors(); /* avoids calling it twice */
200 } else if (n < 0) {
201 palette, query=1, r, g, b;
202 rgb0 = [r, g, b]; /* for append mode */
203 n = -n;
204 }
205 d = dimsof(p);
206 if (structof(p) == pointer) { /* [&[[xr1,r1], [xr2,r2], ...], ...] */
207 r = *p(1);
208 g = *p(2);
209 b = *p(3);
210 scale = cmap_get_scale(r, g, b);
211 } else if (d(1) == 2) {
212 if (d(3) == 1) { /* [[rindex, gindex, bindex]] */
213 rgb = gnu_map(p(1), p(2), p(3), n);
214 r = g = b = span(0.,1.,numberof(rgb)/3)(-:1:2,);
215 r(2,) = rgb(,1);
216 g(2,) = rgb(,2);
217 b(2,) = rgb(,3);
218 if (hsv || hsl) r *= 360.;
219 scale = 255.;
220 } else if (d(2) == 2) { /* [[x1,rgb1], [x2,rgb2], ... */
221 r = g = b = p;
222 p = p(2,);
223 r(2,) = char(p >> 16);
224 g(2,) = char(p >> 8);
225 b(2,) = char(p);
226 scale = 1.;
227 } else if (d(2) == 3) { /* [[r1,g1,b1], [r2,g2,b2], ... */
228 r = g = b = structof(p+0)(indgen(numberof(p)/3))(-:1:2,);
229 r(2,) = p(1,);
230 g(2,) = p(2,);
231 b(2,) = p(3,);
232 scale = cmap_get_scale(r, g, b);
233 histok = 1;
234 } else if (d(2) == 4) { /* [[x1,r1,g1,b1], [x2,r2,g2,b2], ... */
235 r = g = b = p(1,-:1:2,);
236 r(2,) = p(2,);
237 g(2,) = p(3,);
238 b(2,) = p(4,);
239 scale = cmap_get_scale(r, g, b);
240 } else if (d(3) == 3) { /* [r, g, b] */
241 if (rev) p = p(::-1,);
242 if (hsv) p = hsv2rgb(p);
243 else if (hsl) p = hsl2rgb(p);
244 if (structof(p+0) != long) p = long(255*p+0.5);
245 if (hist) {
246 x = span(0., 1., n);
247 x = digitize(x, span(0., 1., numberof(p)/3+1)(2:-1));
248 p = p(x,);
249 }
250 if (am_subroutine()) palette, char(p(,1)), char(p(,2)), char(p(,3));
251 return p;
252 } else {
253 error, "unrecognized color map parameterization";
254 }
255 } else if (d(1)==3 && d(2)==4 && d(3)==3 && d(4)==1) {
256 x = span(0., 1., n);
257 r = g = b = x(-:1:2,);
258 r(2,) = cmap_nonlin(p(,1,1), x);
259 g(2,) = cmap_nonlin(p(,2,1), x);
260 b(2,) = cmap_nonlin(p(,3,1), x);
261 scale = 255.;
262 } else if (structof(p+0) == long) { /* [rgb1, rgb2, ... */
263 r = g = b = indgen(numberof(p))(-:1:2,);
264 r(2,) = (p >> 16) & 0xff;
265 g(2,) = (p >> 8) & 0xff;
266 b(2,) = p & 0xff;
267 scale = 1.;
268 histok = 1;
269 } else {
270 error, "unrecognized color map parameterization";
271 }
272 if (nmax) {
273 if (am_subroutine()) error, "too many colors to set";
274 n = 256;
275 }
276 x = span(0., 1., n);
277 if (rev) x = 1. - x;
278 if (hist) {
279 if (!histok) error, "need simple list of colors for hist=1";
280 if (hist != 2) x0 = span(0., 1., numberof(r)/2+1)(2:-1);
281 else x0 = span(1.e-6, 1.-1.e-6, numberof(r)/2-1);
282 x = digitize(x, x0);
283 r = r(2,x);
284 g = g(2,x);
285 b = b(2,x);
286 } else {
287 cminterp = cmap_interp;
288 if (usehue) {
289 if (!histok) error, "need simple list of colors for usehue=1";
290 if ((!hsv) & (!hsl)) hsv = 1;
291 rgb = (hsv? rgb2hsv : rgb2hsl)(r(2,), g(2,), b(2,));
292 r = double(r); g = double(g); b = double(b);
293 r(2,) = rgb(,1); g(2,) = rgb(,2); b(2,) = rgb(,3);
294 scale = 255.;
295 cminterp = hue_interp;
296 }
297 r = cminterp(r, x);
298 g = cmap_interp(g, x);
299 b = cmap_interp(b, x);
300 }
301 if (hsv || hsl) {
302 if (scale != 255.) error, "expecting real values for hsv or hsl";
303 rgb = (hsv? hsv2rgb : hsl2rgb)(r, g, b);
304 } else {
305 rgb = char(scale*[r, g, b] + 0.5);
306 }
307 if (numberof(rgb0)) rgb = grow(rgb0, rgb);
308 /* remember initial rgb to permit accurate multiple gamma corrections */
309 if (numberof(rgb)!=numberof(_cm_rgb) || nallof(rgb==_cm_rgb)) {
310 extern _cm_gamma, _cm_rgb0;
311 _cm_gamma = _cm_lgamma = _cm_rgb0 = _cm_rgb = [];
312 }
313 if (gamma && gamma!=1.) {
314 cmg = (lgamma? _cm_lgamma : _cm_gamma);
315 if (cmg) {
316 rgb = _cm_rgb0;
317 gamma *= cmg;
318 }
319 _cm_rgb0 = rgb;
320 if (lgamma) {
321 _cm_lgamma = gamma;
322 _cm_gamma = [];
323 } else {
324 _cm_gamma = gamma;
325 _cm_lgamma = [];
326 }
327 rgb = (lgamma? rgb2hsl : rgb2hsv)(rgb);
328 rgb(,3) = rgb(,3)^gamma;
329 rgb = _cm_rgb = (lgamma? hsl2rgb : hsv2rgb)(rgb);
330 }
331 if (!am_subroutine()) return rgb;
332 palette, rgb(,1), rgb(,2), rgb(,3);
333 }
334
335 cmap_alias = [["france", "polar"]];
336
337 func cmap_name(name, &n, &rev)
338 {
339 if (strpart(name,-1:0) == "_r") {
340 rev = !rev;
341 name = strpart(name, 1:-2);
342 }
343 i = strgrep("(.+)_([0-9]+)", name, sub=[1,2]);
344 if (i(4) > i(3)) {
345 n = long(tonum(strpart(name, i(3:4))));
346 if (n<2 || n>240)
347 error, "illegal number of colors for palette, must be between 2 and 240";
348 name = strpart(name, i(1:2));
349 }
350 return name;
351 }
352
cmap_get_scale(r,g,b)353 func cmap_get_scale(r, g, b)
354 {
355 if (structof(r(1)+g(1)+b(1)+0)==long && max(r(2,max),g(2,max),b(2,max))>1)
356 return 1.;
357 else
358 return 255.;
359 }
360
cmap_ncolors(void)361 func cmap_ncolors(void)
362 {
363 local r, g, b;
364 palette, query=1, r, g, b;
365 return (numberof(r) < 2)? 200 : numberof(r);
366 }
367
cmap_clip(x)368 func cmap_clip(x)
369 {
370 return min(max(x, 0.), 1.);
371 }
372
cmap_nonlin(p,x)373 func cmap_nonlin(p, x)
374 {
375 if (!p(1)) return (2.*x-1.)^2; /* gnuplot function 12 */
376 if (!p(2)) x = p(1)*x^p(3) + p(4);
377 else x = p(1)*sin((p(2)*x + p(3)) * pi) + p(4);
378 if (p(1)<0. && p(2)<0.) x = abs(x);
379 return cmap_clip(x);
380 }
381
cmap_interp(p,x)382 func cmap_interp(p, x)
383 {
384 xp = p(1,);
385 xp = (xp - xp(1)) / double(xp(0) - xp(1));
386 list = where(!xp(dif));
387 if (numberof(list)) { /* arrange for discontinuous jump */
388 xp(list+1) += 1.e-6;
389 if (xp(0) > 1.) {
390 xp(-1) -= 1.e-6;
391 xp(0) = 1.;
392 }
393 }
394 return interp(p(2,), xp, x);
395 }
396
hue_interp(p,x)397 func hue_interp(p, x)
398 {
399 p = p;
400 h = p(2,) / 360.;
401 h -= floor(h);
402 dh = h(dif);
403 list = where(abs(dh) > 0.5);
404 if (numberof(list)) dh(list) -= sign(dh(list));
405 h = h(1) + dh(cum);
406 p(2,) = 360. * h;
407 return cmap_interp(p, x);
408 }
409
410 func cmap_test
411 /* DOCUMENT cmap_test
412 * Create a picture to help test color maps for artifacts and common
413 * misfeatures. After calling this, call cmap or one of the *ct
414 * functions to change the color map.
415 * SEE ALSO: cmap, mshct, seqct, mplct, gplct, gmtct, idlct, cb_choices
416 */
417 {
418 x=span(0,1,400)(,-:1:400); y=transpose(x);
419 fma; limits;
420 pli, (1.02-y)*sin(8*pi*x);
421 }
422
gistct(name)423 func gistct(name)
424 /* DOCUMENT cm = gistct(name)
425 * or gistct, name
426 * return color map (ct = "color table") specification for yorick
427 * map NAME (where NAME.gp is the name of the palette file).
428 * You may append "_r" to the name to reverse the colors.
429 * Called as a subroutine, sets the current palette.
430 * SEE ALSO: cmap, mplct, gplct, gmtct, idlct
431 */
432 {
433 local n, rev;
434 name = cmap_name(name, n, rev);
435 i = where(name == gist_names);
436 if (!numberof(i)) error, name+" is not a gist color map";
437 p = *gist_maps(i(1));
438 if (name == "earth") hsv = 1;
439 if (!am_subroutine())
440 return (hsv || rev)? save(p=p, hsv=hsv, rev=rev) : p;
441 cmap, p, rev=rev, hsv=hsv;
442 }
443
444 /* these are good approximations to the gist palettes of the same names */
445 gist_names = ["earth", "heat", "rainbow", "gray", "yarg", "stern", "ncar"];
446
447 /* heat, rainbow, stern, and ncar parameterizations by
448 * Reinier Heeres for matplotlib
449 * earth is hsv
450 */
451 gist_maps = [&[[1,0,0,0],[1,240,1,.135],[7,240,1,.455],[57,180,.629,.5],
452 [109,93.9,.512,.65],[157,40.67,.472,.753],[200,0,0,1]],
453 &[&[[0,0], [7,1], [10,1]], &[[0,0], [19,0], [40,1]],
454 &[[0,0], [3,0], [4,1]]],
455 &[[1,0xff0029],[8,0xff0000],[52,0xffff00],[97,0x00ff00],
456 [141,0x00ffff],[185,0x0000ff],[229,0xff00ff],[240,0xff00bf]],
457 &[0x000000,0xffffff], &[0xffffff,0x000000],
458 &[&[[0,0], [0.0547,1], [0.25,.027], [0.25,.25], [1,1]],
459 &[[0,0], [1,1]], &[[0,0], [.5,1], [0.735,0], [1,1]]],
460 &[&[[0,0],[0.3098,0],[0.3725,0.3993],[0.4235,0.5003],[0.5333,1],
461 [0.7922,1],[0.8471,0.6218],[0.8980,0.9235],[1,0.9961]],
462 &[[0,0],[0.0510,0.3722],[0.1059,0],[0.1569,0.7202],
463 [0.1608,0.7537],[0.1647,0.7752],[0.2157,1],[0.2588,0.9804],
464 [0.2706,0.9804],[0.3176,1],[0.3686,0.8081],[0.4275,1],
465 [0.5216,1],[0.6314,0.7292],[0.6863,0.2796],[0.7451,0],
466 [0.7922,0],[0.8431,0.1753],[0.8980,0.5],[1,0.9725]],
467 &[[0.0,0.5020],[0.0510,0.0222],[0.1098,1],[0.2039,1],
468 [0.2627,0.6145],[0.3216,0],[0.4157,0],[0.4745,0.2342],
469 [0.5333,0],[0.5804,0],[0.6314,0.0549],[0.6902,0],[0.7373,0],
470 [0.7922,0.9738],[0.8000,1],[0.8431,1],[0.8980,0.9341],
471 [1,0.9961]]]];
472
473 func cmap_rd(f, &hsv)
474 /* DOCUMENT rgb = cmap_rd(filename, hsv)
475 * or cmap_rd, filename
476 * Read a color map from file FILENAME. Called as a subroutine, passes
477 * the map to cmap to install it as the current palette. Accepts yorick
478 * (gist) .gp format or GMT .cpt format. The HSV argument is an output,
479 * non-nil if and only if this is to be interpreted in HSV color space.
480 * SEE ALSO: cmap
481 */
482 {
483 hsv = [];
484 lines = text_lines(f);
485 n = strgrep("^[ \t]*ncolors[ \t]*=[ \t]*([0-9]+)", lines, sub=1);
486 list = where(n(1,) < n(2,));
487 if (numberof(list)) { /* this is .gp format */
488 nc = 0;
489 sread, strpart(lines(list(1)), n(,list(1))), nc;
490 lines = strpart(lines, strgrep("^[ \t]*([0-9]+[ \t]*[0-9]+[ \t]*[0-9]+)",
491 lines, sub=1));
492 lines = lines(where(lines));
493 if (numberof(lines) != nc)
494 error, "ncolors does not match rgb list in "+f;
495 rgb = array(char, 3, nc);
496 if (sread(lines, rgb) != 3*nc)
497 error, "problem reading .gp file "+f;
498 } else {
499 lines = strtrim(lines);
500 n = strgrep("^#[ \t]*COLOR_MODEL[ \t]*=.*(RGBA?|HSV|CMYK)[ \t]*",
501 lines, sub=1);
502 m = strpart(lines, n);
503 m = m(where(m))(1);
504 if (m == "HSV") hsv = 1;
505 else if (m == "CMYK") cmyk = 1;
506 else if (m == "RGBA") rgba = 1;
507 else if (m == "RGB") rgb = 1;
508 else if (m) error, "unrecognized COLOR_MODEL in "+f;
509 lines = strpart(lines, strgrep("^[-+. \t0-9]+", lines));
510 lines = lines(where(lines));
511 rgb = array(0., 4+(cmyk||rgba), 2, numberof(lines));
512 if (sread(lines, rgb) != numberof(rgb))
513 error, "problem reading color table in "+f;
514 if (cmyk) error, "no support for CMYK color table in "+f;
515 rgb = rgb(1:4,*);
516 if (!hsv) {
517 if (allof(rgb == long(rgb))) rgb = long(rgb);
518 else if (max(rgb(2:4,)) > 1.) rgb(2:4,) /= 255.;
519 }
520 }
521 if (!am_subroutine()) return rgb;
522 cmap, rgb, hsv=hsv;
523 }
524
525 /* ------------------------------------------------------------------------ */
526 /* msh colormaps, http://www.sandia.gov/~kmorel/documents/ColorMaps/
527 * devised by Kenneth Moreland
528 * The coolwarm Matplotlib map below is apparently a botched version of these.
529 * Coolwarm, blutan, and redgrn appear in Moreland's paper. The others are
530 * random fiddling with the mshct rgb1 and rgb2.
531 */
532
533 msh_names = ["coolwarm", "blutan", "ornpur", "grnred",
534 "purple", "blue", "green", "red", "brown"];
535 msh_maps = [[[ 59, 76,192], [180, 4, 38]], [[ 55,133,232], [172,125, 24]],
536 [[179, 88, 6], [ 84, 39,136]], [[ 22,135, 51], [193, 54, 59]],
537 [[ 63, 0,125], [221,221,221]], [[ 8, 48,107], [221,221,221]],
538 [[ 30, 90, 0], [221,221,221]], [[180, 0, 30], [221,221,221]],
539 [[103, 0, 13], [221,221,221]]];
540
541 func mshct(rgb1, rgb2, n, wht=, msh=, cmax=)
542 /* DOCUMENT cm = mshct(name)
543 * or cm = mshct(rgb1, rgb2)
544 * or mshct, name
545 * or mshct, rgb1, rgb2
546 * return diverging color map going from RGB1 to RGB2 through white. If
547 * either color is too close to white, produces a sequential map between
548 * the two. If one of RGB1 or RGB2 is nil, it is taken to be white.
549 * If the two colors are too close in hue, also just produces a
550 * sequential map. The algorithm is from Kenneth Moreland,
551 * http://www.sandia.gov/~kmorel/documents/ColorMaps/ and references
552 * therein. A few reasonable RGB1 and RGB2 values have been given names.
553 * The name "coolwarm" produces Moreland's recommended color table.
554 * Called as a subroutine, sets the current palette.
555 * SEE ALSO: cmap, seqct, gmtct, gplct, gistct, idlct
556 */
557 {
558 if (structof(rgb1) == string) {
559 /* some predefined diverging and sequential maps */
560 list = where(rgb1 == msh_names);
561 if (!numberof(list)) {
562 if (!am_subroutine()) return [];
563 error, "unknown mshct name "+rgb1;
564 }
565 rgb1 = msh_maps(,1,list(1));
566 rgb2 = msh_maps(,2,list(1));
567 msh = [];
568 }
569
570 /* pushing wht higher than about 93 gives white band */
571 if (is_void(wht)) wht = 88.;
572 if (msh) {
573 msh1 = rgb1; msh2 = rgb2;
574 } else {
575 msh1 = rgb2msh(rgb1);
576 if (!is_void(rgb2)) msh2 = rgb2msh(rgb2);
577 }
578 if (is_void(msh2)) msh2 = [max(msh1(1), wht), 0., 0.];
579 else if (is_void(msh1)) msh1 = [max(msh2(1), wht), 0., 0.];
580 wht = max(msh1(1), msh2(1), wht);
581 if (is_void(n)) n = cmap_ncolors();
582 x = span(0., 1., abs(n));
583 if (n < 0) {
584 if (msh == 1) x = 2.*x(where(x < 0.5));
585 else x = 2.*x(where(x >= 0.5)) - 1.;
586 }
587 s1 = msh1(2);
588 s2 = msh2(2);
589 dh = abs(msh1(3) - msh2(3)) % (2.*pi);
590 dh = min(dh, 2.*pi-dh);
591 if (s1>0.5 && s2>0.05 && dh>pi/3.) {
592 /* if rgb1, rgb2 are saturated and distinct, put white at x=0.5
593 * (otherwise, this is just a fragment going from rgb1 to rgb2)
594 * neither recursion can take this branch
595 */
596 rgb1 = transpose(mshct(msh1, , -n, cmax=cmax, wht=wht, msh=1));
597 rgb2 = transpose(mshct(, msh2, -n, cmax=cmax, wht=wht, msh=2));
598 rgb = transpose(grow(rgb1, rgb2));
599 } else {
600 /* avoid perceptual kink near white */
601 if (s1<0.5 && s2>0.05) msh1(3) = _adjust_hue(msh2, msh1(1));
602 else if (s2<0.5 && s1>0.05) msh2(3) = _adjust_hue(msh1, msh2(1));
603 /* then just interpolate polar coordinates
604 * why isn't this broken for h1, h2 separated across 0,2*pi?
605 */
606 msh = x(..,-:1:3);
607 x = x(*);
608 msh(*,) = (1.-x)*msh1(-,) + x*msh2(-,);
609 rgb = msh2rgb(msh, cmax=cmax);
610 }
611 if (!am_subroutine()) return rgb;
612 cmap, rgb;
613 }
614
rgb2msh(rgb,g,b)615 func rgb2msh(rgb, g, b)
616 {
617 msh = rgb2lab(rgb, g, b);
618 l = msh(..,1); a = msh(..,2); b = msh(..,3); c = abs(b, a);
619 msh(..,3) = atan(b, a+!c);
620 msh(..,1) = a = abs(c, l);
621 msh(..,2) = atan(c, l+!a);
622 return msh;
623 }
624
625 func msh2rgb(msh, cmax=)
626 {
627 s = msh(..,2); h = msh(..,3);
628 lab = double(msh);
629 lab(..,1) = cos(s);
630 lab(..,2:3) = sin(s) * [cos(h), sin(h)];
631 return lab2rgb(msh(..,1)*lab, cmax=cmax);
632 }
633
_adjust_hue(msh,mu)634 func _adjust_hue(msh, mu)
635 { /* only needs to work for scalar m,s,h and mu */
636 m = msh(1); s = msh(2); h = msh(3);
637 if (m >= mu) return h;
638 hspin = s * sqrt(mu*mu - m*m) / (m * sin(s));
639 return (h > -pi/3.)? h + hspin : h - hspin; /* -pi/3 seems odd?? */
640 }
641
642 /* ------------------------------------------------------------------------ */
643 /* Sequential colormaps built on similar principles to Moreland */
644
645 /* named cm_seq map parameters are h (degrees), l1 (bright L), l2 (dark L)
646 * where the L values can be a negative integer to use -L as the index
647 * into seq_params of another named map for the L and saturation
648 *
649 * dblue, dred, dgreen are three matched maps carefully designed to
650 * be distinguishable to dichromats (colorblind people)
651 */
652 seq_names = ["dblue", "dred", "dgreen"];
653 seq_params = [[228, -2, -3], [345, 90, -3], [65, -2, 20]];
654
655 /* lRGB hues in degrees, r=0, g=120, b=240
656 * LMS color directions:
657 * Vischeck L=351.23, M=156.73, S=253.69 (180+156.73 = 336.73)
658 * Meyer L=355.21, M=344.47, S=255.34 (344.47-180 = 164.47)
659 * Dichromat simulator primaries:
660 * Vischeck Meyer
661 * protan 227.99 49.13 228.92 47.02
662 * deuteran 227.99 49.13 221.03 34.76
663 * tritan 202.14 352.67 184.16 0.36
664 */
665
666 func seqct(h, n, l1, l2, cmax=)
667 /* DOCUMENT cm = seqct(name)
668 * or cm = seqct(h, n, l1, l2)
669 * or seqct, h
670 * Return a sequential colormap based on hue H, running from lighter
671 * shades to darker shades in equal steps of luminance. A few good
672 * choices of hue have names; you can also pass such a NAME. The
673 * remaining arguments are optional: N is the number of colors to
674 * return, which defaults to the number in the currently installed
675 * colormap (usually 200). L1 is the luminance for the lightest (first)
676 * shade, which defaults to 90, and L2 is the luminance of the darkest
677 * (last) shade, which defaults to 20. L1 or L2 may also be RGB triples,
678 * which causes both the endpoint luminance and chroma to match that
679 * given color. The hue H may be specified as an RGB triple, or as an
680 * angle in degrees in lRGB color space, with r=0, g=120, and b=240.
681 * The returned map is based on Luv luminance and hue; all points will
682 * have the same (u,v) hue, and therefore the same lRGB hue. By default,
683 * the color will be maximally saturated at the endpoints, but you can
684 * desaturate it by specifying unsaturated RGB triples for L1 or L2.
685 * Typically, you pick L1 or L2 to be the endpoint of another seqct
686 * map you wish to match, or rgb_saturate on another hue.
687 * The colormap follows a second degree Bezier curve in lRGB space,
688 * with the control point between the endpoints located on the fully
689 * saturated edge of the RGB color cube, at the point with the given hue,
690 * guaranteeing the whole curve lies inside the cube. The points are
691 * evenly spaced in luminance along this curve.
692 *
693 * The named seqct maps are "dblue", "dred", and "dgreen". These maps
694 * are matched to have equal luminance and comparable saturation, so that
695 * you can use them for situations in which you use all three maps
696 * in the same figure. Furthermore, the three hues are carefully chosen
697 * to be distinguishable by dichromats (colorblind people).
698 * SEE ALSO: cmap, mshct, gmtct, gplct, gistct, idlct
699 */
700 {
701 if (is_void(n)) n = cmap_ncolors();
702 if (structof(h) == string) {
703 list = where(h == seq_names);
704 if (!numberof(list)) {
705 if (!am_subroutine()) return [];
706 error, "unknown seqct name "+h;
707 }
708 h = seq_params(,list(1));
709 if (h(2) >= 0.) l1 = h(2);
710 else l1 = rgb_saturate(seq_params(1,-h(2)), seq_params(2,-h(2)), cmax=1);
711 if (h(3) >= 0.) l2 = h(3);
712 else l2 = rgb_saturate(seq_params(1,-h(3)), seq_params(3,-h(3)), cmax=1);
713 h = h(1);
714 }
715 rgb = _lrgbsat(cm_hue2lrgb(h))
716 lmid = _lrgb2luv(rgb)(1);
717 gmid = _luv2lrgb([lmid,0.,0.])(1); /* lrgb gray of same luminance as rgb */
718
719 s1 = _cm_get_sat(l1, 90.);
720 s2 = _cm_get_sat(l2, 20.);
721 if (l1<0 || l2>100 || abs(l1-l2)<20) error, "bad endpoint luminances";
722 /* select gray levels with equal luminance steps */
723 g = _luv2lrgb([span(l1, l2, n),0.,0.])(,1);
724 g1 = g(1); g2 = g(0);
725 /* move endpoints to fully saturated colors of given hue */
726 rgb1 = (g1<=gmid)? rgb*g1/gmid : 1.-(1.-rgb)*(1.-g1)/(1.-gmid);
727 rgb2 = (g2<=gmid)? rgb*g2/gmid : 1.-(1.-rgb)*(1.-g2)/(1.-gmid);
728 /* desaturate endpoints if requested */
729 if (numberof(s2)) rgb2 = _cm_desat(rgb2, s2);
730 if (numberof(s1)) rgb1 = _cm_desat(rgb1, s1);
731 /* move midpoint to mean of endpoint luminances or lrgb grays
732 * get brighter colors with mean gray if gmid not between g1 and g2,
733 * otherwise with mean luminance
734 * -- this switch leads to slight discontinuity as function of hue
735 */
736 if ((g1-gmid)*(gmid-g2)<0.) gm = 0.5*(g1 + g2);
737 else gm = _luv2lrgb([0.5*(l1+l2),0.,0.])(1);
738 mask = double(gmid >= gm);
739 rgb = mask*gm/gmid*rgb + (1.-mask)*(1. - (1.-rgb)*(1.-gm)/(1.-gmid));
740 gmid = gm;
741
742 /* [g,g,g] is gray value for points in colormap
743 * colormap is order 2 Bezier curve [rgb1,rgb,rgb2]
744 * first find s Bezier parameter which gives yl
745 */
746 s = (g - g1) / (g2 - g1);
747 sm = (gmid - g1) / (g2 - g1);
748 s /= sm + sqrt(sm*sm + (1.-sm-sm)*s);
749 s = s(-:1:3,); t = 1. - s;
750 rgb = rgb1*t*t + rgb*2.*t*s + rgb2*s*s;
751 rgb = transpose(rgb_l2s(rgb, cmax=cmax));
752 if (!am_subroutine()) return rgb;
753 cmap, rgb;
754 }
755
_lrgb2luv(rgb)756 func _lrgb2luv(rgb) { lrgb_skip=3; return rgb2luv(rgb); }
_luv2lrgb(luv)757 func _luv2lrgb(luv) { lrgb_skip=3; return luv2rgb(luv); }
_lrgbsat(rgb)758 func _lrgbsat(rgb) {
759 rgb -= rgb(min);
760 g = rgb(max);
761 return rgb / (g + !g); /* on maximal saturation edge of cube */
762 }
763 func _cm_get_sat(&l, l0) {
764 if (is_void(l)) l = l0;
765 if (numberof(l) == 3) { s = rgb_s2l(l); l = rgb2luv(l)(1); }
766 return s;
767 }
_cm_desat(rgb,s)768 func _cm_desat(rgb, s) {
769 luv = _lrgb2luv(rgb); c0 = abs(luv(2), luv(3));
770 s = _lrgb2luv(s); s = abs(s(2), s(3));
771 if (s > 1.01*c0) error, "L1 or L2 more saturated than max for this hue";
772 else if (s >= c0) return rgb;
773 return _luv2lrgb(luv * [c0,s,s]/c0);
774 }
775
cm_hue2lrgb(h)776 func cm_hue2lrgb(h)
777 {
778 if (numberof(h) == 3) {
779 return rgb_s2l(h);
780 } else {
781 h *= pi/180.; /* h is lRGB hue */
782 return [2.,-1.,-1.]/sqrt(6.)*cos(h) + [0.,1.,-1.]/sqrt(2.)*sin(h);
783 }
784 }
785
786 func rgb_saturate(rgb, l, &uvc, cmax=)
787 /* DOCUMENT rgbsat = rgb_saturate(rgb, l, uv)
788 * rgbsat = rgb_saturate(hue, l, uv)
789 * Return [r,g,b] with same Luv hue as RGB, saturated at luminosity L.
790 * Optionally return the uv chroma, sqrt(u^2+v^2) for this color.
791 * In the second form, HUE is the lRGB hue in degrees, lRGB=rgb_s2l(rgb),
792 * the angle in the lRGB color cube of the plane determined by lRGB
793 * and the gray diagonal of the cube.
794 * With the cmax= keyword, rgbsat is normalized to cmax.
795 * SEE ALSO: seqct
796 */
797 {
798 gl = _luv2lrgb([l,0.,0.])(1); /* lrgb gray of luminance l */
799 rgb = _lrgbsat(cm_hue2lrgb(rgb)); /* hue of input rgb on edge of cube */
800 g = _luv2lrgb([_lrgb2luv(rgb)(1),0.,0.])(1);
801 mask = double(gl <= g); /* luminance l below rgb */
802 rgb = mask*gl/g*rgb + (1.-mask)*(1. - (1.-rgb)*(1.-gl)/(1.-g));
803 luv = _lrgb2luv(rgb);
804 uvc = abs(luv(2), luv(3));
805 return rgb_l2s(rgb, cmax=cmax);
806 }
807
808 /* ------------------------------------------------------------------------ */
809 /* matplotlib colormaps, plus four additional names for gnuplot maps */
810
mplct(name)811 func mplct(name)
812 /* DOCUMENT cm = mplct(name)
813 * or mplct, name
814 * return color map (ct = "color table") specification for Matplotlib
815 * map NAME. You may append "_r" to the name to reverse the colors.
816 * Called as a subroutine, sets the current palette.
817 * SEE ALSO: cmap, mshct, seqct, gmtct, gplct, gistct, idlct
818 */
819 {
820 local n, rev;
821 name = cmap_name(name, n, rev);
822 i = where(name == mpl_names);
823 if (!numberof(i)) error, name+" is not a known Matplotlib color map";
824 p = *mpl_maps(i(1));
825 if (!am_subroutine())
826 return p;
827 cmap, p;
828 }
829
830 mpl_names = ["binary", "gray", "cool", "bwr", "brg",
831 "autumn", "spring", "summer", "winter",
832 "seismic", "spectral", "coolwarm", "pink", "terrain",
833 "hsv", "bone", "copper", "hot", "jet", "flag", "prism",
834 "gnuplot", "gnuplot2", "ocean", "rainbow", "afmhot",
835 "gnuplot3", "gnu_hot", "gnuplot4", "gnuplot5"];
836 /* gnuplot is traditional pm3d map, BkBlRdYl
837 * gnuplot2 is gray-printable, BkBuViYlWt
838 * following are all mentioned in gnuplot user manual,
839 * gnuplot3 and later not in matplotlib
840 */
841
842 /* matplotlib color maps begin with equally spaced color lists */
843 mpl_maps = [&[0xffffff,0x000000], &[0x000000,0xffffff], &[0x00ffff,0xff00ff],
844 &[0x0000ff,0xffffff,0xff0000], &[0x0000ff, 0xff0000, 0x00ff00],
845 &[0xff0000, 0xffff00], &[0xff00ff, 0xffff00],
846 &[0x008066, 0xffff66], &[0x0000ff, 0x00ff80],
847 &[0x00004d, 0x0000ff, 0xffffff, 0xff0000, 0x800000],
848 &[0x000000,0x770088,0x880099,0x0000aa,0x0000dd,0x0077dd,0x0099dd,
849 0x00aaaa,0x00aa88,0x009900,0x00bb00,0x00dd00,0x00ff00,0xbbff00,
850 0xeeee00,0xffcc00,0xff9900,0xff0000,0xdd0000,0xcc0000,0xcccccc],
851 &[0x1d2660,0x212d66,0x26336b,0x2b3a70,0x304074,0x364778,0x3b4d7b,
852 0x40527d,0x46577e,0x4c5c7f,0x51607f,0x56647e,0x5c677c,0x616a7a,
853 0x656c76,0x6a6d72,0x6e6e6e,0x726c68,0x756962,0x78665c,0x7a6256,
854 0x7b5d50,0x7b5849,0x7b5243,0x7a4c3d,0x784637,0x753f31,0x72382b,
855 0x6e3026,0x6a2721,0x651e1c,0x5f1417,0x590113],
856 &[0x1e0000,0x321a1a,0x402525,0x4b2d2d,0x553434,0x5e3b3b,0x664040,
857 0x6e4545,0x754a4a,0x7b4f4f,0x825353,0x885757,0x8d5b5b,0x935f5f,
858 0x986262,0x9d6666,0xa26969,0xa76c6c,0xac6f6f,0xb07272,0xb57575,
859 0xb97878,0xbd7b7b,0xc27e7e,0xc38481,0xc58a83,0xc79086,0xc99588,
860 0xca9a8b,0xcc9f8d,0xcea490,0xcfa992,0xd1ae94,0xd3b297,0xd4b799,
861 0xd6bb9b,0xd8bf9d,0xd9c3a0,0xdbc7a2,0xdccba4,0xdecfa6,0xdfd3a8,
862 0xe1d7aa,0xe2daac,0xe4deae,0xe5e1b0,0xe7e5b2,0xe8e8b4,0xeaeab9,
863 0xebebbf,0xededc4,0xeeeec9,0xf0f0ce,0xf1f1d3,0xf3f3d8,0xf4f4dd,
864 0xf5f5e1,0xf7f7e6,0xf8f8ea,0xfafaee,0xfbfbf3,0xfcfcf7,0xfefefb,
865 0xffffff],
866 /* followed by piecewise linear unequally spaced color lists */
867 &[[0,0x333399], [3,0x0099ff], [5,0x00cc66], [10,0xffff99],
868 [15,0x805c54], [20,0xffffff]],
869 &[[0, 0xff0000], [10,0xffef00], [11,0xf7ff00], [21,0x08ff00],
870 [22,0x00ff10], [32,0x00ffff], [42,0x0010ff], [43,0x0800ff],
871 [53,0xf700ff], [54,0xff00ef], [63,0xff0018]],
872 /* followed by piecewise linear individual color components */
873 &[&[[0,0], [47,47./72], [63,1]],
874 &[[0,0], [23,23./72], [47,56./72], [63,1]],
875 &[[0,0], [23,32./72], [63,1]]],
876 &[&[[0,0], [17,1], [21,1]],
877 &[[0,0], [21,482./617]],
878 &[[0,0], [21,199./400]]],
879 &[&[[0,26./625], [23,1], [63,1]],
880 &[[0,0], [23,0], [47,1], [63,1]],
881 &[[0,0], [47,0], [63,1]]],
882 &[&[[0,0], [.35,0], [.66,1], [.89,1], [1,.5]],
883 &[[0,0], [.125,0], [.375,1], [.64,1], [.91,0], [1,0]],
884 &[[0,.5], [.11,1], [.34,1], [.65,0], [1,0]]],
885 /* followed by cmap_nonlin individual color components */
886 &[[[0.75, 31.5, 0.25, 0.5], [1, 31.5, 0, 0],
887 [0.75, 31.5, -0.25, 0.5]]],
888 &[[[0.75, 20.9, 0.25, 0.67], [0.75, 20.9, -0.25, 0.33],
889 [-1.1, 20.9, 0, 0]]],
890 /* followed by gnuplot color component enumerated functions */
891 &[[7, 5, 15]], &[[30, 31, 32]], &[[23, 28, 3]], &[[33, 13, 10]],
892 &[[34, 35, 36]], &[[3, 11, 6]], &[[21, 22, 23]], &[[21, 23, 3]],
893 &[[3, 23, 21]]];
894
895 func cubehelix(n, gamma=, s=, r=, h=)
896 /* DOCUMENT cubehelix, n
897 * or cubehelix(n)
898 * Set cubehelix palette, designed by D.A. Green, adapted from matplotlib.
899 * Optional argument N is number of colors in palette, defaults to 200.
900 * If called as function, returns [r,g,b] without setting palette.
901 * Optional keyword arguments:
902 * Keyword Description
903 * gamma gamma factor to emphasise either low intensity values
904 * (gamma < 1), or high intensity values (gamma > 1);
905 * defaults to 1.0.
906 * s the start color; defaults to 0.5 (i.e. purple).
907 * r the number of r,g,b rotations in color that are made
908 * from the start to the end of the color scheme; defaults
909 * to -1.5 (i.e. -> B -> G -> R -> B).
910 * h the hue parameter which controls how saturated the
911 * colors are. If this parameter is zero then the color
912 * scheme is purely a greyscale; defaults to 1.0.
913 */
914 {
915 if (is_void(n)) n = cmap_ncolors();
916 if (is_void(gamma)) gamma = 1.0;
917 if (is_void(s)) s = 0.5;
918 if (is_void(r)) r = -1.5;
919 if (is_void(h)) h = 1.0;
920 x = span(0., 1., (n?n:200));
921 rgb = [cubehelix_gcf(x, -0.14861, 1.78277),
922 cubehelix_gcf(x, -0.29227, -0.90649),
923 cubehelix_gcf(x, 1.97294, 0.0)];
924 rgb = char(255*rgb);
925 if (!am_subroutine()) return rgb;
926 cmap, rgb;
927 }
928
cubehelix_gcf(x,p0,p1)929 func cubehelix_gcf(x, p0, p1)
930 {
931 xg = x^gamma;
932 a = h * xg * (1.-xg) / 2.;
933 phi = 2.*pi * (s/3. + r*x);
934 return xg + a * (p0*cos(phi) + p1*sin(phi));
935 }
936
937 /* ------------------------------------------------------------------------ */
938 /* gnuplot colormaps specified by rgbformulae */
939
gplct(r,g,b)940 func gplct(r, g, b)
941 /* DOCUMENT cm = gplct(r, g, b)
942 * or gplct, r, g, b
943 * return color map (ct = "color table") specification for gnuplot
944 * function indices (R,G,B), suitable to pass to cmap. This is
945 * equivalent to:
946 * cm = [[r, g, b]]
947 * Each of R, G, B must be between 0 and 36 inclusive. A negative
948 * number reverses the sense of the function.
949 * Called as a subroutine, sets the current palette.
950 * SEE ALSO: cmap, gmtct, mplct, gistct, idlct
951 */
952 {
953 rgb = [[r, g, b]];
954 if (max(abs(rgb)) > 36)
955 error, "known gnuplot colormap functions are 0 through 36";
956 if (!am_subroutine()) return rgb;
957 cmap, rgb;
958 }
959
gnu_map(r,g,b,n)960 func gnu_map(r, g, b, n)
961 {
962 if (is_void(n)) n = cmap_ncolors();
963 x = span(0., 1., n);
964 return [gnu_func(r,x), gnu_func(g,x), gnu_func(b,x)];
965 }
966
gnu_func(n,x)967 func gnu_func(n, x)
968 {
969 rev = (n < 0);
970 if (rev) n = -n;
971 if (n > 36) return [];
972 p = *_gnu_funcs(n+1);
973 if (rev) x = 1. - x;
974 return ((dimsof(p)(1) == 2)? cmap_interp : cmap_nonlin)(p, x);
975 }
976
977 _gnu_funcs = [&[[0,0], [1,0]], &[[0,0.5], [1,0.5]], &[[0,1], [1,1]],
978 &[[0,0], [1,1]], &[1, 0, 2, 0], &[1, 0, 3, 0], &[1, 0, 4, 0],
979 &[1, 0, 0.5, 0], &[1, 0, 0.25, 0],
980 &[1, 0.5, 0, 0], &[1, 0.5, 0.5, 0],
981 &[[0,0.5], [1,0], [2,0.5]], &[0.],
982 &[1., 1, 0, 0], &[-1, -1, -0.5, 0],
983 &[1., 2, 0, 0], &[1, 2, 0.5, 0],
984 &[-1., -2, 0, 0], &[-1, -2, -0.5, 0],
985 &[-1., -4, 0, 0], &[-1, -4, -0.5, 0],
986 &[[0,0], [1,1], [3,1]], &[[0,0], [1,0], [2,1], [3,1]],
987 &[[0,0], [2,0], [3,1]], &[[0,1], [1,0], [2,1], [3,1]],
988 &[[0,1], [1,1], [2,0], [3,1]],
989 &[[0,0], [1,0], [3,1]], &[[0,0], [2,0], [3,0.5]],
990 &[[0,0.5], [1,0], [3,1]], &[[0,1], [2,0], [3,0.5]],
991 &[[0,0], [25,0], [57,1], [100,1]],
992 &[[0,0], [42,0], [92,1], [100,1]],
993 &[[0,0], [25,1], [42,1], [92,0], [100,1]],
994 &[[0,0.5], [1,0], [3,1], [4,1]], &[[0,0], [1,1], [2,1]],
995 &[[0,0], [1,0], [3,1], [4,1]], &[[0,0], [1,0], [2,1]]];
996
997 /* ------------------------------------------------------------------------ */
998 /* The following colors and names are repackaged from GMT,
999 * Generic Mapping Tools, distributed under the following license:
1000 *
1001 * Copyright (c) 1991-2013, P. Wessel & W. H. F. Smith
1002 *
1003 * This program is free software; you can redistribute it and/or modify
1004 * it under the terms of the GNU General Public License as published by
1005 * the Free Software Foundation; version 2 or any later version.
1006 *
1007 * This program is distributed in the hope that it will be useful,
1008 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1009 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1010 * GNU General Public License for more details.
1011 *
1012 * Contact info: http://gmt.soest.hawaii.edu
1013 *
1014 * The palette files are in the share/cpt/ subdirectory of the
1015 * GMT source distribution.
1016 */
1017
gmtct(name)1018 func gmtct(name)
1019 /* DOCUMENT cm = gmtct(name)
1020 * or gmtct, name
1021 * return color map (ct = "color table") specification for GMT
1022 * map NAME. You may append "_r" to the name to reverse the colors.
1023 * Called as a subroutine, sets the current palette.
1024 * Note that the cmap_rd function can read GMT color map files.
1025 * SEE ALSO: cmap, mplct, gplct, gistct, cmap_rd
1026 */
1027 {
1028 local n, rev;
1029 name = cmap_name(name, n, rev);
1030 i = where(name == gmt_names);
1031 if (!numberof(i)) error, name+" is not a known GMT color map";
1032 p = *gmt_maps(i(1));
1033 flags = gmt_flags(i(1));
1034 if (flags == 1) hist = 1;
1035 else if (flags == 2) hsv = 1;
1036 if (!am_subroutine())
1037 return (hist || hsv)? save(p=p, hsv=hsv, hist=hist) : p;
1038 cmap, p, hist=hist, hsv=hsv;
1039 }
1040
1041 gmt_names = ["cool","copper","cyclic","drywet","gebco","globe","gray",
1042 "haxby","hot","jet","nighttime","no_green","ocean","paired",
1043 "panoply","polar","rainbow","red2green","relief","sealand",
1044 "seis","split","topo","wysiwyg"];
1045
1046 /* flags is 1 for hist=1, 2 for hsv=1 */
1047 gmt_flags = [0,0,2,0,0,0,0,1,0,0,2,1,0,1,1,0,2,0,0,2,0,0,2,1];
1048
1049 gmt_maps = [&[0x00ffff,0xff00ff], &[[0,0x000000],[51,0xff9f66],[64,0xffc880]],
1050 &[[0.,1,1],[360,1,1]],
1051 &[0x86612a,0xeec764,0xb4ee87,0x32eeeb,0x0c78ee,0x2601b7,0x083371],
1052 &[[0,0x00f0ff],[10,0x00f0ff],[10,0x23ffff],[20,0x23ffff],
1053 [20,0x5affff],[30,0x5affff],[30,0x8cffe6],[40,0x8cffe6],
1054 [40,0xa5ffd7],[50,0xa5ffd7],[50,0xc3ffd7],[60,0xc3ffd7],
1055 [60,0xd2ffd7],[65,0xd2ffd7],[65,0xe6fff0],[68,0xe6fff0],
1056 [68,0xebffff],[70,0xebffff]],
1057 &[[-100,0x9900ff],[-95,0x9900ff],[-90,0x9900ff],[-85,0x9900ff],
1058 [-85,0x8811ff],[-80,0x8811ff],[-80,0x7722ff],[-75,0x7722ff],
1059 [-75,0x6633ff],[-70,0x6633ff],[-70,0x5544ff],[-65,0x5544ff],
1060 [-65,0x4455ff],[-60,0x4455ff],[-60,0x3366ff],[-55,0x3366ff],
1061 [-55,0x2277ff],[-50,0x2277ff],[-50,0x1188ff],[-45,0x1188ff],
1062 [-45,0x0099ff],[-40,0x0099ff],[-40,0x1ba4ff],[-35,0x1ba4ff],
1063 [-35,0x36afff],[-30,0x36afff],[-30,0x51baff],[-25,0x51baff],
1064 [-25,0x6cc5ff],[-20,0x6cc5ff],[-20,0x86d0ff],[-15,0x86d0ff],
1065 [-15,0xa1dbff],[-10,0xa1dbff],[-10,0xbce6ff],[-5,0xbce6ff],
1066 [-5,0xd7f1ff],[-2,0xd7f1ff],[-2,0xf1fcff],[0,0xf1fcff],
1067 [0,0x336600],[1,0x33cc66],[1,0x33cc66],[2,0xbbe492],
1068 [2,0xbbe492],[5,0xffdcb9],[5,0xffdcb9],[10,0xf3ca89],
1069 [10,0xf3ca89],[15,0xe6b858],[15,0xe6b858],[20,0xd9a627],
1070 [20,0xd9a627],[25,0xa89a1f],[25,0xa89a1f],[30,0xa49019],
1071 [30,0xa49019],[35,0xa28613],[35,0xa28613],[40,0x9f7b0d],
1072 [40,0x9f7b0d],[45,0x9c7107],[45,0x9c7107],[50,0x996600],
1073 [50,0x996600],[55,0xa25959],[55,0xa25959],[60,0xb27676],
1074 [60,0xb27676],[65,0xb79393],[65,0xb79393],[70,0xc2b0b0],
1075 [70,0xc2b0b0],[75,0xcccccc],[75,0xcccccc],[80,0xe5e5e5],
1076 [80,0xe5e5e5],[85,0xf2f2f2],[85,0xf2f2f2],[90,0xffffff],
1077 [90,0xffffff],[95,0xffffff],[95,0xffffff],[100,0xffffff]],
1078 &[0x000000,0xffffff],
1079 &[0x0a0079,0x280096,0x1405af,0x000ac8,0x0019d4,0x0028e0,
1080 0x1a66f0,0x0d81f8,0x19afff,0x32beff,0x44caff,0x61e1f0,0x6aebe1,
1081 0x7cebc8,0x8aecae,0xacf5a8,0xcdffa2,0xdff58d,0xf0ec79,0xf7d768,
1082 0xffbd57,0xffa045,0xf4754b,0xee504e,0xff5a5a,0xff7c7c,0xff9e9e,
1083 0xf5b3ae,0xffc4c4,0xffd7d7,0xffebeb,0xffffff],
1084 &[[0,0x000000],[3,0xff0000],[6,0xffff00],[8,0xffffff]],
1085 &[[0,0x00007f],[1,0x0000ff],[3,0x00ffff],[5,0xffff7f],
1086 [7,0xff0000],[8,0x7f0000]],
1087 &[[0,260,1,0.1],[1,195,0.55,0.55],[1,65,0.55,0.55],[2,0,0.1,1]],
1088 &[0x2060ff,0x209fff,0x20bfff,0x00cfff,0x2affff,0x55ffff,0x7fffff,
1089 0xaaffff,0xffff54,0xfff000,0xffbf00,0xffa800,0xff8a00,0xff7000,
1090 0xff4d00,0xff0000],
1091 &[0x000000,0x000519,0x000a32,0x00507d,0x0096c8,0x56c5b8,0xacf5a8,
1092 0xd3fad3,0xfaffff],
1093 &[0xa6cee3,0x1f78b4,0xb2df8a,0x33a02c,0xfb9a99,0xe31a1c,0xfdbf6f,
1094 0xff7f00,0xcab2d6,0x6a3d9a,0xffff99,0xb15928],
1095 &[0x040ed8,0x2050ff,0x4196ff,0x6dc1ff,0x86d9ff,0x9ceeff,0xaff5ff,
1096 0xceffff,0xfffe47,0xffeb00,0xffc400,0xff9000,0xff4800,0xff0000,
1097 0xd50000,0x9e0000],
1098 &[0x0000ff,0xffffff,0xff0000], &[[300.,1,1],[0,1,1]],
1099 &[0xff0000,0xffffff,0x00ff00],
1100 &[[-80,0x000000],[-70,0x000519],[-60,0x000a32],[-50,0x00507d],
1101 [-40,0x0096c8],[-30,0x56c5b8],[-20,0xacf5a8],[-10,0xd3fad3],
1102 [0,0xfaffff],[0,0x467832],[5,0x786432],[10,0x927e3c],
1103 [20,0xc6b250],[30,0xfae664],[30,0xfae664],[40,0xfaea7e],
1104 [40,0xfaea7e],[50,0xfcee98],[50,0xfcee98],[60,0xfcf3b1],
1105 [60,0xfcf3b1],[70,0xfdf9d8],[70,0xfdf9d8],[80,0xffffff]],
1106 &[[0,255,0.6,1],[1,240,0.6,1],[2,225,0.6,1],[3,210,0.6,1],
1107 [4,195,0.6,1],[5,180,0.6,1],[6,165,0.6,1],[7,150,0.6,1],
1108 [8,135,0.6,1],[9,120,0.6,1],[10,105,0.6,1],[11,90,0.6,1],
1109 [12,75,0.6,1],[12,60,0.35,1],[13,40,0.35,1],[13,40,0.35,1],
1110 [14,20,0.35,1],[14,20,0.35,1],[15,0,0.35,1],[15,360,0.35,1],
1111 [16,345,0.3,1],[16,345,0.3,1],[17,330,0.25,1],[17,330,0.25,1],
1112 [18,315,0.2,1]],
1113 &[0xaa0000,0xff0000,0xff5500,0xffaa00,0xffff00,0xffff00,0x5aff1e,
1114 0x00f06e,0x0050ff,0x0000cd],
1115 &[0x8080ff,0x000080,0x000000,0x800000,0xff8080],
1116 &[[-70,290,0.45,0.85],[-65,265,0.45,0.85],[-65,265,0.4,0.9],
1117 [-60,240,0.4,0.9],[-55,220,0.4,0.9],[-50,199,0.4,0.9],
1118 [-45,175,0.4,0.95],[-40,150,0.45,0.95],[-35,125,0.45,0.95],
1119 [-30,99,0.45,0.95],[-25,75,0.45,0.95],[-20,50,0.45,0.95],
1120 [-15,25,0.45,0.95],[-5,10,0.35,0.85],[-5,0,0.25,0.85],
1121 [0,0,0.25,0.8],[0,195,0.35,0.7],[2,160,0.4,0.7],
1122 [2,160,0.4,0.7],[4,125,0.45,0.7],[4,125,0.45,0.7],
1123 [6,99,0.45,0.8],[6,99,0.45,0.8],[10,75,0.45,0.8],
1124 [10,75,0.45,0.8],[15,50,0.35,0.9],[15,50,0.35,0.9],
1125 [35,25,0.1,1],[35,25,0.05,1],[70,0,0,1]],
1126 &[0x400040,0x4000c0,0x0040ff,0x0080ff,0x00a0ff,0x40c0ff,0x40e0ff,
1127 0x40ffff,0x40ffc0,0x40ff40,0x80ff40,0xc0ff40,0xffff40,0xffe040,
1128 0xffa040,0xff6040,0xff2040,0xff60c0,0xffa0ff,0xffe0ff]];
1129
1130 /* ------------------------------------------------------------------------ */
1131 /* The following colors and names are repackaged from a spreadsheet
1132 * obtained from http://colorbrewer.org bearing the following
1133 * open source license:
1134 *
1135 * Copyright (c) 2002 Cynthia Brewer, Mark Harrower,
1136 * and The Pennsylvania State University.
1137 *
1138 * Licensed under the Apache License, Version 2.0 (the "License"); you
1139 * may not use this file except in compliance with the License. You may
1140 * obtain a copy of the License at
1141 *
1142 * http://www.apache.org/licenses/LICENSE-2.0
1143 *
1144 * Unless required by applicable law or agreed to in writing, software
1145 * distributed under the License is distributed on an "AS IS" BASIS,
1146 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1147 * implied. See the License for the specific language governing
1148 * permissions and limitations under the License.
1149 */
1150
1151 /* Unlike the other color maps defined in this file, these sets of
1152 * colors are carefully selected individually. They are intended to
1153 * be used to color maps with a small number of colors (12 or less).
1154 * Each name corresponds to a family of these sets with increasing
1155 * numbers of colors.
1156 *
1157 * By default, yorick palettes all have 200 colors, usually varying
1158 * smoothly, intended to represent continuous variables. By default,
1159 * therefore, we interpret the ColorBrewer palette names as the
1160 * largest set of colors availble with that name, and regard these
1161 * as equally spaced, linearly interpolating the r, g, b components
1162 * to fill in the 200 (or other large number) of smoothly varying
1163 * colors. This interpolation works very well for the sequential
1164 * and diverging ColorBrewer sets, but is a bit odd for the qualitative
1165 * sets, which are specifically chosen not to appear in any natural
1166 * sequence.
1167 *
1168 * You can specify a "histogram" colormap with cmap, which will
1169 * produce a palette having only the specific colors in the ColorBrewer
1170 * color sets. To do that, append "_N" to the name, where N is the
1171 * number of distinct colors you want. Thus, "Blues" will give the
1172 * smoothly interpolated table, while "Blues_7" gives a palette with
1173 * seven steps corresponding exactly to the 7 level ColorBrewer Blues.
1174 */
1175
1176 cb_names = ["Accent","Blues","BrBG","BuGn","BuPu","Dark2","GnBu","Greens",
1177 "Greys","Oranges","OrRd","Paired","Pastel1","Pastel2","PiYG",
1178 "PRGn","PuBu","PuBuGn","PuOr","PuRd","Purples","RdBu","RdGy",
1179 "RdPu","Reds","RdYlBu","RdYlGn","Set1","Set2","Set3","Spectral",
1180 "YlGn","YlGnBu","YlOrBr","YlOrRd"];
1181
1182 /* 1=sequential, 2=divergent, 3=qualitative */
1183 cb_types = [3,1,2,1,1,3,1,1,1,1,1,3,3,3,2,2,1,1,2,1,1,2,2,1,1,2,2,3,3,3,2,
1184 1,1,1,1];
1185
1186 /* here are the 379 unique ColorBrewer colors as 0xrrggbb */
1187 cb_colors =
1188 [0x000000,0x003c30,0x00441b,0x004529,0x005824,0x005a32,0x006837,0x006d2c,
1189 0x008837,0x014636,0x016450,0x01665e,0x016c59,0x018571,0x023858,0x02818a,
1190 0x034e7b,0x045a8d,0x053061,0x0570b0,0x0571b0,0x081d58,0x08306b,0x084081,
1191 0x084594,0x08519c,0x08589e,0x0868ac,0x0c2c84,0x1a1a1a,0x1a9641,0x1a9850,
1192 0x1b7837,0x1b9e77,0x1c9099,0x1d91c0,0x1f78b4,0x2166ac,0x2171b5,0x225ea8,
1193 0x238443,0x238b45,0x252525,0x253494,0x276419,0x2b83ba,0x2b8cbe,0x2c7bb6,
1194 0x2c7fb8,0x2ca25f,0x2d004b,0x313695,0x3182bd,0x31a354,0x3288bd,0x33a02c,
1195 0x35978f,0x3690c0,0x377eb8,0x386cb0,0x3f007d,0x40004b,0x404040,0x41ab5d,
1196 0x41ae76,0x41b6c4,0x4292c6,0x4393c3,0x43a2ca,0x4575b4,0x49006a,0x4a1486,
1197 0x4d004b,0x4d4d4d,0x4d9221,0x4dac26,0x4daf4a,0x4eb3d3,0x525252,0x542788,
1198 0x54278f,0x543005,0x5aae61,0x5ab4ac,0x5e3c99,0x5e4fa2,0x636363,0x662506,
1199 0x666666,0x66a61e,0x66bd63,0x66c2a4,0x66c2a5,0x67000d,0x67001f,0x67a9cf,
1200 0x6a3d9a,0x6a51a3,0x6baed6,0x6e016b,0x737373,0x74a9cf,0x74add1,0x74c476,
1201 0x756bb1,0x7570b3,0x762a83,0x78c679,0x7a0177,0x7b3294,0x7bccc4,0x7f0000,
1202 0x7f2704,0x7f3b08,0x7fbc41,0x7fbf7b,0x7fc97f,0x7fcdbb,0x800026,0x8073ac,
1203 0x807dba,0x80b1d3,0x80cdc1,0x810f7c,0x878787,0x88419d,0x8856a7,0x8c2d04,
1204 0x8c510a,0x8c6bb1,0x8c96c6,0x8da0cb,0x8dd3c7,0x8e0152,0x91003f,0x91bfdb,
1205 0x91cf60,0x92c5de,0x969696,0x980043,0x984ea3,0x990000,0x99000d,0x993404,
1206 0x9970ab,0x998ec3,0x999999,0x99d594,0x99d8c9,0x9e0142,0x9e9ac8,0x9ebcda,
1207 0x9ecae1,0xa1d76a,0xa1d99b,0xa1dab4,0xa50026,0xa50f15,0xa63603,0xa65628,
1208 0xa6611a,0xa6761d,0xa6bddb,0xa6cee3,0xa6d854,0xa6d96a,0xa6dba0,0xa8ddb5,
1209 0xabd9e9,0xabdda4,0xaddd8e,0xae017e,0xaf8dc3,0xb10026,0xb15928,0xb2182b,
1210 0xb2abd2,0xb2df8a,0xb2e2e2,0xb30000,0xb35806,0xb3b3b3,0xb3cde3,0xb3de69,
1211 0xb3e2cd,0xb8e186,0xbababa,0xbae4b3,0xbae4bc,0xbc80bd,0xbcbddc,0xbd0026,
1212 0xbdbdbd,0xbdc9e1,0xbdd7e7,0xbeaed4,0xbebada,0xbf5b17,0xbf812d,0xbfd3e6,
1213 0xc2a5cf,0xc2e699,0xc51b7d,0xc51b8a,0xc6dbef,0xc7e9b4,0xc7e9c0,0xc7eae5,
1214 0xc994c7,0xca0020,0xcab2d6,0xcb181d,0xcbc9e2,0xcbd5e8,0xcc4c02,0xcccccc,
1215 0xccebc5,0xccece6,0xce1256,0xd01c8b,0xd0d1e6,0xd1e5f0,0xd4b9da,0xd53e4f,
1216 0xd6604d,0xd7191c,0xd7301f,0xd73027,0xd7b5d8,0xd8b365,0xd8daeb,0xd94701,
1217 0xd94801,0xd95f02,0xd95f0e,0xd9d9d9,0xd9ef8b,0xd9f0a3,0xd9f0d3,0xdadaeb,
1218 0xdd1c77,0xdd3497,0xde2d26,0xde77ae,0xdecbe4,0xdeebf7,0xdf65b0,0xdfc27d,
1219 0xe08214,0xe0e0e0,0xe0ecf4,0xe0f3db,0xe0f3f8,0xe31a1c,0xe34a33,0xe41a1c,
1220 0xe5c494,0xe5d8bd,0xe5f5e0,0xe5f5f9,0xe6550d,0xe66101,0xe6ab02,0xe6f598,
1221 0xe6f5c9,0xe6f5d0,0xe7298a,0xe78ac3,0xe7d4e8,0xe7e1ef,0xe9a3c9,0xec7014,
1222 0xece2f0,0xece7f2,0xedf8b1,0xedf8e9,0xedf8fb,0xef3b2c,0xef6548,0xef8a62,
1223 0xefedf5,0xeff3ff,0xf0027f,0xf03b20,0xf0f0f0,0xf0f9e8,0xf16913,0xf1a340,
1224 0xf1b6da,0xf1e2cc,0xf1eef6,0xf2f0f7,0xf2f2f2,0xf46d43,0xf4a582,0xf4cae4,
1225 0xf5f5f5,0xf6e8c3,0xf6eff7,0xf768a1,0xf781bf,0xf7f4f9,0xf7f7f7,0xf7fbff,
1226 0xf7fcb9,0xf7fcf0,0xf7fcf5,0xf7fcfd,0xfa9fb5,0xfb6a4a,0xfb8072,0xfb9a99,
1227 0xfbb4ae,0xfbb4b9,0xfc4e2a,0xfc8d59,0xfc8d62,0xfc9272,0xfcae91,0xfcbba1,
1228 0xfcc5c0,0xfccde5,0xfcfbfd,0xfd8d3c,0xfdae61,0xfdae6b,0xfdb462,0xfdb863,
1229 0xfdbb84,0xfdbe85,0xfdbf6f,0xfdc086,0xfdcc8a,0xfdcdac,0xfdd0a2,0xfdd49e,
1230 0xfddaec,0xfddbc7,0xfde0dd,0xfde0ef,0xfe9929,0xfeb24c,0xfec44f,0xfecc5c,
1231 0xfed976,0xfed98e,0xfed9a6,0xfee08b,0xfee090,0xfee0b6,0xfee0d2,0xfee391,
1232 0xfee5d9,0xfee6ce,0xfee8c8,0xfeebe2,0xfeedde,0xfef0d9,0xff7f00,0xffd92f,
1233 0xffed6f,0xffeda0,0xfff2ae,0xfff5eb,0xfff5f0,0xfff7bc,0xfff7ec,0xfff7f3,
1234 0xfff7fb,0xffff33,0xffff99,0xffffb2,0xffffb3,0xffffbf,0xffffcc,0xffffd4,
1235 0xffffd9,0xffffe5,0xffffff];
1236
1237 /* indices into cb_colors for each color map */
1238 cb_maps =
1239 [&[&[117,196,332],&[117,196,332,371],&[117,196,332,371,60],
1240 &[117,196,332,371,60,283],&[117,196,332,371,60,283,198],
1241 &[117,196,332,371,60,283,198,89]],
1242 &[&[246,153,53],&[282,195,99,39],&[282,195,99,53,26],
1243 &[282,205,153,99,53,26],&[282,205,153,99,67,39,25],
1244 &[304,246,205,153,99,67,39,25],&[304,246,205,153,99,67,39,26,23]],
1245 &[&[230,297,84],&[161,248,123,14],&[161,248,297,123,14],
1246 &[129,230,298,208,84,12],&[129,230,298,297,208,84,12],
1247 &[129,199,248,298,208,123,57,12],&[129,199,248,298,297,208,123,57,12],
1248 &[82,129,199,248,298,208,123,57,12,2],
1249 &[82,129,199,248,298,297,208,123,57,12,2]],
1250 &[&[260,149,50],&[277,179,92,42],&[277,179,92,50,8],&[277,218,149,92,50,8],
1251 &[277,218,149,92,65,42,5],&[308,260,218,149,92,65,42,5],
1252 &[308,260,218,149,92,65,42,8,3]],
1253 &[&[251,152,127],&[277,183,131,126],&[277,183,131,127,124],
1254 &[277,200,152,131,127,124],&[277,200,152,131,130,126,100],
1255 &[308,251,200,152,131,130,126,100],&[308,251,200,152,131,130,126,124,73]],
1256 &[&[34,234,106],&[34,234,106,267],&[34,234,106,267,90],
1257 &[34,234,106,267,90,263],&[34,234,106,267,90,263,162],
1258 &[34,234,106,267,90,263,162,89]],
1259 &[&[252,168,69],&[286,189,111,47],&[286,189,111,69,28],
1260 &[286,217,168,111,69,28],&[286,217,168,111,78,47,27],
1261 &[306,252,217,168,111,78,47,27],&[306,252,217,168,111,78,47,28,24]],
1262 &[&[259,155,54],&[276,188,104,42],&[276,188,104,54,8],
1263 &[276,207,155,104,54,8],&[276,207,155,104,64,42,6],
1264 &[307,259,207,155,104,64,42,6],&[307,259,207,155,104,64,42,8,3]],
1265 &[&[285,193,87],&[303,216,139,79],&[303,216,139,87,43],
1266 &[303,236,193,139,87,43],&[303,236,193,139,101,79,43],
1267 &[379,285,236,193,139,101,79,43],&[379,285,236,193,139,101,79,43,1]],
1268 &[&[354,326,261],&[357,330,324,232],&[357,330,324,261,159],
1269 &[357,335,326,324,261,159],&[357,335,326,324,287,233,128],
1270 &[364,354,335,326,324,287,233,128],&[364,354,335,326,324,287,233,159,113]],
1271 &[&[355,329,255],&[358,333,316,227],&[358,333,316,255,180],
1272 &[358,336,329,316,255,180],&[358,336,329,316,279,227,142],
1273 &[367,355,336,329,316,279,227,142],&[367,355,336,329,316,279,227,180,112]],
1274 &[&[164,37,178],&[164,37,178,56],&[164,37,178,56,312],
1275 &[164,37,178,56,312,254],&[164,37,178,56,312,254,331],
1276 &[164,37,178,56,312,254,331,359],&[164,37,178,56,312,254,331,359,211],
1277 &[164,37,178,56,312,254,331,359,211,97],
1278 &[164,37,178,56,312,254,331,359,211,97,371],
1279 &[164,37,178,56,312,254,331,359,211,97,371,175]],
1280 &[&[313,183,217],&[313,183,217,245],&[313,183,217,245,347],
1281 &[313,183,217,245,347,375],&[313,183,217,245,347,375,258],
1282 &[313,183,217,245,347,375,258,337],&[313,183,217,245,347,375,258,337,293]],
1283 &[&[185,334,214],&[185,334,214,296],&[185,334,214,296,265],
1284 &[185,334,214,296,265,363],&[185,334,214,296,265,363,290],
1285 &[185,334,214,296,265,363,290,216]],
1286 &[&[271,303,154],&[220,289,186,76],&[220,289,303,186,76],
1287 &[203,271,340,266,154,75],&[203,271,340,303,266,154,75],
1288 &[203,244,289,340,266,186,115,75],&[203,244,289,340,303,266,186,115,75],
1289 &[134,203,244,289,340,266,186,115,75,45],
1290 &[134,203,244,289,340,303,266,186,115,75,45]],
1291 &[&[173,303,116],&[110,201,167,9],&[110,201,303,167,9],
1292 &[107,173,269,239,116,33],&[107,173,269,303,239,116,33],
1293 &[107,145,201,269,239,167,83,33],&[107,145,201,269,303,239,167,83,33],
1294 &[62,107,145,201,269,239,167,83,33,3],
1295 &[62,107,145,201,269,303,239,167,83,33,3]],
1296 &[&[274,163,47],&[291,194,102,20],&[291,194,102,47,18],
1297 &[291,221,163,102,47,18],&[291,221,163,102,58,20,17],
1298 &[369,274,221,163,102,58,20,17],&[369,274,221,163,102,58,20,18,15]],
1299 &[&[273,163,35],&[299,194,96,16],&[299,194,96,35,13],
1300 &[299,221,163,96,35,13],&[299,221,163,96,58,16,11],
1301 &[369,273,221,163,96,58,16,11],&[369,273,221,163,96,58,16,13,10]],
1302 &[&[288,303,146],&[262,328,177,85],&[262,328,303,177,85],
1303 &[181,288,350,231,146,80],&[181,288,350,303,231,146,80],
1304 &[181,249,328,350,231,177,120,80],&[181,249,328,350,303,231,177,120,80],
1305 &[114,181,249,328,350,231,177,120,80,51],
1306 &[114,181,249,328,350,303,231,177,120,80,51]],
1307 &[&[270,209,241],&[291,229,247,219],&[291,229,247,241,140],
1308 &[291,223,209,247,241,140],&[291,223,209,247,267,219,135],
1309 &[302,270,223,209,247,267,219,135],&[302,270,223,209,247,267,219,140,95]],
1310 &[&[281,191,105],&[292,213,151,98],&[292,213,151,105,81],
1311 &[292,240,191,151,105,81],&[292,240,191,151,121,98,72],
1312 &[323,281,240,191,151,121,98,72],&[323,281,240,191,151,121,98,81,61]],
1313 &[&[280,303,96],&[210,295,138,21],&[210,295,303,138,21],
1314 &[176,280,338,222,96,38],&[176,280,338,303,222,96,38],
1315 &[176,225,295,338,222,138,68,38],&[176,225,295,338,303,222,138,68,38],
1316 &[95,176,225,295,338,222,138,68,38,19],
1317 &[95,176,225,295,338,303,222,138,68,38,19]],
1318 &[&[280,379,147],&[210,295,187,63],&[210,295,379,187,63],
1319 &[176,280,338,250,147,74],&[176,280,338,379,250,147,74],
1320 &[176,225,295,338,250,187,125,74],&[176,225,295,338,379,250,187,125,74],
1321 &[95,176,225,295,338,250,187,125,74,30],
1322 &[95,176,225,295,338,379,250,187,125,74,30]],
1323 &[&[339,309,204],&[356,314,300,172],&[356,314,300,204,109],
1324 &[356,321,309,300,204,109],&[356,321,309,300,242,172,109],
1325 &[368,339,321,309,300,242,172,109],&[368,339,321,309,300,242,172,109,71]],
1326 &[&[351,318,243],&[353,319,310,212],&[353,319,310,243,158],
1327 &[353,320,318,310,243,158],&[353,320,318,310,278,212,143],
1328 &[365,351,320,318,310,278,212,143],&[365,351,320,318,310,278,212,158,94]],
1329 &[&[316,374,136],&[226,325,169,48],&[226,325,374,169,48],
1330 &[228,316,349,253,136,70],&[228,316,349,374,253,136,70],
1331 &[228,294,325,349,253,169,103,70],&[228,294,325,349,374,253,169,103,70],
1332 &[157,228,294,325,349,253,169,103,70,52],
1333 &[157,228,294,325,349,374,253,169,103,70,52]],
1334 &[&[316,374,137],&[226,325,166,31],&[226,325,374,166,31],
1335 &[228,316,348,237,137,32],&[228,316,348,374,237,137,32],
1336 &[228,294,325,348,237,166,91,32],&[228,294,325,348,374,237,166,91,32],
1337 &[157,228,294,325,348,237,166,91,32,7],
1338 &[157,228,294,325,348,374,237,166,91,32,7]],
1339 &[&[256,59,77],&[256,59,77,141],&[256,59,77,141,359],
1340 &[256,59,77,141,359,370],&[256,59,77,141,359,370,160],
1341 &[256,59,77,141,359,370,160,301],&[256,59,77,141,359,370,160,301,147]],
1342 &[&[93,317,132],&[93,317,132,268],&[93,317,132,268,165],
1343 &[93,317,132,268,165,360],&[93,317,132,268,165,360,257],
1344 &[93,317,132,268,165,360,257,182]],
1345 &[&[133,373,197],&[133,373,197,311],&[133,373,197,311,122],
1346 &[133,373,197,311,122,327],&[133,373,197,311,122,327,184],
1347 &[133,373,197,311,122,327,184,322],&[133,373,197,311,122,327,184,322,236],
1348 &[133,373,197,311,122,327,184,322,236,190],
1349 &[133,373,197,311,122,327,184,322,236,190,217],
1350 &[133,373,197,311,122,327,184,322,236,190,217,361]],
1351 &[&[316,374,148],&[226,325,170,46],&[226,325,374,170,46],
1352 &[224,316,348,264,148,55],&[224,316,348,374,264,148,55],
1353 &[224,294,325,348,264,170,93,55],&[224,294,325,348,374,264,170,93,55],
1354 &[150,224,294,325,348,264,170,93,55,86],
1355 &[150,224,294,325,348,374,264,170,93,55,86]],
1356 &[&[305,171,54],&[375,202,108,41],&[375,202,108,54,7],
1357 &[375,238,171,108,54,7],&[375,238,171,108,64,41,6],
1358 &[378,305,238,171,108,64,41,6],&[378,305,238,171,108,64,41,7,4]],
1359 &[&[275,118,49],&[375,156,66,40],&[375,156,66,49,44],
1360 &[375,206,118,66,49,44],&[375,206,118,66,36,40,29],
1361 &[377,275,206,118,66,36,40,29],&[377,275,206,118,66,36,40,44,22]],
1362 &[&[366,343,235],&[376,346,341,215],&[376,346,341,235,144],
1363 &[376,352,343,341,235,144],&[376,352,343,341,272,215,128],
1364 &[378,366,352,343,341,272,215,128],&[378,366,352,343,341,272,215,144,88]],
1365 &[&[362,342,284],&[372,344,324,254],&[372,344,324,284,192],
1366 &[372,345,342,324,284,192],&[372,345,342,324,315,254,174],
1367 &[375,362,345,342,324,315,254,174],&[375,362,345,342,324,315,254,192,119]]];
1368
1369 func cb_map(name, nlevs, &type)
1370 {
1371 if (structof(name) == string) {
1372 maps = where(strcase(0,name) == strcase(0,cb_names));
1373 if (numberof(maps) != 1) return [];
1374 m = maps(1);
1375 } else {
1376 m = name;
1377 if (m<1 || m>numberof(cb_maps)) return [];
1378 }
1379 eq_nocopy, maps, *cb_maps(m);
1380 type = cb_types(m);
1381 if (!nlevs) return cb_colors(*maps(0));
1382 for (i=1 ; i<=numberof(maps) ; ++i) if (nlevs == numberof(*maps(i))) break;
1383 if (i > numberof(maps))
1384 error, cb_names(m)+" has no maps with "+totxt(nlevs)+" levels";
1385 return cb_colors(*maps(i));
1386 }
1387
cb_choices(n,what)1388 func cb_choices(n, what)
1389 /* DOCUMENT cb_choices, n, what
1390 * or cb_choices, name
1391 * list available ColorBrewer color map choices with N colors. The
1392 * WHAT argument is "sequential", "diverging", or "qualitative", which
1393 * can be abbreviated to any smaller number of characters. The N and
1394 * WHAT arguments are both optional, and may occur in either order.
1395 * Called as a function, cb_choices returns a list of palette names;
1396 * if the N argument is specified, "_N" will be appended to the
1397 * returned names.
1398 * In the second form, prints (or displays) a list of the different
1399 * numbers of colors available for color map NAME.
1400 */
1401 {
1402 if (structof(n) == string) {
1403 tmp = n;
1404 n = what;
1405 what = tmp;
1406 }
1407 list = msort(cb_types, cb_names);
1408 names = cb_names(list);
1409 types = cb_types(list);
1410 type = ["sequential", "diverging", "qualitative"];
1411 if (!is_void(what)) {
1412 i = where(strcase(0, what) == strcase(0, names));
1413 if (!numberof(i)) {
1414 i = where(strglob(what+"*", type));
1415 if (numberof(i) != 1) error, "unrecognized color map type "+what;
1416 flag = i(1);
1417 i = where(types == i);
1418 list = list(i);
1419 names = names(i);
1420 types = types(i);
1421 } else {
1422 list = list(i(1));
1423 names = names(i(1));
1424 types = types(i(1));
1425 flag = -1;
1426 }
1427 }
1428 lens = array(int, 20, numberof(list));
1429 maps = cb_maps(list);
1430 for (i=1 ; i<=numberof(maps) ; ++i) {
1431 m = *maps(i);
1432 for (j=1 ; j<=numberof(m) ; ++j) lens(numberof(*m(j)), i) = 1;
1433 }
1434 if (flag == -1) {
1435 lens = where(lens);
1436 if (am_subroutine()) {
1437 write, names(1)+" maps available with";
1438 print, lens;
1439 write, "colors";
1440 }
1441 return lens;
1442 }
1443 if (n) {
1444 if (n<1 || n>20) error, "bad color map size "+totxt(n);
1445 i = where(lens(n,));
1446 if (!numberof(i)) {
1447 if (am_subroutine())
1448 write, "No "+(flag?type(flag)+" ":"")+"maps with "+totxt(n)+" colors";
1449 return [];
1450 }
1451 list = list(i);
1452 names = names(i);
1453 types = types(i);
1454 sfx = "_"+totxt(n);
1455 if (am_subroutine())
1456 write, "Available maps with "+totxt(n)+" colors:";
1457 } else {
1458 sfx = string(0);
1459 }
1460 if (!am_subroutine()) return names+sfx;
1461 i = where(types == 1);
1462 if (numberof(i)) write, grow("Sequential maps:",names(i));
1463 i = where(types == 2);
1464 if (numberof(i)) write, grow("Diverging maps:",names(i));
1465 i = where(types == 3);
1466 if (numberof(i)) write, grow("Qualitative maps:",names(i));
1467 }
1468
1469 /* ------------------------------------------------------------------------ */
1470 /* Many published figures use color tables from the IDL (or PVWAVE)
1471 * programming language. See
1472 * http://www.exelisvis.com/language/en-us/productsservices/idl.aspx
1473 * http://en.wikipedia.org/wiki/IDL_%28programming_language%29
1474 */
1475
1476 func idlct_rd(filename, &names)
1477 /* DOCUMENT tables = idlct_rd(filename, names)
1478 * read an IDL color table file, returning TABLES and NAMES.
1479 * TABLES is a 256-by-3-by-N array of N [r,g,b] color mappings, and
1480 * NAMES is a corresponding list of N descriptions.
1481 * The first index of tables corresponds to color index values 0:255.
1482 *
1483 * The default IDL color tables file is colors1.tbl in the
1484 * resource/colors subdirectory of the IDL distribution. Copies
1485 * and modified copies can be found on the Web, for example:
1486 * http://www.bnl.gov/x26a/download/colors1.zip
1487 * The IDLVM virtual machine is available without charge and
1488 * includes this file.
1489 *
1490 * This function will also read the png files posted at
1491 * http://docs.idldev.com/vis/color/default-colors.png
1492 * (see http://docs.idldev.com/vis/color/vis_loadct.html)
1493 * (Assumes you have the yorick-z package installed.)
1494 * SEE ALSO: idlct
1495 */
1496 {
1497 if (strpart(filename, -3:0) != ".png") {
1498 f = open(filename, "rb");
1499 ntab = char(0);
1500 _read, f, 0, ntab;
1501 if (!ntab) error, filename+" has no color tables";
1502 if (sizeof(f) < 1+800*ntab) error, filename+" too short";
1503 if (sizeof(f) > 1+800*ntab) write, "idlct: "+filename+" not truncated?";
1504 names = array(char, 32, ntab);
1505 _read, f, 1+768*ntab, names;
1506 names = strtrim(strchar(names));
1507 tables = array(char, 256, 3, ntab);
1508 _read, f, 1, tables;
1509 tables = transpose(tables, [1,2]);
1510 } else {
1511 tables = png_read(filename)(1:3, 1:256, 7::13);
1512 names = [];
1513 }
1514 return tables;
1515 }
1516
idlct(n,ncols)1517 func idlct(n, ncols)
1518 /* DOCUMENT idlct, n
1519 * or idlct, tables
1520 * set palette to IDL color table N. You must first call the function
1521 * with the TABLES returned by idlct_rd. A second parameter is interpreted
1522 * as the number of colors to use; the default is the size of the current
1523 * palette or 200 if there is none.
1524 * Hint: You can set _idlctables to a string containing the name of
1525 * a file readable by idlct_rd to automatically load the tables the
1526 * first time idlct is called.
1527 * SEE ALSO: idlct_rd, cmap
1528 */
1529 {
1530 d = dimsof(n);
1531 if (d(1)) {
1532 if (d(1)!=3 || d(2)!=3 || structof(n)!=char)
1533 error, "IDL tables array not in format returned by idlct_rd";
1534 extern _idlctables;
1535 _idlctables = n;
1536 } else {
1537 if (structof(_idlctables) == string)
1538 _idlctables = idlct_rd(_idlctables);
1539 if (is_void(_idlctables))
1540 error, "IDL color tables not installed, use idlct,idlct_rd(file)";
1541 if (n<0 || n>=dimsof(_idlctables)(4))
1542 error, "invalid color table index, "+totxt(d(4))+" tables installed";
1543 ct = _idlctables(,,1+n);
1544 if (!am_subroutine()) return ct;
1545 cmap, ct, ncols;
1546 }
1547 }
1548